static int dw8250_probe_acpi(struct uart_8250_port *up, struct dw8250_data *data) { const struct acpi_device_id *id; struct uart_port *p = &up->port; dw8250_setup_port(up); id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); if (!id) return -ENODEV; p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; p->regshift = 2; if (!p->uartclk) p->uartclk = (unsigned int)id->driver_data; up->dma = &data->dma; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; return 0; }
static int dw8250_probe_acpi(struct uart_8250_port *up, struct dw8250_data *data) { struct uart_port *p = &up->port; dw8250_setup_port(up); p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; p->regshift = 2; /* Platforms with iDMA */ if (platform_get_resource_byname(to_platform_device(up->port.dev), IORESOURCE_MEM, "lpss_priv")) { data->dma.rx_param = up->port.dev->parent; data->dma.tx_param = up->port.dev->parent; data->dma.fn = dw8250_idma_filter; } up->dma = &data->dma; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; up->port.set_termios = dw8250_set_termios; return 0; }
static int dw8250_probe_of(struct uart_port *p, struct dw8250_data *data) { struct device_node *np = p->dev->of_node; struct uart_8250_port *up = up_to_u8250p(p); u32 val; bool has_ucv = true; if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { #ifdef __BIG_ENDIAN /* * Low order bits of these 64-bit registers, when * accessed as a byte, are 7 bytes further down in the * address space in big endian mode. */ p->membase += 7; #endif p->serial_out = dw8250_serial_out_rb; p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; p->type = PORT_OCTEON; data->usr_reg = 0x27; has_ucv = false; } else if (!of_property_read_u32(np, "reg-io-width", &val)) { switch (val) { case 1: break; case 4: p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; break; default: dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); return -EINVAL; } } if (has_ucv) dw8250_setup_port(up); if (!of_property_read_u32(np, "reg-shift", &val)) p->regshift = val; /* clock got configured through clk api, all done */ if (p->uartclk) return 0; /* try to find out clock frequency from DT as fallback */ if (of_property_read_u32(np, "clock-frequency", &val)) { dev_err(p->dev, "clk or clock-frequency not defined\n"); return -EINVAL; } p->uartclk = val; return 0; }
static int dw8250_probe_acpi(struct uart_8250_port *up, struct dw8250_data *data) { struct uart_port *p = &up->port; dw8250_setup_port(up); p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; p->regshift = 2; up->dma = &data->dma; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; up->port.set_termios = dw8250_set_termios; return 0; }
static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); struct dw8250_data *data; int err; if (!regs || !irq) { dev_err(&pdev->dev, "no registers/irq defined\n"); return -EINVAL; } spin_lock_init(&uart.port.lock); uart.port.mapbase = regs->start; uart.port.irq = irq->start; uart.port.handle_irq = dw8250_handle_irq; uart.port.pm = dw8250_do_pm; uart.port.type = PORT_8250; uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; uart.port.dev = &pdev->dev; uart.port.membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!uart.port.membase) return -ENOMEM; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->clk = devm_clk_get(&pdev->dev, NULL); if (!IS_ERR(data->clk)) { clk_prepare_enable(data->clk); uart.port.uartclk = clk_get_rate(data->clk); } uart.port.iotype = UPIO_MEM; uart.port.serial_in = dw8250_serial_in; uart.port.serial_out = dw8250_serial_out; uart.port.private_data = data; dw8250_setup_port(&uart); if (pdev->dev.of_node) { err = dw8250_probe_of(&uart.port); if (err) return err; } else if (ACPI_HANDLE(&pdev->dev)) { err = dw8250_probe_acpi(&uart); if (err) return err; } else { return -ENODEV; } data->line = serial8250_register_8250_port(&uart); if (data->line < 0) return data->line; platform_set_drvdata(pdev, data); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; }
static int dw8250_probe_of(struct uart_port *p, struct dw8250_data *data) { struct device_node *np = p->dev->of_node; struct uart_8250_port *up = up_to_u8250p(p); u32 val; bool has_ucv = true; int id; #ifdef CONFIG_64BIT if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { p->serial_in = dw8250_serial_inq; p->serial_out = dw8250_serial_outq; p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; p->type = PORT_OCTEON; data->usr_reg = 0x27; has_ucv = false; } else #endif if (!of_property_read_u32(np, "reg-io-width", &val)) { switch (val) { case 1: break; case 4: p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; break; default: dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); return -EINVAL; } } if (has_ucv) dw8250_setup_port(up); /* if we have a valid fifosize, try hooking up DMA here */ if (p->fifosize) { up->dma = &data->dma; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; } if (!of_property_read_u32(np, "reg-shift", &val)) p->regshift = val; /* get index of serial line, if found in DT aliases */ id = of_alias_get_id(np, "serial"); if (id >= 0) p->line = id; if (of_property_read_bool(np, "dcd-override")) { /* Always report DCD as active */ data->msr_mask_on |= UART_MSR_DCD; data->msr_mask_off |= UART_MSR_DDCD; } if (of_property_read_bool(np, "dsr-override")) { /* Always report DSR as active */ data->msr_mask_on |= UART_MSR_DSR; data->msr_mask_off |= UART_MSR_DDSR; } if (of_property_read_bool(np, "cts-override")) { /* Always report CTS as active */ data->msr_mask_on |= UART_MSR_CTS; data->msr_mask_off |= UART_MSR_DCTS; } if (of_property_read_bool(np, "ri-override")) { /* Always report Ring indicator as inactive */ data->msr_mask_off |= UART_MSR_RI; data->msr_mask_off |= UART_MSR_TERI; } return 0; }
static int dw8250_probe_of(struct uart_port *p, struct dw8250_data *data) { struct device_node *np = p->dev->of_node; struct uart_8250_port *up = up_to_u8250p(p); u32 val; bool has_ucv = true; int id; #ifdef CONFIG_64BIT if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { p->serial_in = dw8250_serial_inq; p->serial_out = dw8250_serial_outq; p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; p->type = PORT_OCTEON; data->usr_reg = 0x27; has_ucv = false; } else #endif if (!of_property_read_u32(np, "reg-io-width", &val)) { switch (val) { case 1: break; case 4: p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; break; default: dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); return -EINVAL; } } if (has_ucv) dw8250_setup_port(up); /* if we have a valid fifosize, try hooking up DMA here */ if (p->fifosize) { up->dma = &data->dma; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; } if (!of_property_read_u32(np, "reg-shift", &val)) p->regshift = val; /* get index of serial line, if found in DT aliases */ id = of_alias_get_id(np, "serial"); if (id >= 0) p->line = id; /* clock got configured through clk api, all done */ if (p->uartclk) return 0; /* try to find out clock frequency from DT as fallback */ if (of_property_read_u32(np, "clock-frequency", &val)) { dev_err(p->dev, "clk or clock-frequency not defined\n"); return -EINVAL; } p->uartclk = val; return 0; }
static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); int irq = platform_get_irq(pdev, 0); struct uart_port *p = &uart.port; struct dw8250_data *data; int err; u32 val; if (!regs) { dev_err(&pdev->dev, "no registers defined\n"); return -EINVAL; } if (irq < 0) { if (irq != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot get irq\n"); return irq; } spin_lock_init(&p->lock); p->mapbase = regs->start; p->irq = irq; p->handle_irq = dw8250_handle_irq; p->pm = dw8250_do_pm; p->type = PORT_8250; p->flags = UPF_SHARE_IRQ | UPF_FIXED_PORT; p->dev = &pdev->dev; p->iotype = UPIO_MEM; p->serial_in = dw8250_serial_in; p->serial_out = dw8250_serial_out; p->membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!p->membase) return -ENOMEM; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->dma.fn = dw8250_fallback_dma_filter; data->usr_reg = DW_UART_USR; p->private_data = data; data->uart_16550_compatible = device_property_read_bool(p->dev, "snps,uart-16550-compatible"); err = device_property_read_u32(p->dev, "reg-shift", &val); if (!err) p->regshift = val; err = device_property_read_u32(p->dev, "reg-io-width", &val); if (!err && val == 4) { p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; } if (device_property_read_bool(p->dev, "dcd-override")) { /* Always report DCD as active */ data->msr_mask_on |= UART_MSR_DCD; data->msr_mask_off |= UART_MSR_DDCD; } if (device_property_read_bool(p->dev, "dsr-override")) { /* Always report DSR as active */ data->msr_mask_on |= UART_MSR_DSR; data->msr_mask_off |= UART_MSR_DDSR; } if (device_property_read_bool(p->dev, "cts-override")) { /* Always report CTS as active */ data->msr_mask_on |= UART_MSR_CTS; data->msr_mask_off |= UART_MSR_DCTS; } if (device_property_read_bool(p->dev, "ri-override")) { /* Always report Ring indicator as inactive */ data->msr_mask_off |= UART_MSR_RI; data->msr_mask_off |= UART_MSR_TERI; } /* Always ask for fixed clock rate from a property. */ device_property_read_u32(p->dev, "clock-frequency", &p->uartclk); /* If there is separate baudclk, get the rate from it. */ data->clk = devm_clk_get(&pdev->dev, "baudclk"); if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER) data->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) return -EPROBE_DEFER; if (!IS_ERR_OR_NULL(data->clk)) { err = clk_prepare_enable(data->clk); if (err) dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n", err); else p->uartclk = clk_get_rate(data->clk); } /* If no clock rate is defined, fail. */ if (!p->uartclk) { dev_err(&pdev->dev, "clock rate not defined\n"); return -EINVAL; } data->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_clk; } if (!IS_ERR(data->pclk)) { err = clk_prepare_enable(data->pclk); if (err) { dev_err(&pdev->dev, "could not enable apb_pclk\n"); goto err_clk; } } data->rst = devm_reset_control_get_optional(&pdev->dev, NULL); if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_pclk; } if (!IS_ERR(data->rst)) reset_control_deassert(data->rst); dw8250_quirks(p, data); /* If the Busy Functionality is not implemented, don't handle it */ if (data->uart_16550_compatible) p->handle_irq = NULL; if (!data->skip_autocfg) dw8250_setup_port(p); /* If we have a valid fifosize, try hooking up DMA */ if (p->fifosize) { data->dma.rxconf.src_maxburst = p->fifosize / 4; data->dma.txconf.dst_maxburst = p->fifosize / 4; uart.dma = &data->dma; } data->line = serial8250_register_8250_port(&uart); if (data->line < 0) { err = data->line; goto err_reset; } platform_set_drvdata(pdev, data); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; err_reset: if (!IS_ERR(data->rst)) reset_control_assert(data->rst); err_pclk: if (!IS_ERR(data->pclk)) clk_disable_unprepare(data->pclk); err_clk: if (!IS_ERR(data->clk)) clk_disable_unprepare(data->clk); return err; }