All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
To: kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org
Cc: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	Lee Jones <lee-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>,
	Greg Kroah-Hartman
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	Jiri Slaby <jslaby-IBi9RG/b67k@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH V2 2/2] serial: bcm2835: add driver for bcm2835-aux-uart
Date: Mon, 11 Jan 2016 10:52:32 +0100	[thread overview]
Message-ID: <56937B60.5020200@i2se.com> (raw)
In-Reply-To: <1452344854-2576-3-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>

Hi Martin,

Am 09.01.2016 um 14:07 schrieb kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org:
> From: Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
>
> The bcm2835 SOC contains an auxiliary uart, which is very close
> to the ns16550 with some differences.
>
> The big difference is that the uart HW is not using an internal divider
> of 16 but 8, which results in an effictive baud-rate being twice
> the requested baud-rate.
>
> This driver handles this device correctly and handles the difference in
> the HW divider by scaling up the clock ba a factor of 2.
>
> The approach to write a separate (wrapper) driver instead of using a
> multiplying clock and "ns16550" as compatibility in the device-tree
> has been recommended by Stephen Warren.
>
> Signed-off-by: Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
> ---
>  drivers/tty/serial/8250/8250_bcm2835aux.c |  143 +++++++++++++++++++++++++++++
>  drivers/tty/serial/8250/Kconfig           |    8 ++
>  drivers/tty/serial/8250/Makefile          |    1 +
>  3 files changed, 152 insertions(+)
>  create mode 100644 drivers/tty/serial/8250/8250_bcm2835aux.c
>
> diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c
> new file mode 100644
> index 0000000..718c357
> --- /dev/null
> +++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
> @@ -0,0 +1,143 @@
> +/*
> + * Serial port driver for BCM2835AUX UART
> + *
> + * Copyright (C) 2016 Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
> + *
> + * Based on 8250_lpc18xx.c:
> + * Copyright (C) 2015 Joachim Eastwood <manabian-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include "8250.h"
> +
> +struct bcm2835aux_data {
> +	struct uart_8250_port uart;
> +	struct clk *clk;
> +};
> +
> +static int bcm2835aux_serial_probe(struct platform_device *pdev)
> +{
> +	struct bcm2835aux_data *data;
> +	struct resource *res;
> +	int ret;
> +
> +	/* allocate the custom structure */
> +	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	/* initialize data */
> +	spin_lock_init(&data->uart.port.lock);
> +	data->uart.port.dev = &pdev->dev;
> +	data->uart.port.regshift = 2;
> +	data->uart.port.type = PORT_16550;
> +	data->uart.port.iotype = UPIO_MEM;
> +	data->uart.port.fifosize = 8;

data->uart.capabilities = UART_CAP_FIFO; ?

> +	data->uart.port.flags = UPF_SHARE_IRQ |
> +				UPF_FIXED_PORT |
> +				UPF_FIXED_TYPE |
> +				UPF_SKIP_TEST;
> +
> +	/* get the clock - this also enables the HW */
> +	data->clk = devm_clk_get(&pdev->dev, NULL);
> +	ret = PTR_ERR_OR_ZERO(data->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not get clk: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* get the interrupt */
> +	data->uart.port.irq = platform_get_irq(pdev, 0);
> +	if (data->uart.port.irq < 0) {
> +		dev_err(&pdev->dev, "irq not found - %i",
> +			data->uart.port.irq);
> +		return data->uart.port.irq;
> +	}
> +
> +	/* map the main registers */
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "memory resource not found");
> +		return -EINVAL;
> +	}
> +	data->uart.port.membase = devm_ioremap_resource(&pdev->dev, res);
> +	ret = PTR_ERR_OR_ZERO(data->uart.port.membase);
> +	if (ret)
> +		return ret;
> +
> +	/* Check for a fixed line number */
> +	ret = of_alias_get_id(pdev->dev.of_node, "serial");
> +	if (ret >= 0)
> +		data->uart.port.line = ret;
> +
> +	/* enable the clock as a last step */
> +	ret = clk_prepare_enable(data->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to enable uart clock\n");
> +		return ret;
> +	}
> +
> +	/* the HW-clock divider for bcm2835aux is 8,
> +	 * but 8250 expects a divider of 16,
> +	 * so we have to multiply the actual clock by 2
> +	 * to get identical baudrates.
> +	 */
> +	data->uart.port.uartclk = clk_get_rate(data->clk) * 2;
> +
> +	/* register the port */
> +	ret = serial8250_register_8250_port(&data->uart);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev,
> +			"unable to register 8250 port - %d\n", ret);

