static int sirfsoc_uart_probe(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport; struct uart_port *port; struct resource *res; int ret; const struct of_device_id *match; match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); if (of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id)) { dev_err(&pdev->dev, "Unable to find cell-index in uart node.\n"); ret = -EFAULT; goto err; } if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) pdev->id += ((struct sirfsoc_uart_register *) match->data)->uart_param.register_uart_nr; sirfport = &sirfsoc_uart_ports[pdev->id]; port = &sirfport->port; port->dev = &pdev->dev; port->private_data = sirfport; sirfport->uart_reg = (struct sirfsoc_uart_register *)match->data; sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, "sirf,uart-has-rtscts"); if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) { sirfport->uart_reg->uart_type = SIRF_REAL_UART; if (of_property_read_u32(pdev->dev.of_node, "sirf,uart-dma-rx-channel", &sirfport->rx_dma_no)) sirfport->rx_dma_no = UNVALID_DMA_CHAN; if (of_property_read_u32(pdev->dev.of_node, "sirf,uart-dma-tx-channel", &sirfport->tx_dma_no)) sirfport->tx_dma_no = UNVALID_DMA_CHAN; } if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) { sirfport->uart_reg->uart_type = SIRF_USP_UART; if (of_property_read_u32(pdev->dev.of_node, "sirf,usp-dma-rx-channel", &sirfport->rx_dma_no)) sirfport->rx_dma_no = UNVALID_DMA_CHAN; if (of_property_read_u32(pdev->dev.of_node, "sirf,usp-dma-tx-channel", &sirfport->tx_dma_no)) sirfport->tx_dma_no = UNVALID_DMA_CHAN; if (!sirfport->hw_flow_ctrl) goto usp_no_flow_control; if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL)) sirfport->cts_gpio = of_get_named_gpio( pdev->dev.of_node, "cts-gpios", 0); else sirfport->cts_gpio = -1; if (of_find_property(pdev->dev.of_node, "rts-gpios", NULL)) sirfport->rts_gpio = of_get_named_gpio( pdev->dev.of_node, "rts-gpios", 0); else sirfport->rts_gpio = -1; if ((!gpio_is_valid(sirfport->cts_gpio) || !gpio_is_valid(sirfport->rts_gpio))) { ret = -EINVAL; dev_err(&pdev->dev, "Usp flow control must have cts and rts gpio"); goto err; } ret = devm_gpio_request(&pdev->dev, sirfport->cts_gpio, "usp-cts-gpio"); if (ret) { dev_err(&pdev->dev, "Unable request cts gpio"); goto err; } gpio_direction_input(sirfport->cts_gpio); ret = devm_gpio_request(&pdev->dev, sirfport->rts_gpio, "usp-rts-gpio"); if (ret) { dev_err(&pdev->dev, "Unable request rts gpio"); goto err; } gpio_direction_output(sirfport->rts_gpio, 1); } usp_no_flow_control: if (of_device_is_compatible(pdev->dev.of_node, "sirf,marco-uart")) sirfport->is_marco = true; if (of_property_read_u32(pdev->dev.of_node, "fifosize", &port->fifosize)) { dev_err(&pdev->dev, "Unable to find fifosize in uart node.\n"); ret = -EFAULT; goto err; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } spin_lock_init(&sirfport->rx_lock); spin_lock_init(&sirfport->tx_lock); tasklet_init(&sirfport->rx_dma_complete_tasklet, sirfsoc_uart_rx_dma_complete_tl, (unsigned long)sirfport); tasklet_init(&sirfport->rx_tmo_process_tasklet, sirfsoc_rx_tmo_process_tl, (unsigned long)sirfport); port->mapbase = res->start; port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!port->membase) { dev_err(&pdev->dev, "Cannot remap resource.\n"); ret = -ENOMEM; goto err; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } port->irq = res->start; sirfport->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(sirfport->clk)) { ret = PTR_ERR(sirfport->clk); goto err; } clk_prepare_enable(sirfport->clk); port->uartclk = clk_get_rate(sirfport->clk); port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); platform_set_drvdata(pdev, sirfport); ret = uart_add_one_port(&sirfsoc_uart_drv, port); if (ret != 0) { dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); goto port_err; } return 0; port_err: clk_disable_unprepare(sirfport->clk); clk_put(sirfport->clk); err: return ret; }
static int tegra_uart_probe(struct platform_device *pdev) { struct tegra_uart_port *tup; struct uart_port *u; struct resource *resource; int ret; const struct tegra_uart_chip_data *cdata; const struct of_device_id *match; match = of_match_device(tegra_uart_of_match, &pdev->dev); if (!match) { dev_err(&pdev->dev, "Error: No device match found\n"); return -ENODEV; } cdata = match->data; tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL); if (!tup) { dev_err(&pdev->dev, "Failed to allocate memory for tup\n"); return -ENOMEM; } ret = tegra_uart_parse_dt(pdev, tup); if (ret < 0) return ret; u = &tup->uport; u->dev = &pdev->dev; u->ops = &tegra_uart_ops; u->type = PORT_TEGRA; u->fifosize = 32; tup->cdata = cdata; platform_set_drvdata(pdev, tup); resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!resource) { dev_err(&pdev->dev, "No IO memory resource\n"); return -ENODEV; } u->mapbase = resource->start; u->membase = devm_ioremap_resource(&pdev->dev, resource); if (IS_ERR(u->membase)) return PTR_ERR(u->membase); tup->uart_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(tup->uart_clk)) { dev_err(&pdev->dev, "Couldn't get the clock\n"); return PTR_ERR(tup->uart_clk); } tup->rst = devm_reset_control_get(&pdev->dev, "serial"); if (IS_ERR(tup->rst)) { dev_err(&pdev->dev, "Couldn't get the reset\n"); return PTR_ERR(tup->rst); } u->iotype = UPIO_MEM32; u->irq = platform_get_irq(pdev, 0); u->regshift = 2; ret = uart_add_one_port(&tegra_uart_driver, u); if (ret < 0) { dev_err(&pdev->dev, "Failed to add uart port, err %d\n", ret); return ret; } return ret; }
static int __init msm_serial_hsl_probe(struct platform_device *pdev) { struct msm_hsl_port *msm_hsl_port; struct resource *uart_resource; struct resource *gsbi_resource; struct uart_port *port; int ret; if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial_hsl: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_hsl_port = UART_TO_MSM(port); if (msm_serial_hsl_has_gsbi()) { gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"); if (unlikely(!gsbi_resource)) return -ENXIO; msm_hsl_port->clk = clk_get(&pdev->dev, "gsbi_uart_clk"); msm_hsl_port->pclk = clk_get(&pdev->dev, "gsbi_pclk"); } else { msm_hsl_port->clk = clk_get(&pdev->dev, "uartdm_clk"); msm_hsl_port->pclk = NULL; } if (unlikely(IS_ERR(msm_hsl_port->clk))) { printk(KERN_ERR "%s: Error getting clk\n", __func__); return PTR_ERR(msm_hsl_port->clk); } if (unlikely(IS_ERR(msm_hsl_port->pclk))) { printk(KERN_ERR "%s: Error getting pclk\n", __func__); return PTR_ERR(msm_hsl_port->pclk); } /* Set up the MREG/NREG/DREG/MNDREG */ #ifdef CONFIG_LGE_FELICA ret = clk_set_rate(msm_hsl_port->clk, 7372800); if (ret) { printk(KERN_WARNING "Error setting clock rate on UART\n"); return ret; } #else // [email protected] 30550g original, remove clk_set_rate #endif uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uartdm_resource"); if (unlikely(!uart_resource)) { printk(KERN_ERR "getting uartdm_resource failed\n"); return -ENXIO; } port->mapbase = uart_resource->start; port->irq = platform_get_irq(pdev, 0); if (unlikely(port->irq < 0)) { printk(KERN_ERR "%s: getting irq failed\n", __func__); return -ENXIO; } device_set_wakeup_capable(&pdev->dev, 1); platform_set_drvdata(pdev, port); pm_runtime_enable(port->dev); ret = uart_add_one_port(&msm_hsl_uart_driver, port); return ret; }
static int serial_pxa_probe(struct platform_device *dev) { struct uart_pxa_port *sport; struct resource *mmres, *irqres; int ret; mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); if (!mmres || !irqres) return -ENODEV; sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); if (!sport) return -ENOMEM; sport->clk = clk_get(&dev->dev, NULL); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); goto err_free; } ret = clk_prepare(sport->clk); if (ret) { clk_put(sport->clk); goto err_free; } sport->port.type = PORT_PXA; sport->port.iotype = UPIO_MEM; sport->port.mapbase = mmres->start; sport->port.irq = irqres->start; sport->port.fifosize = 64; sport->port.ops = &serial_pxa_pops; sport->port.dev = &dev->dev; sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; sport->port.uartclk = clk_get_rate(sport->clk); ret = serial_pxa_probe_dt(dev, sport); if (ret > 0) sport->port.line = dev->id; else if (ret < 0) goto err_clk; snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1); sport->port.membase = ioremap(mmres->start, resource_size(mmres)); if (!sport->port.membase) { ret = -ENOMEM; goto err_clk; } serial_pxa_ports[sport->port.line] = sport; uart_add_one_port(&serial_pxa_reg, &sport->port); platform_set_drvdata(dev, sport); return 0; err_clk: clk_unprepare(sport->clk); clk_put(sport->clk); err_free: kfree(sport); return ret; }
static int serial_omap_probe(struct platform_device *pdev) { struct uart_omap_port *up; struct resource *mem, *irq, *dma_tx, *dma_rx; struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; int ret = -ENOSPC; if (pdev->dev.of_node) omap_up_info = of_get_uart_port_info(&pdev->dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "no irq resource?\n"); return -ENODEV; } if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); if (!dma_rx) return -ENXIO; dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); if (!dma_tx) return -ENXIO; up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.irq = irq->start; up->port.regshift = 2; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; if (pdev->dev.of_node) up->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); else up->port.line = pdev->id; if (up->port.line < 0) { dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", up->port.line); ret = -ENODEV; goto err_port_line; } sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; up->port.membase = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!up->port.membase) { dev_err(&pdev->dev, "can't ioremap UART\n"); ret = -ENOMEM; goto err_ioremap; } up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; if (!up->port.uartclk) { up->port.uartclk = DEFAULT_CLK_SPEED; dev_warn(&pdev->dev, "No clock speed specified: using default:" "%d\n", DEFAULT_CLK_SPEED); } up->uart_dma.uart_base = mem->start; if (omap_up_info->dma_enabled) { up->uart_dma.uart_dma_tx = dma_tx->start; up->uart_dma.uart_dma_rx = dma_rx->start; up->use_dma = 1; up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; } up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; pm_qos_add_request(&up->pm_qos_request, PM_QOS_CPU_DMA_LATENCY, up->latency); serial_omap_uart_wq = create_singlethread_workqueue(up->name); INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->autosuspend_timeout); pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); omap_serial_fill_features_erratas(up); ui[up->port.line] = up; serial_omap_add_console_port(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto err_add_port; pm_runtime_put(&pdev->dev); platform_set_drvdata(pdev, up); return 0; err_add_port: pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); err_ioremap: err_port_line: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); return ret; }
static int vt8500_serial_probe(struct platform_device *pdev) { struct vt8500_port *vt8500_port; struct resource *mmres, *irqres; struct device_node *np = pdev->dev.of_node; int ret; int port; mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!mmres || !irqres) return -ENODEV; if (np) { port = of_alias_get_id(np, "serial"); if (port >= VT8500_MAX_PORTS) port = -1; } else { port = -1; } if (port < 0) { /* calculate the port id */ port = find_first_zero_bit(&vt8500_ports_in_use, sizeof(vt8500_ports_in_use)); } if (port >= VT8500_MAX_PORTS) return -ENODEV; /* reserve the port id */ if (test_and_set_bit(port, &vt8500_ports_in_use)) { /* port already in use - shouldn't really happen */ return -EBUSY; } vt8500_port = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_port), GFP_KERNEL); if (!vt8500_port) return -ENOMEM; vt8500_port->uart.membase = devm_ioremap_resource(&pdev->dev, mmres); if (IS_ERR(vt8500_port->uart.membase)) return PTR_ERR(vt8500_port->uart.membase); vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); if (IS_ERR(vt8500_port->clk)) { dev_err(&pdev->dev, "failed to get clock\n"); return -EINVAL; } ret = clk_prepare_enable(vt8500_port->clk); if (ret) { dev_err(&pdev->dev, "failed to enable clock\n"); return ret; } vt8500_port->uart.type = PORT_VT8500; vt8500_port->uart.iotype = UPIO_MEM; vt8500_port->uart.mapbase = mmres->start; vt8500_port->uart.irq = irqres->start; vt8500_port->uart.fifosize = 16; vt8500_port->uart.ops = &vt8500_uart_pops; vt8500_port->uart.line = port; vt8500_port->uart.dev = &pdev->dev; vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); snprintf(vt8500_port->name, sizeof(vt8500_port->name), "VT8500 UART%d", pdev->id); vt8500_uart_ports[port] = vt8500_port; uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); platform_set_drvdata(pdev, vt8500_port); return 0; }
static int pl011_probe(struct amba_device *dev, void *id) { struct uart_amba_port *uap; void *base; int i, ret; for (i = 0; i < ARRAY_SIZE(amba_ports); i++) if (amba_ports[i] == NULL) break; if (i == ARRAY_SIZE(amba_ports)) { ret = -EBUSY; goto out; } uap = kmalloc(sizeof(struct uart_amba_port), GFP_KERNEL); if (uap == NULL) { ret = -ENOMEM; goto out; } base = ioremap(dev->res.start, PAGE_SIZE); if (!base) { ret = -ENOMEM; goto free; } memset(uap, 0, sizeof(struct uart_amba_port)); uap->clk = clk_get(&dev->dev, "UARTCLK"); if (IS_ERR(uap->clk)) { ret = PTR_ERR(uap->clk); goto unmap; } ret = clk_use(uap->clk); if (ret) goto putclk; uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; uap->port.iotype = UPIO_MEM; uap->port.irq = dev->irq[0]; uap->port.fifosize = 16; uap->port.ops = &amba_pl011_pops; uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = i; amba_ports[i] = uap; amba_set_drvdata(dev, uap); ret = uart_add_one_port(&amba_reg, &uap->port); if (ret) { amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; clk_unuse(uap->clk); putclk: clk_put(uap->clk); unmap: iounmap(base); free: kfree(uap); } out: return ret; }
static int sprd_probe(struct platform_device *pdev) { struct resource *res; struct uart_port *up; int irq; int index; int ret; for (index = 0; index < ARRAY_SIZE(sprd_port); index++) if (sprd_port[index] == NULL) break; if (index == ARRAY_SIZE(sprd_port)) return -EBUSY; index = sprd_probe_dt_alias(index, &pdev->dev); sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]), GFP_KERNEL); if (!sprd_port[index]) return -ENOMEM; up = &sprd_port[index]->port; up->dev = &pdev->dev; up->line = index; up->type = PORT_SPRD; up->iotype = UPIO_MEM; up->uartclk = SPRD_DEF_RATE; up->fifosize = SPRD_FIFO_SIZE; up->ops = &serial_sprd_ops; up->flags = UPF_BOOT_AUTOCONF; ret = sprd_clk_init(up); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); up->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(up->membase)) return PTR_ERR(up->membase); up->mapbase = res->start; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "not provide irq resource: %d\n", irq); return irq; } up->irq = irq; /* * Allocate one dma buffer to prepare for receive transfer, in case * memory allocation failure at runtime. */ ret = sprd_rx_alloc_buf(sprd_port[index]); if (ret) return ret; if (!sprd_ports_num) { ret = uart_register_driver(&sprd_uart_driver); if (ret < 0) { pr_err("Failed to register SPRD-UART driver\n"); return ret; } } sprd_ports_num++; ret = uart_add_one_port(&sprd_uart_driver, up); if (ret) { sprd_port[index] = NULL; sprd_remove(pdev); } platform_set_drvdata(pdev, up); return ret; }
static int pl010_probe(struct amba_device *dev, struct amba_id *id) { struct uart_amba_port *uap; void __iomem *base; int i, ret; for (i = 0; i < ARRAY_SIZE(amba_ports); i++) if (amba_ports[i] == NULL) break; if (i == ARRAY_SIZE(amba_ports)) { ret = -EBUSY; goto out; } uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) { ret = -ENOMEM; goto out; } base = ioremap(dev->res.start, resource_size(&dev->res)); if (!base) { ret = -ENOMEM; goto free; } uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { ret = PTR_ERR(uap->clk); goto unmap; } uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; uap->port.iotype = UPIO_MEM; uap->port.irq = dev->irq[0]; uap->port.fifosize = 16; uap->port.ops = &amba_pl010_pops; uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = i; uap->dev = dev; uap->data = dev->dev.platform_data; amba_ports[i] = uap; amba_set_drvdata(dev, uap); ret = uart_add_one_port(&amba_reg, &uap->port); if (ret) { amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; clk_put(uap->clk); unmap: iounmap(base); free: kfree(uap); } out: return ret; }
int nwpserial_register_port(struct uart_port *port) { struct nwpserial_port *up = NULL; int ret = -1; int i; static int first = 1; int dcr_len; int dcr_base; struct device_node *dn; mutex_lock(&nwpserial_mutex); dn = to_of_device(port->dev)->dev.of_node; if (dn == NULL) goto out; /* get dcr base. */ dcr_base = dcr_resource_start(dn, 0); /* find matching entry */ for (i = 0; i < NWPSERIAL_NR; i++) if (nwpserial_ports[i].port.iobase == dcr_base) { up = &nwpserial_ports[i]; break; } /* we didn't find a mtching entry, search for a free port */ if (up == NULL) for (i = 0; i < NWPSERIAL_NR; i++) if (nwpserial_ports[i].port.type == PORT_UNKNOWN && nwpserial_ports[i].port.iobase == 0) { up = &nwpserial_ports[i]; break; } if (up == NULL) { ret = -EBUSY; goto out; } if (first) uart_register_driver(&nwpserial_reg); first = 0; up->port.membase = port->membase; up->port.irq = port->irq; up->port.uartclk = port->uartclk; up->port.fifosize = port->fifosize; up->port.regshift = port->regshift; up->port.iotype = port->iotype; up->port.flags = port->flags; up->port.mapbase = port->mapbase; up->port.private_data = port->private_data; if (port->dev) up->port.dev = port->dev; if (up->port.iobase != dcr_base) { up->port.ops = &nwpserial_pops; up->port.fifosize = 16; spin_lock_init(&up->port.lock); up->port.iobase = dcr_base; dcr_len = dcr_resource_len(dn, 0); up->dcr_host = dcr_map(dn, dcr_base, dcr_len); if (!DCR_MAP_OK(up->dcr_host)) { printk(KERN_ERR "Cannot map DCR resources for NWPSERIAL"); goto out; } } ret = uart_add_one_port(&nwpserial_reg, &up->port); if (ret == 0) ret = up->port.line; out: mutex_unlock(&nwpserial_mutex); return ret; }
static int vt8500_serial_probe(struct platform_device *pdev) { struct vt8500_port *vt8500_port; struct resource *mmres, *irqres; struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; const unsigned int *flags; int ret; int port; match = of_match_device(wmt_dt_ids, &pdev->dev); if (!match) return -EINVAL; flags = match->data; mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!mmres || !irqres) return -ENODEV; if (np) { port = of_alias_get_id(np, "serial"); if (port >= VT8500_MAX_PORTS) port = -1; } else { port = -1; } if (port < 0) { /* calculate the port id */ port = find_first_zero_bit(&vt8500_ports_in_use, sizeof(vt8500_ports_in_use)); } if (port >= VT8500_MAX_PORTS) return -ENODEV; /* reserve the port id */ if (test_and_set_bit(port, &vt8500_ports_in_use)) { /* port already in use - shouldn't really happen */ return -EBUSY; } vt8500_port = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_port), GFP_KERNEL); if (!vt8500_port) return -ENOMEM; vt8500_port->uart.membase = devm_ioremap_resource(&pdev->dev, mmres); if (IS_ERR(vt8500_port->uart.membase)) return PTR_ERR(vt8500_port->uart.membase); vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); if (IS_ERR(vt8500_port->clk)) { dev_err(&pdev->dev, "failed to get clock\n"); return -EINVAL; } ret = clk_prepare_enable(vt8500_port->clk); if (ret) { dev_err(&pdev->dev, "failed to enable clock\n"); return ret; } vt8500_port->vt8500_uart_flags = *flags; vt8500_port->clk_predivisor = DIV_ROUND_CLOSEST( clk_get_rate(vt8500_port->clk), VT8500_RECOMMENDED_CLK ); vt8500_port->uart.type = PORT_VT8500; vt8500_port->uart.iotype = UPIO_MEM; vt8500_port->uart.mapbase = mmres->start; vt8500_port->uart.irq = irqres->start; vt8500_port->uart.fifosize = 16; vt8500_port->uart.ops = &vt8500_uart_pops; vt8500_port->uart.line = port; vt8500_port->uart.dev = &pdev->dev; vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; /* Serial core uses the magic "16" everywhere - adjust for it */ vt8500_port->uart.uartclk = 16 * clk_get_rate(vt8500_port->clk) / vt8500_port->clk_predivisor / VT8500_OVERSAMPLING_DIVISOR; snprintf(vt8500_port->name, sizeof(vt8500_port->name), "VT8500 UART%d", pdev->id); vt8500_uart_ports[port] = vt8500_port; uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); platform_set_drvdata(pdev, vt8500_port); return 0; }
static int timbuart_probe(struct platform_device *dev) { int err; struct timbuart_port *uart; struct resource *iomem; dev_dbg(&dev->dev, "%s\n", __func__); uart = kzalloc(sizeof(*uart), GFP_KERNEL); if (!uart) { err = -EINVAL; goto err_mem; } uart->usedma = 0; uart->port.uartclk = 3250000 * 16; uart->port.fifosize = TIMBUART_FIFO_SIZE; uart->port.regshift = 2; uart->port.iotype = UPIO_MEM; uart->port.ops = &timbuart_ops; uart->port.irq = 0; uart->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP; uart->port.line = 0; uart->port.dev = &dev->dev; iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!iomem) { err = -ENOMEM; goto err_register; } uart->port.mapbase = iomem->start; uart->port.membase = NULL; uart->port.irq = platform_get_irq(dev, 0); if (uart->port.irq < 0) { err = -EINVAL; goto err_register; } tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); err = uart_register_driver(&timbuart_driver); if (err) goto err_register; err = uart_add_one_port(&timbuart_driver, &uart->port); if (err) goto err_add_port; platform_set_drvdata(dev, uart); return 0; err_add_port: uart_unregister_driver(&timbuart_driver); err_register: kfree(uart); err_mem: printk(KERN_ERR "timberdale: Failed to register Timberdale UART: %d\n", err); return err; }
static int serial_hsu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct uart_hsu_port *uport; int index, ret; printk(KERN_INFO "HSU: found PCI Serial controller(ID: %04x:%04x)\n", pdev->vendor, pdev->device); switch (pdev->device) { case 0x081B: index = 0; break; case 0x081C: index = 1; break; case 0x081D: index = 2; break; case 0x081E: /* internal DMA controller */ index = 3; break; default: dev_err(&pdev->dev, "HSU: out of index!"); return -ENODEV; } ret = pci_enable_device(pdev); if (ret) return ret; if (index == 3) { /* DMA controller */ ret = request_irq(pdev->irq, dma_irq, 0, "hsu_dma", phsu); if (ret) { dev_err(&pdev->dev, "can not get IRQ\n"); goto err_disable; } pci_set_drvdata(pdev, phsu); } else { /* UART port 0~2 */ uport = &phsu->port[index]; uport->port.irq = pdev->irq; uport->port.dev = &pdev->dev; uport->dev = &pdev->dev; ret = request_irq(pdev->irq, port_irq, 0, uport->name, uport); if (ret) { dev_err(&pdev->dev, "can not get IRQ\n"); goto err_disable; } uart_add_one_port(&serial_hsu_reg, &uport->port); #ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE if (index == 2) { register_console(&serial_hsu_console); uport->port.cons = &serial_hsu_console; } #endif pci_set_drvdata(pdev, uport); } return 0; err_disable: pci_disable_device(pdev); return ret; }
static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, struct regmap *regmap, int irq, unsigned long flags) { int i, ret, fmin, fmax, freq, uartclk; struct clk *clk_osc, *clk_xtal; struct max310x_port *s; bool xtal = false; if (IS_ERR(regmap)) return PTR_ERR(regmap); /* Alloc port structure */ s = devm_kzalloc(dev, sizeof(*s) + sizeof(struct max310x_one) * devtype->nr, GFP_KERNEL); if (!s) { dev_err(dev, "Error allocating port structure\n"); return -ENOMEM; } clk_osc = devm_clk_get(dev, "osc"); clk_xtal = devm_clk_get(dev, "xtal"); if (!IS_ERR(clk_osc)) { s->clk = clk_osc; fmin = 500000; fmax = 35000000; } else if (!IS_ERR(clk_xtal)) { s->clk = clk_xtal; fmin = 1000000; fmax = 4000000; xtal = true; } else if (PTR_ERR(clk_osc) == -EPROBE_DEFER || PTR_ERR(clk_xtal) == -EPROBE_DEFER) { return -EPROBE_DEFER; } else { dev_err(dev, "Cannot get clock\n"); return -EINVAL; } ret = clk_prepare_enable(s->clk); if (ret) return ret; freq = clk_get_rate(s->clk); /* Check frequency limits */ if (freq < fmin || freq > fmax) { ret = -ERANGE; goto out_clk; } s->regmap = regmap; s->devtype = devtype; dev_set_drvdata(dev, s); /* Check device to ensure we are talking to what we expect */ ret = devtype->detect(dev); if (ret) goto out_clk; for (i = 0; i < devtype->nr; i++) { unsigned int offs = i << 5; /* Reset port */ regmap_write(s->regmap, MAX310X_MODE2_REG + offs, MAX310X_MODE2_RST_BIT); /* Clear port reset */ regmap_write(s->regmap, MAX310X_MODE2_REG + offs, 0); /* Wait for port startup */ do { regmap_read(s->regmap, MAX310X_BRGDIVLSB_REG + offs, &ret); } while (ret != 0x01); regmap_update_bits(s->regmap, MAX310X_MODE1_REG + offs, MAX310X_MODE1_AUTOSLEEP_BIT, MAX310X_MODE1_AUTOSLEEP_BIT); } uartclk = max310x_set_ref_clk(s, freq, xtal); dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); /* Register UART driver */ s->uart.owner = THIS_MODULE; s->uart.dev_name = "ttyMAX"; s->uart.major = MAX310X_MAJOR; s->uart.minor = MAX310X_MINOR; s->uart.nr = devtype->nr; ret = uart_register_driver(&s->uart); if (ret) { dev_err(dev, "Registering UART driver failed\n"); goto out_clk; } #ifdef CONFIG_GPIOLIB /* Setup GPIO cotroller */ s->gpio.owner = THIS_MODULE; s->gpio.dev = dev; s->gpio.label = dev_name(dev); s->gpio.direction_input = max310x_gpio_direction_input; s->gpio.get = max310x_gpio_get; s->gpio.direction_output= max310x_gpio_direction_output; s->gpio.set = max310x_gpio_set; s->gpio.base = -1; s->gpio.ngpio = devtype->nr * 4; s->gpio.can_sleep = 1; ret = gpiochip_add(&s->gpio); if (ret) goto out_uart; #endif mutex_init(&s->mutex); for (i = 0; i < devtype->nr; i++) { /* Initialize port data */ s->p[i].port.line = i; s->p[i].port.dev = dev; s->p[i].port.irq = irq; s->p[i].port.type = PORT_MAX310X; s->p[i].port.fifosize = MAX310X_FIFO_SIZE; s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; s->p[i].port.iotype = UPIO_PORT; s->p[i].port.iobase = i * 0x20; s->p[i].port.membase = (void __iomem *)~0; s->p[i].port.uartclk = uartclk; s->p[i].port.rs485_config = max310x_rs485_config; s->p[i].port.ops = &max310x_ops; /* Disable all interrupts */ max310x_port_write(&s->p[i].port, MAX310X_IRQEN_REG, 0); /* Clear IRQ status register */ max310x_port_read(&s->p[i].port, MAX310X_IRQSTS_REG); /* Enable IRQ pin */ max310x_port_update(&s->p[i].port, MAX310X_MODE1_REG, MAX310X_MODE1_IRQSEL_BIT, MAX310X_MODE1_IRQSEL_BIT); /* Initialize queue for start TX */ INIT_WORK(&s->p[i].tx_work, max310x_wq_proc); /* Initialize queue for changing mode */ INIT_WORK(&s->p[i].md_work, max310x_md_proc); /* Register port */ uart_add_one_port(&s->uart, &s->p[i].port); /* Go to suspend mode */ devtype->power(&s->p[i].port, 0); } /* Setup interrupt */ ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist, IRQF_ONESHOT | flags, dev_name(dev), s); if (!ret) return 0; dev_err(dev, "Unable to reguest IRQ %i\n", irq); mutex_destroy(&s->mutex); #ifdef CONFIG_GPIOLIB gpiochip_remove(&s->gpio); out_uart: #endif uart_unregister_driver(&s->uart); out_clk: clk_disable_unprepare(s->clk); return ret; }
static int sprd_probe(struct platform_device *pdev) { struct resource *res; struct uart_port *up; struct clk *clk; int irq; int index; int ret; for (index = 0; index < ARRAY_SIZE(sprd_port); index++) if (sprd_port[index] == NULL) break; if (index == ARRAY_SIZE(sprd_port)) return -EBUSY; index = sprd_probe_dt_alias(index, &pdev->dev); sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]), GFP_KERNEL); if (!sprd_port[index]) return -ENOMEM; up = &sprd_port[index]->port; up->dev = &pdev->dev; up->line = index; up->type = PORT_SPRD; up->iotype = UPIO_MEM; up->uartclk = SPRD_DEF_RATE; up->fifosize = SPRD_FIFO_SIZE; up->ops = &serial_sprd_ops; up->flags = UPF_BOOT_AUTOCONF; clk = devm_clk_get(&pdev->dev, NULL); if (!IS_ERR_OR_NULL(clk)) up->uartclk = clk_get_rate(clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "not provide mem resource\n"); return -ENODEV; } up->mapbase = res->start; up->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(up->membase)) return PTR_ERR(up->membase); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "not provide irq resource\n"); return -ENODEV; } up->irq = irq; if (!sprd_ports_num) { ret = uart_register_driver(&sprd_uart_driver); if (ret < 0) { pr_err("Failed to register SPRD-UART driver\n"); return ret; } } sprd_ports_num++; ret = uart_add_one_port(&sprd_uart_driver, up); if (ret) { sprd_port[index] = NULL; sprd_remove(pdev); } platform_set_drvdata(pdev, up); return ret; }
static int __devinit altera_uart_probe(struct platform_device *pdev) { struct altera_uart_platform_uart *platp = pdev->dev.platform_data; struct uart_port *port; struct resource *res_mem; struct resource *res_irq; int i = pdev->id; int ret; /* if id is -1 scan for a free id and use that one */ if (i == -1) { for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) if (altera_uart_ports[i].port.mapbase == 0) break; } if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) return -EINVAL; port = &altera_uart_ports[i].port; res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; else if (platp) port->mapbase = platp->mapbase; else return -EINVAL; res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) port->irq = res_irq->start; else if (platp) port->irq = platp->irq; /* Check platform data first so we can override device node data */ if (platp) port->uartclk = platp->uartclk; else { ret = altera_uart_get_of_uartclk(pdev, port); if (ret) return ret; } port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); if (!port->membase) return -ENOMEM; if (platp) port->regshift = platp->bus_shift; else port->regshift = 0; port->line = i; port->type = PORT_ALTERA_UART; port->iotype = SERIAL_IO_MEM; port->ops = &altera_uart_ops; port->flags = UPF_BOOT_AUTOCONF; dev_set_drvdata(&pdev->dev, port); uart_add_one_port(&altera_uart_driver, port); return 0; }
static int milkymist_uart_probe(struct platform_device *op) { struct uart_port *port; struct device_node *np = op->dev.of_node; int ret; struct resource res; const unsigned int *pid, *clk; int id; int irq; ret = of_address_to_resource(np, 0, &res); if (ret) { dev_err(&op->dev, "invalid address\n"); return ret; } irq = irq_of_parse_and_map(np, 0); clk = of_get_property(np, "clock-frequency", NULL); if (!clk) { dev_warn(&op->dev, "no clock-frequency property set\n"); return -ENODEV; } pid = of_get_property(np, "port-number", NULL); if (pid) id = *pid; else { /* find free id */ for (id = 0; id < MILKYMIST_NR_UARTS; id++) if (milkymist_uart_ports[id].mapbase == 0) break; } if (id < 0 || id >= MILKYMIST_NR_UARTS) { dev_err(&op->dev, "milkymist_uart%i too large\n", id); return -EINVAL; } if (milkymist_uart_ports[id].mapbase && milkymist_uart_ports[id].mapbase != res.start) { dev_err(&op->dev, "milkymist_uart%i already in use\n", id); return -EBUSY; } ret = uart_register_driver(&milkymist_uart_driver); if (ret) { dev_err(&op->dev, "uart_register_driver() failed; err=%i\n", ret); return ret; } port = &milkymist_uart_ports[id]; spin_lock_init(&port->lock); port->line = id; port->regshift = 2; port->iotype = UPIO_MEM; port->mapbase = res.start; port->membase = NULL; port->flags = UPF_BOOT_AUTOCONF; port->irq = irq; port->ops = &milkymist_uart_ops; port->type = PORT_UNKNOWN; port->uartclk = *clk; port->dev = &op->dev; dev_set_drvdata(&op->dev, port); ret = uart_add_one_port(&milkymist_uart_driver, port); if (ret) { dev_err(&op->dev, "uart_add_one_port() failed; err=%i\n", ret); port->mapbase = 0; return ret; } //device_init_wakeup(&op->dev, 1); return 0; }
static int serial_m3110_probe(struct spi_device *spi) { struct uart_max3110 *max; int ret; unsigned char *buffer; u16 res; max = kzalloc(sizeof(*max), GFP_KERNEL); if (!max) return -ENOMEM; /* set spi info */ spi->mode = SPI_MODE_0; spi->bits_per_word = 16; max->clock = MAX3110_HIGH_CLK; spi->controller_data = &spi0_uart; spi_setup(spi); max->port.type = PORT_PXA; /* need apply for a max3110 type */ max->port.fifosize = 2; /* only have 16b buffer */ max->port.ops = &serial_m3110_ops; max->port.line = 0; max->port.dev = &spi->dev; max->port.uartclk = 115200; max->spi = spi; max->name = spi->modalias; /* use spi name as the name */ max->irq = (u16)spi->irq; mutex_init(&max->thread_mutex); max->word_7bits = 0; max->parity = 0; max->baud = 0; max->cur_conf = 0; max->uart_flags = 0; /* Check if reading configuration register returns something sane */ res = RC_TAG; ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); if (ret < 0 || res == 0 || res == 0xffff) { printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)", res); ret = -ENODEV; goto err_get_page; } buffer = (unsigned char *)__get_free_page(GFP_KERNEL); if (!buffer) { ret = -ENOMEM; goto err_get_page; } max->con_xmit.buf = (unsigned char *)buffer; max->con_xmit.head = max->con_xmit.tail = 0; max->main_thread = kthread_run(max3110_main_thread, max, "max3110_main"); if (IS_ERR(max->main_thread)) { ret = PTR_ERR(max->main_thread); goto err_kthread; } pmax = max; /* give membase a psudo value to pass serial_core's check */ max->port.membase = (void *)0xff110000; uart_add_one_port(&serial_m3110_reg, &max->port); return 0; err_kthread: free_page((unsigned long)buffer); err_get_page: pmax = NULL; kfree(max); return ret; }
static int __devinit msm_serial_hsl_probe_irda(struct platform_device *pdev) { struct msm_hsl_port *msm_hsl_port; struct resource *uart_resource; struct resource *gsbi_resource; struct uart_port *port; const struct of_device_id *match; struct irda_platform_data *pdata; int ret; if (pdev->id == -1) pdev->id = atomic_inc_return(&msm_serial_hsl_next_id) - 1; if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial_irda: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; pdata = pdev->dev.platform_data; if (!pdata) { E("[irdaerror]%s: Assign platform_data error!!\n", __func__); return -ENXIO; } msm_hsl_port = UART_TO_MSM(port); msm_hsl_port->irda_enable= pdata->irda_enable; htc_irda_port = msm_hsl_port; match = of_match_device(msm_hsl_match_table, &pdev->dev); if (!match) msm_hsl_port->ver_id = UARTDM_VERSION_11_13; else { D("%s () match:port->line %d, ir\n", __func__, port->line); msm_hsl_port->ver_id = (unsigned int)match->data; } gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"); if (!gsbi_resource) { gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1); D("%s () gsbi_resourc:port->line %d, ir\n", __func__, port->line); } msm_hsl_port->clk = clk_get(&pdev->dev, "core_clk"); if (gsbi_resource) { printk(KERN_INFO "msm_serial_irda: get gsbi_uart_clk and gsbi_pclk\n"); msm_hsl_port->is_uartdm = 1; msm_hsl_port->pclk = clk_get(&pdev->dev, "iface_clk"); } else { printk(KERN_INFO "msm_serial_irda: get uartdm_clk\n"); msm_hsl_port->is_uartdm = 0; msm_hsl_port->pclk = NULL; } if (unlikely(IS_ERR(msm_hsl_port->clk))) { printk(KERN_ERR "%s: Error getting clk\n", __func__); return PTR_ERR(msm_hsl_port->clk); } if (unlikely(IS_ERR(msm_hsl_port->pclk))) { printk(KERN_ERR "%s: Error getting pclk\n", __func__); return PTR_ERR(msm_hsl_port->pclk); } uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uartdm_resource"); if (!uart_resource) uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!uart_resource)) { printk(KERN_ERR "getting uartdm_resource failed\n"); return -ENXIO; } port->mapbase = uart_resource->start; printk(KERN_INFO "msm_serial_hsl: port[%d] mapbase:%x\n", port->line, port->mapbase); port->irq = platform_get_irq(pdev, 0); if (unlikely((int)port->irq < 0)) { printk(KERN_ERR "%s: getting irq failed\n", __func__); return -ENXIO; } device_set_wakeup_capable(&pdev->dev, 1); platform_set_drvdata(pdev, port); pm_runtime_enable(port->dev); #ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE ret = device_create_file(&pdev->dev, &dev_attr_console); D("%s () device_create_file, port->line %d, ir\n", __func__, port->line); if (unlikely(ret)) E("%s():Can't create console attribute\n", __func__); #endif msm_hsl_debugfs_init(msm_hsl_port, pdev->id); /* Temporarily increase the refcount on the GSBI clock to avoid a race * condition with the earlyprintk handover mechanism. */ if (msm_hsl_port->pclk) { clk_prepare_enable(msm_hsl_port->pclk); D("%s () clk_enable, port->line %d, ir\n", __func__, port->line); } ret = uart_add_one_port(&msm_hsl_uart_driver, port); if (msm_hsl_port->pclk) { D("%s () clk_disabl, port->line %d, ir\n", __func__, port->line); clk_disable_unprepare(msm_hsl_port->pclk); } D("%s ():port->line %d, ir\n", __func__, port->line); msm_hsl_port->irda_class = class_create(THIS_MODULE, "htc_irda"); if (IS_ERR(msm_hsl_port->irda_class)) { ret = PTR_ERR(msm_hsl_port->irda_class); msm_hsl_port->irda_class = NULL; return -ENXIO; } msm_hsl_port->irda_dev = device_create(msm_hsl_port->irda_class, NULL, 0, "%s", "irda"); if (unlikely(IS_ERR(msm_hsl_port->irda_dev))) { ret = PTR_ERR(msm_hsl_port->irda_dev); msm_hsl_port->irda_dev = NULL; goto err_create_ls_device; } /* register the attributes */ ret = device_create_file(msm_hsl_port->irda_dev, &dev_attr_enable_irda); if (ret) goto err_create_ls_device_file; msm_hsl_write(port, 3, UARTDM_IRDA_ADDR); enable_irda(0);/*0 disable, 3=enable, 9=loopback*/ return ret; err_create_ls_device_file: device_unregister(msm_hsl_port->irda_dev); err_create_ls_device: class_destroy(msm_hsl_port->irda_class); return ret; return ret; }
static int tegra_uart_probe(struct platform_device *pdev) { struct tegra_uart_port *t; struct uart_port *u; struct resource *resource; int ret; char name[64]; if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) { pr_err("Invalid Uart instance (%d)\n", pdev->id); return -ENODEV; } t = kzalloc(sizeof(struct tegra_uart_port), GFP_KERNEL); if (!t) { pr_err("%s: Failed to allocate memory\n", __func__); return -ENOMEM; } u = &t->uport; u->dev = &pdev->dev; platform_set_drvdata(pdev, u); u->line = pdev->id; u->ops = &tegra_uart_ops; u->type = ~PORT_UNKNOWN; u->fifosize = 32; resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) { ret = -ENXIO; goto fail; } u->mapbase = resource->start; u->membase = IO_ADDRESS(u->mapbase); if (unlikely(!u->membase)) { ret = -ENOMEM; goto fail; } u->irq = platform_get_irq(pdev, 0); if (unlikely(u->irq < 0)) { ret = -ENXIO; goto fail; } u->regshift = 2; t->clk = clk_get(&pdev->dev, NULL); if (IS_ERR_OR_NULL(t->clk)) { dev_err(&pdev->dev, "Couldn't get the clock\n"); ret = -ENODEV; goto fail; } ret = uart_add_one_port(&tegra_uart_driver, u); if (ret) { pr_err("%s: Failed(%d) to add uart port %s%d\n", __func__, ret, tegra_uart_driver.dev_name, u->line); goto fail; } snprintf(name, sizeof(name), "tegra_hsuart_%d", u->line); pr_info("Registered UART port %s%d\n", tegra_uart_driver.dev_name, u->line); t->uart_state = TEGRA_UART_CLOSED; if (!RX_FORCE_PIO) { ret = tegra_uart_init_rx_dma_buffer(t); if (ret < 0) { pr_err("%s: Failed(%d) to allocate rx dma buffer " "%s%d\n", __func__, ret, tegra_uart_driver.dev_name, u->line); goto rx_dma_buff_fail; } } return ret; rx_dma_buff_fail: uart_remove_one_port(&tegra_uart_driver, u); fail: if (t->clk) clk_put(t->clk); platform_set_drvdata(pdev, NULL); kfree(t); return ret; }
static int serial_omap_probe(struct platform_device *pdev) { struct uart_omap_port *up = NULL; struct resource *mem, *irq, *dma_tx, *dma_rx; struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; struct omap_device *od; int ret = -ENOSPC; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "no irq resource?\n"); return -ENODEV; } if (!request_mem_region(mem->start, (mem->end - mem->start) + 1, pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); if (!dma_rx) { ret = -EINVAL; goto err; } dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); if (!dma_tx) { ret = -EINVAL; goto err; } up = kzalloc(sizeof(*up), GFP_KERNEL); if (up == NULL) { ret = -ENOMEM; goto do_release_region; } sprintf(up->name, "OMAP UART%d", pdev->id); up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.irq = irq->start; up->port.regshift = 2; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; up->port.line = pdev->id; up->port.mapbase = mem->start; up->port.membase = ioremap(mem->start, mem->end - mem->start); if (!up->port.membase) { dev_err(&pdev->dev, "can't ioremap UART\n"); ret = -ENOMEM; goto err1; } up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; up->uart_dma.uart_base = mem->start; up->errata = omap_up_info->errata; up->enable_wakeup = omap_up_info->enable_wakeup; up->wer = omap_up_info->wer; up->chk_wakeup = omap_up_info->chk_wakeup; up->wake_peer = omap_up_info->wake_peer; up->rts_mux_driver_control = omap_up_info->rts_mux_driver_control; up->rts_pullup_in_suspend = 0; if (omap_up_info->use_dma) { up->uart_dma.uart_dma_tx = dma_tx->start; up->uart_dma.uart_dma_rx = dma_rx->start; up->use_dma = 1; up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; } pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->auto_sus_timeout); if (device_may_wakeup(&pdev->dev)) pm_runtime_enable(&pdev->dev); pm_runtime_irq_safe(&pdev->dev); if (omap_up_info->console_uart) { od = to_omap_device(up->pdev); omap_hwmod_idle(od->hwmods[0]); serial_omap_port_enable(up); serial_omap_port_disable(up); } ui[pdev->id] = up; serial_omap_add_console_port(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto err1; dev_set_drvdata(&pdev->dev, up); platform_set_drvdata(pdev, up); return 0; err: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); err1: kfree(up); do_release_region: release_mem_region(mem->start, (mem->end - mem->start) + 1); return ret; }
static int __init msm_serial_probe(struct platform_device *pdev) { struct msm_port *msm_port; struct resource *resource; struct uart_port *port; int irq; #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP struct msm_serial_platform_data *pdata = pdev->dev.platform_data; #endif if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_port = UART_TO_MSM(port); msm_port->clk = clk_get(&pdev->dev, "core_clk"); if (unlikely(IS_ERR(msm_port->clk))) return PTR_ERR(msm_port->clk); port->uartclk = clk_get_rate(msm_port->clk); if (!port->uartclk) port->uartclk = 19200000; resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) return -ENXIO; port->mapbase = resource->start; irq = platform_get_irq(pdev, 0); if (unlikely(irq < 0)) return -ENXIO; port->irq = irq; platform_set_drvdata(pdev, port); #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP if (pdata == NULL) msm_port->wakeup.irq = -1; else { msm_port->wakeup.irq = pdata->wakeup_irq; msm_port->wakeup.ignore = 1; msm_port->wakeup.inject_rx = pdata->inject_rx_on_wakeup; msm_port->wakeup.rx_to_inject = pdata->rx_to_inject; if (unlikely(msm_port->wakeup.irq <= 0)) return -EINVAL; } #endif #ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL msm_port->clk_state = MSM_CLK_PORT_OFF; hrtimer_init(&msm_port->clk_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); msm_port->clk_off_timer.function = msm_serial_clock_off; msm_port->clk_off_delay = ktime_set(0, 1000000); /* 1 ms */ #endif pm_runtime_enable(port->dev); return uart_add_one_port(&msm_uart_driver, port); }
int sirfsoc_uart_probe(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport; struct uart_port *port; struct resource *res; int ret; if (of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id)) { dev_err(&pdev->dev, "Unable to find cell-index in uart node.\n"); ret = -EFAULT; goto err; } sirfport = &sirfsoc_uart_ports[pdev->id]; port = &sirfport->port; port->dev = &pdev->dev; port->private_data = sirfport; if (of_find_property(pdev->dev.of_node, "hw_flow_ctrl", NULL)) sirfport->hw_flow_ctrl = 1; if (of_property_read_u32(pdev->dev.of_node, "fifosize", &port->fifosize)) { dev_err(&pdev->dev, "Unable to find fifosize in uart node.\n"); ret = -EFAULT; goto err; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } port->mapbase = res->start; port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!port->membase) { dev_err(&pdev->dev, "Cannot remap resource.\n"); ret = -ENOMEM; goto err; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } port->irq = res->start; if (sirfport->hw_flow_ctrl) { sirfport->p = pinctrl_get_select_default(&pdev->dev); if (IS_ERR(sirfport->p)) { ret = PTR_ERR(sirfport->p); goto err; } } sirfport->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(sirfport->clk)) { ret = PTR_ERR(sirfport->clk); goto clk_err; } clk_prepare_enable(sirfport->clk); port->uartclk = clk_get_rate(sirfport->clk); port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); platform_set_drvdata(pdev, sirfport); ret = uart_add_one_port(&sirfsoc_uart_drv, port); if (ret != 0) { dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); goto port_err; } return 0; port_err: clk_disable_unprepare(sirfport->clk); clk_put(sirfport->clk); clk_err: platform_set_drvdata(pdev, NULL); if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); err: return ret; }
static int sirfsoc_uart_probe(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport; struct uart_port *port; struct resource *res; int ret; int i, j; struct dma_slave_config slv_cfg = { .src_maxburst = 2, }; struct dma_slave_config tx_slv_cfg = { .dst_maxburst = 2, }; const struct of_device_id *match; match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); if (of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id)) { dev_err(&pdev->dev, "Unable to find cell-index in uart node.\n"); ret = -EFAULT; goto err; } if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) pdev->id += ((struct sirfsoc_uart_register *) match->data)->uart_param.register_uart_nr; sirfport = &sirfsoc_uart_ports[pdev->id]; port = &sirfport->port; port->dev = &pdev->dev; port->private_data = sirfport; sirfport->uart_reg = (struct sirfsoc_uart_register *)match->data; sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, "sirf,uart-has-rtscts"); if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) sirfport->uart_reg->uart_type = SIRF_REAL_UART; if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) { sirfport->uart_reg->uart_type = SIRF_USP_UART; if (!sirfport->hw_flow_ctrl) goto usp_no_flow_control; if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL)) sirfport->cts_gpio = of_get_named_gpio( pdev->dev.of_node, "cts-gpios", 0); else sirfport->cts_gpio = -1; if (of_find_property(pdev->dev.of_node, "rts-gpios", NULL)) sirfport->rts_gpio = of_get_named_gpio( pdev->dev.of_node, "rts-gpios", 0); else sirfport->rts_gpio = -1; if ((!gpio_is_valid(sirfport->cts_gpio) || !gpio_is_valid(sirfport->rts_gpio))) { ret = -EINVAL; dev_err(&pdev->dev, "Usp flow control must have cts and rts gpio"); goto err; } ret = devm_gpio_request(&pdev->dev, sirfport->cts_gpio, "usp-cts-gpio"); if (ret) { dev_err(&pdev->dev, "Unable request cts gpio"); goto err; } gpio_direction_input(sirfport->cts_gpio); ret = devm_gpio_request(&pdev->dev, sirfport->rts_gpio, "usp-rts-gpio"); if (ret) { dev_err(&pdev->dev, "Unable request rts gpio"); goto err; } gpio_direction_output(sirfport->rts_gpio, 1); } usp_no_flow_control: if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart")) sirfport->is_atlas7 = true; if (of_property_read_u32(pdev->dev.of_node, "fifosize", &port->fifosize)) { dev_err(&pdev->dev, "Unable to find fifosize in uart node.\n"); ret = -EFAULT; goto err; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } tasklet_init(&sirfport->rx_dma_complete_tasklet, sirfsoc_uart_rx_dma_complete_tl, (unsigned long)sirfport); tasklet_init(&sirfport->rx_tmo_process_tasklet, sirfsoc_rx_tmo_process_tl, (unsigned long)sirfport); port->mapbase = res->start; port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!port->membase) { dev_err(&pdev->dev, "Cannot remap resource.\n"); ret = -ENOMEM; goto err; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } port->irq = res->start; sirfport->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(sirfport->clk)) { ret = PTR_ERR(sirfport->clk); goto err; } port->uartclk = clk_get_rate(sirfport->clk); if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-bt-uart")) { sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); if (IS_ERR(sirfport->clk_general)) { ret = PTR_ERR(sirfport->clk_general); goto err; } sirfport->clk_noc = devm_clk_get(&pdev->dev, "noc"); if (IS_ERR(sirfport->clk_noc)) { ret = PTR_ERR(sirfport->clk_noc); goto err; } sirfport->is_bt_uart = true; } else sirfport->is_bt_uart = false; port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); platform_set_drvdata(pdev, sirfport); ret = uart_add_one_port(&sirfsoc_uart_drv, port); if (ret != 0) { dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); goto err; } sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); for (i = 0; sirfport->rx_dma_chan && i < SIRFSOC_RX_LOOP_BUF_CNT; i++) { sirfport->rx_dma_items[i].xmit.buf = dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL); if (!sirfport->rx_dma_items[i].xmit.buf) { dev_err(port->dev, "Uart alloc bufa failed\n"); ret = -ENOMEM; goto alloc_coherent_err; } sirfport->rx_dma_items[i].xmit.head = sirfport->rx_dma_items[i].xmit.tail = 0; } if (sirfport->rx_dma_chan) dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg); sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx"); if (sirfport->tx_dma_chan) dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg); return 0; alloc_coherent_err: for (j = 0; j < i; j++) dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, sirfport->rx_dma_items[j].xmit.buf, sirfport->rx_dma_items[j].dma_addr); dma_release_channel(sirfport->rx_dma_chan); err: return ret; } static int sirfsoc_uart_remove(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); struct uart_port *port = &sirfport->port; uart_remove_one_port(&sirfsoc_uart_drv, port); if (sirfport->rx_dma_chan) { int i; dmaengine_terminate_all(sirfport->rx_dma_chan); dma_release_channel(sirfport->rx_dma_chan); for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, sirfport->rx_dma_items[i].xmit.buf, sirfport->rx_dma_items[i].dma_addr); } if (sirfport->tx_dma_chan) { dmaengine_terminate_all(sirfport->tx_dma_chan); dma_release_channel(sirfport->tx_dma_chan); } return 0; } #ifdef CONFIG_PM_SLEEP static int sirfsoc_uart_suspend(struct device *pdev) { struct sirfsoc_uart_port *sirfport = dev_get_drvdata(pdev); struct uart_port *port = &sirfport->port; uart_suspend_port(&sirfsoc_uart_drv, port); return 0; } static int sirfsoc_uart_resume(struct device *pdev) { struct sirfsoc_uart_port *sirfport = dev_get_drvdata(pdev); struct uart_port *port = &sirfport->port; uart_resume_port(&sirfsoc_uart_drv, port); return 0; } #endif static const struct dev_pm_ops sirfsoc_uart_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(sirfsoc_uart_suspend, sirfsoc_uart_resume) }; static struct platform_driver sirfsoc_uart_driver = { .probe = sirfsoc_uart_probe, .remove = sirfsoc_uart_remove, .driver = { .name = SIRFUART_PORT_NAME, .of_match_table = sirfsoc_uart_ids, .pm = &sirfsoc_uart_pm_ops, }, }; static int __init sirfsoc_uart_init(void) { int ret = 0; ret = uart_register_driver(&sirfsoc_uart_drv); if (ret) goto out; ret = platform_driver_register(&sirfsoc_uart_driver); if (ret) uart_unregister_driver(&sirfsoc_uart_drv); out: return ret; } module_init(sirfsoc_uart_init); static void __exit sirfsoc_uart_exit(void) { platform_driver_unregister(&sirfsoc_uart_driver); uart_unregister_driver(&sirfsoc_uart_drv); }
static int __devinit sc26xx_probe(struct platform_device *dev) { struct resource *res; struct uart_sc26xx_port *up; unsigned int *sc26xx_data = dev->dev.platform_data; int err; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; up = kzalloc(sizeof *up, GFP_KERNEL); if (unlikely(!up)) return -ENOMEM; up->port[0].line = 0; up->port[0].ops = &sc26xx_ops; up->port[0].type = PORT_SC26XX; up->port[0].uartclk = (29491200 / 16); /* arbitrary */ up->port[0].mapbase = res->start; up->port[0].membase = ioremap_nocache(up->port[0].mapbase, 0x40); up->port[0].iotype = UPIO_MEM; up->port[0].irq = platform_get_irq(dev, 0); up->port[0].dev = &dev->dev; sc26xx_init_masks(up, 0, sc26xx_data[0]); sc26xx_port = &up->port[0]; up->port[1].line = 1; up->port[1].ops = &sc26xx_ops; up->port[1].type = PORT_SC26XX; up->port[1].uartclk = (29491200 / 16); /* arbitrary */ up->port[1].mapbase = up->port[0].mapbase; up->port[1].membase = up->port[0].membase; up->port[1].iotype = UPIO_MEM; up->port[1].irq = up->port[0].irq; up->port[1].dev = &dev->dev; sc26xx_init_masks(up, 1, sc26xx_data[1]); err = uart_register_driver(&sc26xx_reg); if (err) goto out_free_port; sc26xx_reg.tty_driver->name_base = sc26xx_reg.minor; err = uart_add_one_port(&sc26xx_reg, &up->port[0]); if (err) goto out_unregister_driver; err = uart_add_one_port(&sc26xx_reg, &up->port[1]); if (err) goto out_remove_port0; err = request_irq(up->port[0].irq, sc26xx_interrupt, 0, "sc26xx", up); if (err) goto out_remove_ports; dev_set_drvdata(&dev->dev, up); return 0; out_remove_ports: uart_remove_one_port(&sc26xx_reg, &up->port[1]); out_remove_port0: uart_remove_one_port(&sc26xx_reg, &up->port[0]); out_unregister_driver: uart_unregister_driver(&sc26xx_reg); out_free_port: kfree(up); sc26xx_port = NULL; return err; }
static int uart_clps711x_probe(struct platform_device *pdev) { struct clps711x_port *s; int ret, i; s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL); if (!s) { dev_err(&pdev->dev, "Error allocating port structure\n"); return -ENOMEM; } platform_set_drvdata(pdev, s); s->uart_clk = devm_clk_get(&pdev->dev, "uart"); if (IS_ERR(s->uart_clk)) { dev_err(&pdev->dev, "Can't get UART clocks\n"); ret = PTR_ERR(s->uart_clk); goto err_out; } s->uart.owner = THIS_MODULE; s->uart.dev_name = "ttyCL"; s->uart.major = UART_CLPS711X_MAJOR; s->uart.minor = UART_CLPS711X_MINOR; s->uart.nr = UART_CLPS711X_NR; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE s->uart.cons = &s->console; s->uart.cons->device = uart_console_device; s->uart.cons->write = uart_clps711x_console_write; s->uart.cons->setup = uart_clps711x_console_setup; s->uart.cons->flags = CON_PRINTBUFFER; s->uart.cons->index = -1; s->uart.cons->data = s; strcpy(s->uart.cons->name, "ttyCL"); #endif ret = uart_register_driver(&s->uart); if (ret) { dev_err(&pdev->dev, "Registering UART driver failed\n"); devm_clk_put(&pdev->dev, s->uart_clk); goto err_out; } for (i = 0; i < UART_CLPS711X_NR; i++) { s->port[i].line = i; s->port[i].dev = &pdev->dev; s->port[i].irq = TX_IRQ(&s->port[i]); s->port[i].iobase = SYSCON(&s->port[i]); s->port[i].type = PORT_CLPS711X; s->port[i].fifosize = 16; s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; s->port[i].uartclk = clk_get_rate(s->uart_clk); s->port[i].ops = &uart_clps711x_ops; WARN_ON(uart_add_one_port(&s->uart, &s->port[i])); } return 0; err_out: platform_set_drvdata(pdev, NULL); return ret; }
/** * cdns_uart_probe - Platform driver probe * @pdev: Pointer to the platform device structure * * Return: 0 on success, negative errno otherwise */ static int cdns_uart_probe(struct platform_device *pdev) { int rc, id; struct uart_port *port; struct resource *res, *res2; struct cdns_uart *cdns_uart_data; cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data), GFP_KERNEL); if (!cdns_uart_data) return -ENOMEM; cdns_uart_data->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(cdns_uart_data->pclk)) { cdns_uart_data->pclk = devm_clk_get(&pdev->dev, "aper_clk"); if (!IS_ERR(cdns_uart_data->pclk)) dev_err(&pdev->dev, "clock name 'aper_clk' is deprecated.\n"); } if (IS_ERR(cdns_uart_data->pclk)) { dev_err(&pdev->dev, "pclk clock not found.\n"); return PTR_ERR(cdns_uart_data->pclk); } cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk"); if (IS_ERR(cdns_uart_data->uartclk)) { cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "ref_clk"); if (!IS_ERR(cdns_uart_data->uartclk)) dev_err(&pdev->dev, "clock name 'ref_clk' is deprecated.\n"); } if (IS_ERR(cdns_uart_data->uartclk)) { dev_err(&pdev->dev, "uart_clk clock not found.\n"); return PTR_ERR(cdns_uart_data->uartclk); } rc = clk_prepare_enable(cdns_uart_data->pclk); if (rc) { dev_err(&pdev->dev, "Unable to enable pclk clock.\n"); return rc; } rc = clk_prepare_enable(cdns_uart_data->uartclk); if (rc) { dev_err(&pdev->dev, "Unable to enable device clock.\n"); goto err_out_clk_dis_pclk; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { rc = -ENODEV; goto err_out_clk_disable; } res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res2) { rc = -ENODEV; goto err_out_clk_disable; } #ifdef CONFIG_COMMON_CLK cdns_uart_data->clk_rate_change_nb.notifier_call = cdns_uart_clk_notifier_cb; if (clk_notifier_register(cdns_uart_data->uartclk, &cdns_uart_data->clk_rate_change_nb)) dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); #endif /* Look for a serialN alias */ id = of_alias_get_id(pdev->dev.of_node, "serial"); if (id < 0) id = 0; /* Initialize the port structure */ port = cdns_uart_get_port(id); if (!port) { dev_err(&pdev->dev, "Cannot get uart_port structure\n"); rc = -ENODEV; goto err_out_notif_unreg; } else { /* Register the port. * This function also registers this device with the tty layer * and triggers invocation of the config_port() entry point. */ port->mapbase = res->start; port->irq = res2->start; port->dev = &pdev->dev; port->uartclk = clk_get_rate(cdns_uart_data->uartclk); port->private_data = cdns_uart_data; cdns_uart_data->port = port; platform_set_drvdata(pdev, port); rc = uart_add_one_port(&cdns_uart_uart_driver, port); if (rc) { dev_err(&pdev->dev, "uart_add_one_port() failed; err=%i\n", rc); goto err_out_notif_unreg; } return 0; } err_out_notif_unreg: #ifdef CONFIG_COMMON_CLK clk_notifier_unregister(cdns_uart_data->uartclk, &cdns_uart_data->clk_rate_change_nb); #endif err_out_clk_disable: clk_disable_unprepare(cdns_uart_data->uartclk); err_out_clk_dis_pclk: clk_disable_unprepare(cdns_uart_data->pclk); return rc; }
static int __devinit mxs_auart_probe(struct platform_device *pdev) { struct mxs_auart_port *s; u32 version; int ret = 0; struct resource *r; s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL); if (!s) { ret = -ENOMEM; goto out; } s->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(s->clk)) { ret = PTR_ERR(s->clk); goto out_free; } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { ret = -ENXIO; goto out_free_clk; } s->port.mapbase = r->start; s->port.membase = ioremap(r->start, resource_size(r)); s->port.ops = &mxs_auart_ops; s->port.iotype = UPIO_MEM; s->port.line = pdev->id < 0 ? 0 : pdev->id; s->port.fifosize = 16; s->port.uartclk = clk_get_rate(s->clk); s->port.type = PORT_IMX; s->port.dev = s->dev = get_device(&pdev->dev); s->flags = 0; s->ctrl = 0; s->irq = platform_get_irq(pdev, 0); s->port.irq = s->irq; ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s); if (ret) goto out_free_clk; platform_set_drvdata(pdev, s); auart_port[pdev->id] = s; mxs_auart_reset(&s->port); ret = uart_add_one_port(&auart_driver, &s->port); if (ret) goto out_free_irq; version = readl(s->port.membase + AUART_VERSION); dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", (version >> 24) & 0xff, (version >> 16) & 0xff, version & 0xffff); return 0; out_free_irq: auart_port[pdev->id] = NULL; free_irq(s->irq, s); out_free_clk: clk_put(s->clk); out_free: kfree(s); out: return ret; }
static int serial_omap_probe(struct platform_device *pdev) { struct uart_omap_port *up; struct resource *mem, *irq, *dma_tx, *dma_rx; struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; int ret = -ENOSPC; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "no irq resource?\n"); return -ENODEV; } if (!request_mem_region(mem->start, (mem->end - mem->start) + 1, pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); if (!dma_rx) { ret = -EINVAL; goto err; } dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); if (!dma_tx) { ret = -EINVAL; goto err; } up = kzalloc(sizeof(*up), GFP_KERNEL); if (up == NULL) { ret = -ENOMEM; goto do_release_region; } sprintf(up->name, "OMAP UART%d", pdev->id); up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.irq = irq->start; up->port.regshift = 2; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; up->port.line = pdev->id; up->port.membase = omap_up_info->membase; up->port.mapbase = omap_up_info->mapbase; up->port.flags = omap_up_info->flags; up->port.irqflags = omap_up_info->irqflags; up->port.uartclk = omap_up_info->uartclk; up->uart_dma.uart_base = mem->start; if (omap_up_info->dma_enabled) { up->uart_dma.uart_dma_tx = dma_tx->start; up->uart_dma.uart_dma_rx = dma_rx->start; up->use_dma = 1; up->uart_dma.rx_buf_size = 4096; up->uart_dma.rx_timeout = 2; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; } ui[pdev->id] = up; serial_omap_add_console_port(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto do_release_region; platform_set_drvdata(pdev, up); return 0; err: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); do_release_region: release_mem_region(mem->start, (mem->end - mem->start) + 1); return ret; }
static int serial_omap_probe(struct platform_device *pdev) { struct uart_omap_port *up; struct resource *mem, *irq; int ret = -ENOSPC; char str[7]; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "no irq resource?\n"); return -ENODEV; } ret = (int) request_mem_region(mem->start, (mem->end - mem->start) + 1, pdev->dev.driver->name); if (!ret) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } up = kzalloc(sizeof(*up), GFP_KERNEL); if (up == NULL) { ret = -ENOMEM; goto do_release_region; } sprintf(up->name, "OMAP UART%d", pdev->id); up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.mapbase = mem->start; up->port.irq = irq->start; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; up->port.line = pdev->id - 1; #define QUART_CLK (1843200) if (pdev->id == 4) { up->port.membase = ioremap_nocache(mem->start, 0x16 << 1); up->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ | UPF_TRIGGER_HIGH; up->port.uartclk = QUART_CLK; up->port.regshift = 1; } else { up->port.membase = (void *) io_p2v(mem->start); up->port.flags = UPF_BOOT_AUTOCONF; up->port.uartclk = 48000000; up->port.regshift = 2; } if (pdev->id == (UART1+1)) { #ifdef CONFIG_SERIAL_OMAP_DMA_UART1 up->use_dma = 1; up->uart_dma.rx_buf_size = CONFIG_SERIAL_OMAP_UART1_RXDMA_BUFSIZE; up->uart_dma.rx_timeout = CONFIG_SERIAL_OMAP_UART1_RXDMA_TIMEOUT; #endif } else if (pdev->id == (UART2+1)) { #ifdef CONFIG_SERIAL_OMAP_DMA_UART2 up->use_dma = 1; up->uart_dma.rx_buf_size = CONFIG_SERIAL_OMAP_UART2_RXDMA_BUFSIZE; up->uart_dma.rx_timeout = CONFIG_SERIAL_OMAP_UART2_RXDMA_TIMEOUT; #endif } else if (pdev->id == (UART3+1)) { #ifdef CONFIG_SERIAL_OMAP_DMA_UART3 up->use_dma = 1; up->uart_dma.rx_buf_size = CONFIG_SERIAL_OMAP_UART3_RXDMA_BUFSIZE; up->uart_dma.rx_timeout = CONFIG_SERIAL_OMAP_UART3_RXDMA_TIMEOUT; #endif } if (up->use_dma) { spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = 0xFF; up->uart_dma.rx_dma_channel = 0xFF; } if (console_detect(str)){ printk("Invalid console paramter. UART Library Init Failed!\n"); return -EPERM; } up->use_console = 0; fcr[pdev->id - 1] = 0; if (!strcmp(str, "ttyS0")) up->use_console = 1; else if (!strcmp(str, "ttyS1")) up->use_console = 1; else if (!strcmp(str, "ttyS2")) up->use_console = 1; else if (!strcmp(str, "ttyS3")) up->use_console = 1; else printk(KERN_INFO "!!!!!!!! Unable to recongnize Console UART........\n"); ui[pdev->id - 1] = up; serial_omap_add_console_port(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto do_release_region; platform_set_drvdata(pdev, up); return 0; do_release_region: release_mem_region(mem->start, (mem->end - mem->start) + 1); return ret; }