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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}
Example #6
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;
}
Example #7
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;
}
Example #8
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;
}