devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mark Rutland <mark.rutland@arm.com>
To: "H. Nikolaus Schaller" <hns@goldelico.com>
Cc: Jiri Slaby <jslaby@suse.cz>, Arnd Bergmann <arnd@arndb.de>,
	Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Kumar Gala <galak@codeaurora.org>,
	Jonathan Corbet <corbet@lwn.net>,
	Sergei Zviagintsev <sergei@s15v.net>,
	Peter Hurley <peter@hurleysoftware.com>,
	One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>,
	Sebastian Reichel <sre@kernel.org>, NeilBrown <neil@brown.name>,
	Grant Likely <grant.likely@linaro.org>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-serial@vger.kernel.org, Marek Belisko <marek@goldelico.com>,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org
Subject: Re: [PATCH v3 1/3] tty: serial core: provide a method to search uart by phandle
Date: Fri, 16 Oct 2015 19:39:00 +0100	[thread overview]
Message-ID: <20151016183900.GF4039@leverpostej> (raw)
In-Reply-To: <c46694357c903d8791f07e2ec287c684832056a5.1445018913.git.hns@goldelico.com>

On Fri, Oct 16, 2015 at 08:08:33PM +0200, H. Nikolaus Schaller wrote:
> 1. add uart_ports to a search list as soon as they are registered
> 2. provide a function to search an uart_port by phandle. This copies the
>    mechanism how devm_usb_get_phy_by_phandle() works
> 3. add a bindings document how serial slaves should use this feature
> 4. add Documentation how serla slaves work in general

I thought maintainers preferred the child node approach to the phandle
approach, and this series comes with no rationale (nor change log,
despite being 'v3').

I don't understand. What is going on here?

Mark.

> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> ---
>  .../devicetree/bindings/serial/slaves.txt          |  16 +++
>  Documentation/serial/slaves.txt                    |  36 +++++++
>  drivers/tty/serial/serial_core.c                   | 107 +++++++++++++++++++++
>  include/linux/serial_core.h                        |  10 ++
>  4 files changed, 169 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/serial/slaves.txt
>  create mode 100644 Documentation/serial/slaves.txt
> 
> diff --git a/Documentation/devicetree/bindings/serial/slaves.txt b/Documentation/devicetree/bindings/serial/slaves.txt
> new file mode 100644
> index 0000000..353b87f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/slaves.txt
> @@ -0,0 +1,16 @@
> +Device-Tree bindings for UART slave devices
> +
> +A node describing a slave device defines a phandle to reference the UART
> +the device is connected to. In the (unexpected) case of two or more UARTs
> +a list of phandles can be specified.
> +
> +properties:
> +	- uart: (list of) phandle(s) of UART(s) the device is connected to
> +
> +
> +example:
> +
> +	gps {
> +		compatible = "wi2wi,w2sg0004";
> +		uart = <&uart1>;
> +	};
> diff --git a/Documentation/serial/slaves.txt b/Documentation/serial/slaves.txt
> new file mode 100644
> index 0000000..6f8d44d
> --- /dev/null
> +++ b/Documentation/serial/slaves.txt
> @@ -0,0 +1,36 @@
> +UART slave device support
> +
> +A remote device connected to a RS232 interface is usually power controlled by the DTR line.
> +The DTR line is managed automatically by the UART driver for open() and close() syscalls
> +and on demand by tcsetattr().
> +
> +With embedded devices, the serial peripheral might be directly and always connected to the UART
> +and there might be no physical DTR line involved. Power control (on/off) has to be done by some
> +chip specific device driver (which we call "UART slave") through some mechanisms (I2C, GPIOs etc.)
> +not related to the serial interface. Some devices do not explicitly tell their power state except
> +by sending or not sending data to the UART. In such a case the device driver must be able to monitor
> +data activity. The role of the device driver is to encapsulate such power control in a single place.
> +
> +This patch series allows to support such drivers by providing:
> +* a mechanism that a slave driver can identify the UART instance it is connected to
> +* a mechanism that UART slave drivers can register to be notified
> +* notfications for DTR (and other modem control) state changes
> +* notifications that the UART has received some data from the UART
> +
> +A slave device simply adds a phandle reference to the UART it is connected to, e.g.
> +
> +	gps {
> +		compatible = "wi2wi,w2sg0004";
> +		uart = <&uart1>;
> +	};
> +
> +The slave driver calls devm_serial_get_uart_by_phandle() to identify the uart driver.
> +This API follows the concept of devm_usb_get_phy_by_phandle().
> +
> +A slave device driver registers itself with serial_register_slave() to receive notifications.
> +Notification handler callbacks can be registered by serial_register_mctrl_notification() and
> +serial_register_rx_notification(). If an UART has registered a NULL slave or a NULL handler,
> +no notifications are sent.
> +
> +RX notification handlers can define a ktermios during setup and the handler function can modify
> +or decide to throw away each character that is passed upwards.
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index 603d2cc..9caa33e 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -38,6 +38,36 @@
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
>  
> +static LIST_HEAD(uart_list);
> +static DEFINE_SPINLOCK(uart_lock);
> +
> +/* same concept as __of_usb_find_phy */
> +static struct uart_port *__of_serial_find_uart(struct device_node *node)
> +{
> +	struct uart_port  *uart;
> +
> +	if (!of_device_is_available(node))
> +		return ERR_PTR(-ENODEV);
> +
> +	list_for_each_entry(uart, &uart_list, head) {
> +		if (node != uart->dev->of_node)
> +			continue;
> +
> +		return uart;
> +	}
> +
> +	return ERR_PTR(-EPROBE_DEFER);
> +}
> +
> +static void devm_serial_uart_release(struct device *dev, void *res)
> +{
> +	struct uart_port *uart = *(struct uart_port **)res;
> +
> +	/* FIXME: I don't understand the serial subsystem well enough
> +	 * to know if we should call serial_put_uart(uart); here
> +	 */
> +}
> +
>  /*
>   * This is used to lock changes in serial line configuration.
>   */
> @@ -64,6 +94,79 @@ static int uart_dcd_enabled(struct uart_port *uport)
>  	return !!(uport->status & UPSTAT_DCD_ENABLE);
>  }
>  
> +/**
> + * devm_serial_get_uart_by_phandle - find the uart by phandle
> + * @dev - device that requests this uart
> + * @phandle - name of the property holding the uart phandle value
> + * @index - the index of the uart
> + *
> + * Returns the uart_port associated with the given phandle value,
> + * after getting a refcount to it, -ENODEV if there is no such uart or
> + * -EPROBE_DEFER if there is a phandle to the uart, but the device is
> + * not yet loaded. While at that, it also associates the device with
> + * the uart using devres. On driver detach, release function is invoked
> + * on the devres data, then, devres data is freed.
> + *
> + * For use by tty host and peripheral drivers.
> + */
> +
> +/* same concept as devm_usb_get_phy_by_phandle() */
> +
> +struct uart_port *devm_serial_get_uart_by_phandle(struct device *dev,
> +		const char *phandle, u8 index)
> +{
> +	struct uart_port  *uart = ERR_PTR(-ENOMEM), **ptr;
> +	unsigned long   flags;
> +	struct device_node *node;
> +
> +	if (!dev->of_node) {
> +		dev_err(dev, "device does not have a device node entry\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	node = of_parse_phandle(dev->of_node, phandle, index);
> +	if (!node) {
> +		dev_err(dev, "failed to get %s phandle in %s node\n", phandle,
> +			dev->of_node->full_name);
> +		return ERR_PTR(-ENODEV);
> +	}
> +
> +	ptr = devres_alloc(devm_serial_uart_release, sizeof(*ptr), GFP_KERNEL);
> +	if (!ptr) {
> +		dev_err(dev, "failed to allocate memory for devres\n");
> +		goto err0;
> +	}
> +
> +	spin_lock_irqsave(&uart_lock, flags);
> +
> +	uart = __of_serial_find_uart(node);
> +	if (IS_ERR(uart)) {
> +		devres_free(ptr);
> +		goto err1;
> +	}
> +
> +	if (!try_module_get(uart->dev->driver->owner)) {
> +		uart = ERR_PTR(-ENODEV);
> +		devres_free(ptr);
> +		goto err1;
> +	}
> +
> +	*ptr = uart;
> +	devres_add(dev, ptr);
> +
> +	get_device(uart->dev);
> +
> +err1:
> +	spin_unlock_irqrestore(&uart_lock, flags);
> +
> +err0:
> +	of_node_put(node);
> +
> +	return uart;
> +}
> +EXPORT_SYMBOL_GPL(devm_serial_get_uart_by_phandle);
> +
> +
>  /*
>   * This routine is used by the interrupt handler to schedule processing in
>   * the software interrupt portion of the driver.
> @@ -2733,6 +2836,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>  	 */
>  	uport->flags &= ~UPF_DEAD;
>  
> +	list_add_tail(&uport->head, &uart_list);
> +
>   out:
>  	mutex_unlock(&port->mutex);
>  	mutex_unlock(&port_mutex);
> @@ -2764,6 +2869,8 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
>  
>  	mutex_lock(&port_mutex);
>  
> +	list_del(&uport->head);
> +
>  	/*
>  	 * Mark the port "dead" - this prevents any opens from
>  	 * succeeding while we shut down the port.
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 297d4fa..d7a2e15 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -247,6 +247,7 @@ struct uart_port {
>  	const struct attribute_group **tty_groups;	/* all attributes (serial core use only) */
>  	struct serial_rs485     rs485;
>  	void			*private_data;		/* generic platform data pointer */
> +	struct list_head	head;			/* uarts list (lookup by phandle) */
>  };
>  
>  static inline int serial_port_in(struct uart_port *up, int offset)
> @@ -475,4 +476,13 @@ static inline int uart_handle_break(struct uart_port *port)
>  					 (cflag) & CRTSCTS || \
>  					 !((cflag) & CLOCAL))
>  
> +/*
> + * Helper functions for UART slave drivers
> + */
> +
> +/* find UART by phandle (e.g. with 'uart = <&uart2>;' then call as
> + * devm_serial_get_uart_by_phandle(dev, "uart", 0);
> + */
> +extern struct uart_port *devm_serial_get_uart_by_phandle(struct device *dev,
> +		const char *phandle, u8 index);
>  #endif /* LINUX_SERIAL_CORE_H */
> -- 
> 2.5.1
> 

  reply	other threads:[~2015-10-16 18:39 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-16 18:08 [PATCH v3 0/3] UART slave device support (goldelico version) H. Nikolaus Schaller
2015-10-16 18:08 ` [PATCH v3 1/3] tty: serial core: provide a method to search uart by phandle H. Nikolaus Schaller
2015-10-16 18:39   ` Mark Rutland [this message]
2015-10-16 19:24     ` H. Nikolaus Schaller
2015-10-16 18:47   ` kbuild test robot
     [not found]   ` <c46694357c903d8791f07e2ec287c684832056a5.1445018913.git.hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>
2015-10-16 19:05     ` Arnd Bergmann
2015-10-16 19:29   ` kbuild test robot
2015-10-16 18:08 ` [PATCH v3 2/3] tty: serial_core: add hooks for uart slave drivers H. Nikolaus Schaller
2015-10-16 18:08 ` [PATCH v3 3/3] misc: Add w2sg0004 gps receiver driver H. Nikolaus Schaller
     [not found]   ` <c53ab7a3ca68f8b9f802c1ea799d72e1cb04a1eb.1445018913.git.hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>
2015-10-16 18:15     ` H. Nikolaus Schaller
2015-10-16 19:06   ` Arnd Bergmann
2015-10-16 19:27     ` H. Nikolaus Schaller
2015-10-16 19:38       ` Arnd Bergmann
2015-10-16 20:07         ` H. Nikolaus Schaller
2015-10-16 23:45   ` kbuild test robot
2015-10-16 19:11 ` [PATCH v3 0/3] UART slave device support (goldelico version) H. Nikolaus Schaller

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=20151016183900.GF4039@leverpostej \
    --to=mark.rutland@arm.com \
    --cc=arnd@arndb.de \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=gnomes@lxorguk.ukuu.org.uk \
    --cc=grant.likely@linaro.org \
    --cc=hns@goldelico.com \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=jslaby@suse.cz \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=marek@goldelico.com \
    --cc=neil@brown.name \
    --cc=pawel.moll@arm.com \
    --cc=peter@hurleysoftware.com \
    --cc=robh+dt@kernel.org \
    --cc=sergei@s15v.net \
    --cc=sre@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).