diff mbox

[PATCHv1,1/6] HSI: add Device Tree support for HSI clients

Message ID 1393199401-27197-2-git-send-email-sre@debian.org (mailing list archive)
State New, archived
Headers show

Commit Message

Sebastian Reichel Feb. 23, 2014, 11:49 p.m. UTC
Add new method hsi_add_clients_from_dt, which can be used
to initialize HSI clients from a device tree node.

The patch also documents the DT binding for trivial HSI
clients.

Signed-off-by: Sebastian Reichel <sre@debian.org>
---
 .../devicetree/bindings/hsi/trivial-devices.txt    | 36 +++++++++++
 drivers/hsi/hsi.c                                  | 70 +++++++++++++++++++++-
 include/dt-bindings/hsi/hsi.h                      | 17 ++++++
 include/linux/hsi/hsi.h                            |  2 +
 4 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/hsi/trivial-devices.txt
 create mode 100644 include/dt-bindings/hsi/hsi.h

Comments

Mark Rutland Feb. 24, 2014, 3:09 p.m. UTC | #1
On Sun, Feb 23, 2014 at 11:49:56PM +0000, Sebastian Reichel wrote:
> Add new method hsi_add_clients_from_dt, which can be used
> to initialize HSI clients from a device tree node.
> 
> The patch also documents the DT binding for trivial HSI
> clients.
> 
> Signed-off-by: Sebastian Reichel <sre@debian.org>
> ---
>  .../devicetree/bindings/hsi/trivial-devices.txt    | 36 +++++++++++
>  drivers/hsi/hsi.c                                  | 70 +++++++++++++++++++++-
>  include/dt-bindings/hsi/hsi.h                      | 17 ++++++
>  include/linux/hsi/hsi.h                            |  2 +
>  4 files changed, 124 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/hsi/trivial-devices.txt
>  create mode 100644 include/dt-bindings/hsi/hsi.h

It would be nice if we had a general HSI binding document that explains
what HSI is and how HSI bus devices and clients are expected too look.

Does HSI have an addressing scheme, or does each port have a single
device?

> 
> diff --git a/Documentation/devicetree/bindings/hsi/trivial-devices.txt b/Documentation/devicetree/bindings/hsi/trivial-devices.txt
> new file mode 100644
> index 0000000..1ace14a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hsi/trivial-devices.txt
> @@ -0,0 +1,36 @@
> +This is a list of trivial hsi client devices that have simple
> +device tree bindings, consisting only of a compatible field
> +and the optional hsi configuration.
> +
> +If a device needs more specific bindings, such as properties to
> +describe some aspect of it, there needs to be a specific binding
> +document for it just like any other devices.

Might this make more sense as a hsi-clients binding doc? I assume these
properties could be applied to non-trivial devices?

> +
> +Optional HSI configuration properties:
> +
> +- hsi,mode		Bit transmission mode (STREAM or FRAME)
> +			The first value is used for RX and the second one for
> +			TX configuration. If only one value is provided it will
> +			be used for RX and TX.
> +			The assignments may be found in header file
> +			<dt-bindings/hsi/hsi.h>.

Why not have hsi,rx-mode and hsi,tx-mode? I'll certainly get confused as
to which cell is tx and which is rx with the current binding.

Having separate tx-* and rx-* versions of the remaining properties would
be good too.

I note that the defines are called HSI_MODE_STREAM and HSI_MODE_FRAME,
not STREAM and FRAME as the binding document implies. Please refer to
exact names.

It may make more sense to use a string here and for the other
properties. They're easier for humans to read, and they survive
decompilation (so you get _much_ better error messages).

> +- hsi,channels		Number of channels to use [1..16]
> +			The first value is used for RX and the second one for
> +			TX configuration. If only one value is provided it will
> +			be used for RX and TX.
> +- hsi,speed		Max bit transmission speed (Kbit/s)
> +			The first value is used for RX and the second one for
> +			TX configuration. If only one value is provided it will
> +			be used for RX and TX.
> +- hsi,flow		RX flow type (SYNCHRONIZED or PIPELINE)
> +			The assignments may be found in header file
> +			<dt-bindings/hsi/hsi.h>.
> +- hsi,arb_mode		Arbitration mode for TX frame (Round robin, priority)
> +			The assignments may be found in header file
> +			<dt-bindings/hsi/hsi.h>.

s/_/-/ in property names please.

> +
> +This is the list of trivial client devices:
> +
> +Compatible		Description
> +==========		=============
> +hsi-char		HSI character device

What exactly is a HSI character device?

This seems more like a Linux abstraction than a real class of device.