This should fit in one line.

> +		goto dis_clk;
> +	}
> +	data->uart.port.line = ret;

This looks wrong because it overwrites the result of of_alias_get_id.
Either
you store it in a new member of bcm2835aux_data or drop the assignment.

> +
> +	platform_set_drvdata(pdev, data);
> +
> +	return 0;
> +
> +dis_clk:
> +	clk_disable_unprepare(data->clk);
> +	return ret;
> +}
> +
> +static int bcm2835aux_serial_remove(struct platform_device *pdev)
> +{
> +	struct bcm2835aux_data *data = platform_get_drvdata(pdev);
> +
> +	serial8250_unregister_port(data->uart.port.line);
> +	clk_disable_unprepare(data->clk);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id bcm2835aux_serial_match[] = {
> +	{ .compatible = "brcm,bcm2835-aux-uart" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, bcm2835aux_serial_match);
> +
> +static struct platform_driver bcm2835aux_serial_driver = {
> +	.driver = {
> +		.name = "bcm2835-aux-uart",
> +		.of_match_table = bcm2835aux_serial_match,
> +	},
> +	.probe  = bcm2835aux_serial_probe,
> +	.remove = bcm2835aux_serial_remove,
> +};
> +module_platform_driver(bcm2835aux_serial_driver);
> +
> +MODULE_DESCRIPTION("BCM2835 auxiliar UART driver");
> +MODULE_AUTHOR("Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 6412f14..105aa19 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -272,6 +272,14 @@ config SERIAL_8250_ACORN
>  	  system, say Y to this option.  The driver can handle 1, 2, or 3 port
>  	  cards.  If unsure, say N.
>  
> +config SERIAL_8250_BCM2835AUX
> +	tristate "BCM2835 auxiliar uart support"

BCM2835 auxiliary mini UART support

> +	depends on ARCH_BCM2835 || COMPILE_TEST
> +	depends on SERIAL_8250 && SERIAL_8250_SHARE_IRQ
> +	help
> +	  support for the BCM2835 auxiliar uart.

auxiliary UART

Since it's a mini UART it would be helpful to write down the
limitiations here.

> +	  If unsure, say N.
> +
>  config SERIAL_8250_FSL
>  	bool
>  	depends on SERIAL_8250_CONSOLE
>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: stefan.wahren@i2se.com (Stefan Wahren)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V2 2/2] serial: bcm2835: add driver for bcm2835-aux-uart
Date: Mon, 11 Jan 2016 10:52:32 +0100	[thread overview]
Message-ID: <56937B60.5020200@i2se.com> (raw)
In-Reply-To: <1452344854-2576-3-git-send-email-kernel@martin.sperl.org>

Hi Martin,

Am 09.01.2016 um 14:07 schrieb kernel at martin.sperl.org:
> From: Martin Sperl <kernel@martin.sperl.org>
>
> The bcm2835 SOC contains an auxiliary uart, which is very close
> to the ns16550 with some differences.
>
> The big difference is that the uart HW is not using an internal divider
> of 16 but 8, which results in an effictive baud-rate being twice
> the requested baud-rate.
>
> This driver handles this device correctly and handles the difference in
> the HW divider by scaling up the clock ba a factor of 2.
>
> The approach to write a separate (wrapper) driver instead of using a
> multiplying clock and "ns16550" as compatibility in the device-tree
> has been recommended by Stephen Warren.
>
> Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
> ---
>  drivers/tty/serial/8250/8250_bcm2835aux.c |  143 +++++++++++++++++++++++++++++
>  drivers/tty/serial/8250/Kconfig           |    8 ++
>  drivers/tty/serial/8250/Makefile          |    1 +
>  3 files changed, 152 insertions(+)
>  create mode 100644 drivers/tty/serial/8250/8250_bcm2835aux.c
>
> diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c
> new file mode 100644
> index 0000000..718c357
> --- /dev/null
> +++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
> @@ -0,0 +1,143 @@
> +/*
> + * Serial port driver for BCM2835AUX UART
> + *
> + * Copyright (C) 2016 Martin Sperl <kernel@martin.sperl.org>
> + *
> + * Based on 8250_lpc18xx.c:
> + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include "8250.h"
> +
> +struct bcm2835aux_data {
> +	struct uart_8250_port uart;
> +	struct clk *clk;
> +};
> +
> +static int bcm2835aux_serial_probe(struct platform_device *pdev)
> +{
> +	struct bcm2835aux_data *data;
> +	struct resource *res;
> +	int ret;
> +
> +	/* allocate the custom structure */
> +	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	/* initialize data */
> +	spin_lock_init(&data->uart.port.lock);
> +	data->uart.port.dev = &pdev->dev;
> +	data->uart.port.regshift = 2;
> +	data->uart.port.type = PORT_16550;
> +	data->uart.port.iotype = UPIO_MEM;
> +	data->uart.port.fifosize = 8;

data->uart.capabilities = UART_CAP_FIFO; ?

> +	data->uart.port.flags = UPF_SHARE_IRQ |
> +				UPF_FIXED_PORT |
> +				UPF_FIXED_TYPE |
> +				UPF_SKIP_TEST;
> +
> +	/* get the clock - this also enables the HW */
> +	data->clk = devm_clk_get(&pdev->dev, NULL);
> +	ret = PTR_ERR_OR_ZERO(data->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not get clk: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* get the interrupt */
> +	data->uart.port.irq = platform_get_irq(pdev, 0);
> +	if (data->uart.port.irq < 0) {
> +		dev_err(&pdev->dev, "irq not found - %i",
> +			data->uart.port.irq);
> +		return data->uart.port.irq;
> +	}
> +
> +	/* map the main registers */
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "memory resource not found");
> +		return -EINVAL;
> +	}
> +	data->uart.port.membase = devm_ioremap_resource(&pdev->dev, res);
> +	ret = PTR_ERR_OR_ZERO(data->uart.port.membase);
> +	if (ret)
> +		return ret;
> +
> +	/* Check for a fixed line number */
> +	ret = of_alias_get_id(pdev->dev.of_node, "serial");
> +	if (ret >= 0)
> +		data->uart.port.line = ret;
> +
> +	/* enable the clock as a last step */
> +	ret = clk_prepare_enable(data->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to enable uart clock\n");
> +		return ret;
> +	}
> +
> +	/* the HW-clock divider for bcm2835aux is 8,
> +	 * but 8250 expects a divider of 16,
> +	 * so we have to multiply the actual clock by 2
> +	 * to get identical baudrates.
> +	 */
> +	data->uart.port.uartclk = clk_get_rate(data->clk) * 2;
> +
> +	/* register the port */
> +	ret = serial8250_register_8250_port(&data->uart);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev,
> +			"unable to register 8250 port - %d\n", ret);