Cheers,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring Feb. 25, 2014, 12:47 a.m. UTC | #2
On Sun, Feb 23, 2014 at 5:49 PM, Sebastian Reichel <sre@debian.org> wrote:
> Add new method hsi_add_clients_from_dt, which can be used
> to initialize HSI clients from a device tree node.
>
> The patch also documents the DT binding for trivial HSI
> clients.
>
> Signed-off-by: Sebastian Reichel <sre@debian.org>
> ---
>  .../devicetree/bindings/hsi/trivial-devices.txt    | 36 +++++++++++
>  drivers/hsi/hsi.c                                  | 70 +++++++++++++++++++++-
>  include/dt-bindings/hsi/hsi.h                      | 17 ++++++
>  include/linux/hsi/hsi.h                            |  2 +
>  4 files changed, 124 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/hsi/trivial-devices.txt
>  create mode 100644 include/dt-bindings/hsi/hsi.h
>
> diff --git a/Documentation/devicetree/bindings/hsi/trivial-devices.txt b/Documentation/devicetree/bindings/hsi/trivial-devices.txt
> new file mode 100644
> index 0000000..1ace14a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hsi/trivial-devices.txt
> @@ -0,0 +1,36 @@
> +This is a list of trivial hsi client devices that have simple
> +device tree bindings, consisting only of a compatible field
> +and the optional hsi configuration.
> +
> +If a device needs more specific bindings, such as properties to
> +describe some aspect of it, there needs to be a specific binding
> +document for it just like any other devices.
> +
> +Optional HSI configuration properties:
> +
> +- hsi,mode             Bit transmission mode (STREAM or FRAME)

hsi is not a vendor prefix, so all these properties should be hsi-*.

> +                       The first value is used for RX and the second one for
> +                       TX configuration. If only one value is provided it will
> +                       be used for RX and TX.
> +                       The assignments may be found in header file
> +                       <dt-bindings/hsi/hsi.h>.
> +- hsi,channels         Number of channels to use [1..16]
> +                       The first value is used for RX and the second one for
> +                       TX configuration. If only one value is provided it will
> +                       be used for RX and TX.
> +- hsi,speed            Max bit transmission speed (Kbit/s)

Include the units in the prop name: hsi-speed-kbps

> +                       The first value is used for RX and the second one for
> +                       TX configuration. If only one value is provided it will
> +                       be used for RX and TX.
> +- hsi,flow             RX flow type (SYNCHRONIZED or PIPELINE)
> +                       The assignments may be found in header file
> +                       <dt-bindings/hsi/hsi.h>.
> +- hsi,arb_mode         Arbitration mode for TX frame (Round robin, priority)
> +                       The assignments may be found in header file
> +                       <dt-bindings/hsi/hsi.h>.
> +
> +This is the list of trivial client devices:
> +
> +Compatible             Description
> +==========             =============
> +hsi-char               HSI character device


I've gotten this far and still have no idea what HSI is.

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/hsi/trivial-devices.txt b/Documentation/devicetree/bindings/hsi/trivial-devices.txt
new file mode 100644
index 0000000..1ace14a
--- /dev/null
+++ b/Documentation/devicetree/bindings/hsi/trivial-devices.txt
@@ -0,0 +1,36 @@ 
+This is a list of trivial hsi client devices that have simple
+device tree bindings, consisting only of a compatible field
+and the optional hsi configuration.
+
+If a device needs more specific bindings, such as properties to
+describe some aspect of it, there needs to be a specific binding
+document for it just like any other devices.
+
+Optional HSI configuration properties:
+
+- hsi,mode		Bit transmission mode (STREAM or FRAME)
+			The first value is used for RX and the second one for
+			TX configuration. If only one value is provided it will
+			be used for RX and TX.
+			The assignments may be found in header file
+			<dt-bindings/hsi/hsi.h>.
+- hsi,channels		Number of channels to use [1..16]
+			The first value is used for RX and the second one for
+			TX configuration. If only one value is provided it will
+			be used for RX and TX.
+- hsi,speed		Max bit transmission speed (Kbit/s)
+			The first value is used for RX and the second one for
+			TX configuration. If only one value is provided it will
+			be used for RX and TX.
+- hsi,flow		RX flow type (SYNCHRONIZED or PIPELINE)
+			The assignments may be found in header file
+			<dt-bindings/hsi/hsi.h>.
+- hsi,arb_mode		Arbitration mode for TX frame (Round robin, priority)
+			The assignments may be found in header file
+			<dt-bindings/hsi/hsi.h>.
+
+This is the list of trivial client devices:
+
+Compatible		Description
+==========		=============
+hsi-char		HSI character device
diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c
index 749f7b5..8bbc0f1 100644
--- a/drivers/hsi/hsi.c
+++ b/drivers/hsi/hsi.c
@@ -26,6 +26,8 @@ 
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include "hsi_core.h"
 
 static ssize_t modalias_show(struct device *dev,
@@ -50,7 +52,10 @@  static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 
 static int hsi_bus_match(struct device *dev, struct device_driver *driver)
 {
-	return strcmp(dev_name(dev), driver->name) == 0;
+	if (dev->of_node != NULL)
+		return of_driver_match_device(dev, driver);
+	else
+		return strcmp(dev_name(dev), driver->name) == 0;
 }
 
 static struct bus_type hsi_bus_type = {
@@ -75,6 +80,7 @@  static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)
 	cl->tx_cfg = info->tx_cfg;
 	cl->rx_cfg = info->rx_cfg;
 	cl->device.bus = &hsi_bus_type;
+
 	cl->device.parent = &port->device;
 	cl->device.release = hsi_client_release;
 	dev_set_name(&cl->device, "%s", info->name);
@@ -101,6 +107,68 @@  static void hsi_scan_board_info(struct hsi_controller *hsi)
 		}
 }
 
+static void hsi_of_get_client_cfg_property(struct device_node *client,
+				char *name, unsigned int *rx, unsigned int *tx)
+{
+	int err;
+
+	err = of_property_read_u32_index(client, name, 0, rx);
+	if (err)
+		*rx = 0;
+
+	err = of_property_read_u32_index(client, name, 1, tx);
+	if (err)
+		*tx = *rx;
+}
+
+static void hsi_add_client_from_dt(struct hsi_port *port,
+						struct device_node *client)
+{
+	struct hsi_client *cl;
+	const char *name;
+	int err;
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	if (!cl)
+		return;
+
+	err = of_property_read_string(client, "compatible", &name);
+	if (!err) {
+		dev_set_name(&cl->device, "%s", name);
+	} else {
+		kfree(cl);
+		return;
+	}
+
+	hsi_of_get_client_cfg_property(client, "hsi,mode", &cl->rx_cfg.mode,
+							&cl->tx_cfg.mode);
+	hsi_of_get_client_cfg_property(client, "hsi,speed", &cl->rx_cfg.speed,
+							&cl->tx_cfg.speed);
+	hsi_of_get_client_cfg_property(client, "hsi,channels",
+				&cl->rx_cfg.channels, &cl->tx_cfg.channels);
+	of_property_read_u32(client, "hsi,flow", &cl->rx_cfg.flow);
+	of_property_read_u32(client, "hsi,arb_mode", &cl->tx_cfg.arb_mode);
+
+	cl->device.bus = &hsi_bus_type;
+	cl->device.parent = &port->device;
+	cl->device.release = hsi_client_release;
+	cl->device.of_node = client;
+
+	if (device_register(&cl->device) < 0) {
+		pr_err("hsi: failed to register client: %s\n", name);
+		put_device(&cl->device);
+	}
+}
+
+void hsi_add_clients_from_dt(struct hsi_port *port, struct device_node *clients)
+{
+	struct device_node *child;
+
+	for_each_available_child_of_node(clients, child)
+		hsi_add_client_from_dt(port, child);
+}
+EXPORT_SYMBOL_GPL(hsi_add_clients_from_dt);
+
 static int hsi_remove_client(struct device *dev, void *data __maybe_unused)
 {
 	device_unregister(dev);
diff --git a/include/dt-bindings/hsi/hsi.h b/include/dt-bindings/hsi/hsi.h
new file mode 100644
index 0000000..2d6b181
--- /dev/null
+++ b/include/dt-bindings/hsi/hsi.h
@@ -0,0 +1,17 @@ 
+/*
+ * This header provides constants for hsi client bindings.
+ */
+
+#ifndef _DT_BINDINGS_HSI_H
+#define _DT_BINDINGS_HSI_H
+
+#define HSI_MODE_STREAM 1
+#define HSI_MODE_FRAME 2
+
+#define HSI_FLOW_SYNC 0
+#define HSI_FLOW_PIPE 1
+
+#define HSI_ARB_RR 0
+#define HSI_ARB_PRIO 1
+
+#endif /* _DT_BINDINGS_HSI_H */
diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h
index 0dca785..fb07339 100644
--- a/include/linux/hsi/hsi.h
+++ b/include/linux/hsi/hsi.h
@@ -282,6 +282,8 @@  struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags);
 void hsi_put_controller(struct hsi_controller *hsi);
 int hsi_register_controller(struct hsi_controller *hsi);
 void hsi_unregister_controller(struct hsi_controller *hsi);
+void hsi_add_clients_from_dt(struct hsi_port *port,
+						struct device_node *clients);
 
 static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi,
 								void *data)