This should fit in one line.

> +		goto dis_clk;
> +	}
> +	data->uart.port.line = ret;

This looks wrong because it overwrites the result of of_alias_get_id.
Either
you store it in a new member of bcm2835aux_data or drop the assignment.

> +
> +	platform_set_drvdata(pdev, data);
> +
> +	return 0;
> +
> +dis_clk:
> +	clk_disable_unprepare(data->clk);
> +	return ret;
> +}
> +
> +static int bcm2835aux_serial_remove(struct platform_device *pdev)
> +{
> +	struct bcm2835aux_data *data = platform_get_drvdata(pdev);
> +
> +	serial8250_unregister_port(data->uart.port.line);
> +	clk_disable_unprepare(data->clk);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id bcm2835aux_serial_match[] = {
> +	{ .compatible = "brcm,bcm2835-aux-uart" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, bcm2835aux_serial_match);
> +
> +static struct platform_driver bcm2835aux_serial_driver = {
> +	.driver = {
> +		.name = "bcm2835-aux-uart",
> +		.of_match_table = bcm2835aux_serial_match,
> +	},
> +	.probe  = bcm2835aux_serial_probe,
> +	.remove = bcm2835aux_serial_remove,
> +};
> +module_platform_driver(bcm2835aux_serial_driver);
> +
> +MODULE_DESCRIPTION("BCM2835 auxiliar UART driver");
> +MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 6412f14..105aa19 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -272,6 +272,14 @@ config SERIAL_8250_ACORN
>  	  system, say Y to this option.  The driver can handle 1, 2, or 3 port
>  	  cards.  If unsure, say N.
>  
> +config SERIAL_8250_BCM2835AUX
> +	tristate "BCM2835 auxiliar uart support"

BCM2835 auxiliary mini UART support

> +	depends on ARCH_BCM2835 || COMPILE_TEST
> +	depends on SERIAL_8250 && SERIAL_8250_SHARE_IRQ
> +	help
> +	  support for the BCM2835 auxiliar uart.

auxiliary UART

Since it's a mini UART it would be helpful to write down the
limitiations here.

> +	  If unsure, say N.
> +
>  config SERIAL_8250_FSL
>  	bool
>  	depends on SERIAL_8250_CONSOLE
>

  parent reply	other threads:[~2016-01-11  9:52 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-09 13:07 [PATCH V2 0/2] serial: bcm2835: add bcm2835 auxiliar uart driver kernel-TqfNSX0MhmxHKSADF0wUEw
2016-01-09 13:07 ` kernel at martin.sperl.org
     [not found] ` <1452344854-2576-1-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-09 13:07   ` [PATCH V2 1/2] dt/bindings: serial: bcm2835: add binding documentation for bcm2835-aux-uart kernel-TqfNSX0MhmxHKSADF0wUEw
2016-01-09 13:07     ` kernel at martin.sperl.org
     [not found]     ` <1452344854-2576-2-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-09 20:53       ` Arnd Bergmann
2016-01-09 20:53         ` Arnd Bergmann
2016-01-10 10:49         ` Martin Sperl
2016-01-10 10:49           ` Martin Sperl
     [not found]           ` <175E89CE-581C-48AB-B7FF-6E9A41B033D5-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-11 12:21             ` Arnd Bergmann
2016-01-11 12:21               ` Arnd Bergmann
2016-01-11 13:57               ` Martin Sperl
2016-01-11 13:57                 ` Martin Sperl
     [not found]                 ` <6035A0DD-AD61-48F7-B641-272BB23F3CD8-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-11 14:40                   ` Arnd Bergmann
2016-01-11 14:40                     ` Arnd Bergmann
2016-01-28  6:39                     ` Eric Anholt
2016-01-28  6:39                       ` Eric Anholt
2016-01-09 13:07   ` [PATCH V2 2/2] serial: bcm2835: add driver " kernel-TqfNSX0MhmxHKSADF0wUEw
2016-01-09 13:07     ` kernel at martin.sperl.org
     [not found]     ` <1452344854-2576-3-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-11  9:52       ` Stefan Wahren [this message]
2016-01-11  9:52         ` Stefan Wahren
2016-01-11 15:25       ` Peter Korsgaard
2016-01-11 15:25         ` Peter Korsgaard
2016-01-10 15:05   ` [PATCH V2 0/2] serial: bcm2835: add bcm2835 auxiliar uart driver Stefan Wahren
2016-01-10 15:05     ` Stefan Wahren
     [not found]     ` <1057226922.507844.cb24b396-67be-4b7b-9938-7cb30ef4fe05.open-xchange-7tX72C7vayboQLBSYMtkGA@public.gmane.org>
2016-01-10 15:45       ` Martin Sperl
2016-01-10 15:45         ` Martin Sperl
     [not found]         ` <46FD7886-510C-4F0F-A039-500D5438207B-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-10 21:17           ` Stefan Wahren
2016-01-10 21:17             ` Stefan Wahren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56937B60.5020200@i2se.com \
    --to=stefan.wahren-es4nqchxeme@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org \
    --cc=gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
    --cc=jslaby-IBi9RG/b67k@public.gmane.org \
    --cc=kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org \
    --cc=lee-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.