All of lore.kernel.org
 help / color / mirror / Atom feed
From: marek.behun@nic.cz (Marek Behún)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 2/7] drivers: mfd: Add support for Moxtet bus
Date: Wed,  8 Aug 2018 17:27:01 +0200	[thread overview]
Message-ID: <20180808152706.21727-3-marek.behun@nic.cz> (raw)
In-Reply-To: <20180808152706.21727-1-marek.behun@nic.cz>

On the Turris Mox router there can be connected different modules to
the main CPU board, currently a module with a SFP cage, a module with
MiniPCIe connector, a 4-port switch module and a 8-port switch module,
for example:
  [CPU]-[PCIe]-[8-port switch]-[8-port switch]-[SFP]

Each of this modules has an input and output shift register, and these
are connected via SPI to CPU board.

Via this SPI connection we are able to discover which modules are
connected and we can also read/write some configuration to the modules.
Fromi/to each module 8 bits can be read (of which lower 4 bits identify
the module) and written.

For example from the module with a SFP cage we can read the LOS,
TX-FAULT and MOD-DEF0 signals, while we can write TX-DISABLE and
RATE-SELECT signals.

Other modules may support something else.

This driver creates a new bus type, called "moxtet". For each Mox module
it finds via SPI, it creates a new device on the moxtet bus so that
drivers can be written for them, for example a gpio driver for the
module with a SFP cage.

The topology of how Mox modules are connected can then be read by
listing /sys/bus/moxtet/devices.

Signed-off-by: Marek Behun <marek.behun@nic.cz>

 create mode 100644 Documentation/devicetree/bindings/mfd/moxtet.txt
 create mode 100644 drivers/mfd/moxtet.c
 create mode 100644 include/linux/mfd/moxtet.h

diff --git a/Documentation/devicetree/bindings/mfd/moxtet.txt b/Documentation/devicetree/bindings/mfd/moxtet.txt
new file mode 100644
index 000000000000..02b96fbd5ddd
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/moxtet.txt
@@ -0,0 +1,36 @@
+Turris Mox module configuration bus (over SPI)
+
+Required properties:
+ - compatible		: Should be "cznic,moxtet".
+ - #address-cells	: Has to be 1
+ - #size-cells		: Has to be 0
+For other required and optional properties of SPI slave
+nodes please refer to ../spi/spi-bus.txt.
+
+Required properties of subnodes:
+ - reg			: Should be position on the Moxtet bus
+ - moxtet,id		: Should be ID of the Moxtet device connected
+
+The driver finds the devices connected to the bus by itself, but it may be
+needed to reference some of them from other parts of the device tree. In that
+case the devices can be defined as subnodes of the moxtet node.
+
+Example:
+
+	moxtet at 1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "cznic,moxtet";
+		reg = <1>;
+		spi-max-frequency = <1000000>;
+		spi-cpol;
+		spi-cpha;
+
+		moxtet_sfp: moxtet-sfp at 0 {
+			compatible = "cznic,moxtet-sfp";
+			gpio-controller;
+			#gpio-cells;
+			reg = <0>;
+			moxtet,id = <1>;
+		}
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 7cebd5bba8a8..27ca12e8309a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1378,6 +1378,13 @@ F:	drivers/clocksource/timer-prima2.c
 F:	drivers/clocksource/timer-atlas7.c
 N:	[^a-z]sirf
 
+ARM/CZ.NIC TURRIS MOX SUPPORT
+M:	Marek Behun <marek.behun@nic.cz>
+W:	http://mox.turris.cz
+S:	Maintained
+F:	include/mfd/moxtet.h
+F:	drivers/mfd/moxtet.c
+
 ARM/EBSA110 MACHINE SUPPORT
 M:	Russell King <linux@armlinux.org.uk>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..395d8b15f8a8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -784,6 +784,16 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_MOXTET
+	tristate "CZ.NIC Turris Mox module configuration bus"
+	depends on SPI_MASTER && OF
+	help
+	  Say yes here to add support for the module configuration bus found
+	  on CZ.NIC's Turris Mox. This is needed for the ability to read
+	  in what order the modules are connected and to get/set some of
+	  their settings. For example the GPIOs on Mox SFP module are
+	  configured through this bus.
+
 config MFD_MT6397
 	tristate "MediaTek MT6397 PMIC Support"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e9fd20dba18d..1401863e27b1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -147,6 +147,7 @@ max8925-objs			:= max8925-core.o max8925-i2c.o
 obj-$(CONFIG_MFD_MAX8925)	+= max8925.o
 obj-$(CONFIG_MFD_MAX8997)	+= max8997.o max8997-irq.o
 obj-$(CONFIG_MFD_MAX8998)	+= max8998.o max8998-irq.o
+obj-$(CONFIG_MFD_MOXTET)	+= moxtet.o
 
 pcf50633-objs			:= pcf50633-core.o pcf50633-irq.o
 obj-$(CONFIG_MFD_PCF50633)	+= pcf50633.o
diff --git a/drivers/mfd/moxtet.c b/drivers/mfd/moxtet.c
new file mode 100644
index 000000000000..62b36308d51a
--- /dev/null
+++ b/drivers/mfd/moxtet.c
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Turris Mox module configuration bus driver
+ *
+ * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/moxtet.h>
+
+static ssize_t
+module_id_show(struct device *dev, struct device_attribute *a, char *buf)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+
+	return sprintf(buf, "0x%x\n", mdev->id);
+}
+static DEVICE_ATTR_RO(module_id);
+
+static ssize_t
+module_name_show(struct device *dev, struct device_attribute *a, char *buf)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+
+	return sprintf(buf, "%s\n", turris_mox_module_name(mdev->id));
+}
+static DEVICE_ATTR_RO(module_name);
+
+static ssize_t
+input_value_show(struct device *dev, struct device_attribute *a, char *buf)
+{
+	int ret;
+
+	ret = moxtet_device_read(dev);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "0x%x\n", ret);
+}
+static DEVICE_ATTR_RO(input_value);
+
+static ssize_t
+output_value_show(struct device *dev, struct device_attribute *a, char *buf)
+{
+	int ret;
+
+	ret = moxtet_device_written(dev);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "0x%x\n", ret);
+}
+
+static ssize_t
+output_value_store(struct device *dev, struct device_attribute *a,
+		   const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val > 0xff)
+		return -ERANGE;
+
+	ret = moxtet_device_write(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_RW(output_value);
+
+static struct attribute *moxtet_dev_attrs[] = {
+	&dev_attr_module_id.attr,
+	&dev_attr_module_name.attr,
+	&dev_attr_input_value.attr,
+	&dev_attr_output_value.attr,
+	NULL,
+};
+
+static const struct attribute_group moxtet_dev_group = {
+	.attrs = moxtet_dev_attrs,
+};
+
+static const struct attribute_group *moxtet_dev_groups[] = {
+	&moxtet_dev_group,
+	NULL,
+};
+
+static int moxtet_match(struct device *dev, struct device_driver *drv)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+	struct moxtet_driver *tdrv = to_moxtet_driver(drv);
+	const enum turris_mox_module_id *t;
+
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	for (t = tdrv->id_table; *t; ++t)
+		if (*t == mdev->id)
+			return 1;
+
+	return 0;
+}
+
+struct bus_type moxtet_bus_type = {
+	.name		= "moxtet",
+	.dev_groups	= moxtet_dev_groups,
+	.match		= moxtet_match,
+};
+EXPORT_SYMBOL_GPL(moxtet_bus_type);
+
+int __moxtet_register_driver(struct module *owner,
+			     struct moxtet_driver *mdrv)
+{
+	mdrv->driver.owner = owner;
+	mdrv->driver.bus = &moxtet_bus_type;
+	return driver_register(&mdrv->driver);
+}
+EXPORT_SYMBOL_GPL(__moxtet_register_driver);
+
+static int moxtet_dev_check(struct device *dev, void *data)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+	struct moxtet_device *new_dev = data;
+
+	if (mdev->moxtet == new_dev->moxtet && mdev->id == new_dev->id &&
+	    mdev->idx == new_dev->idx)
+		return -EBUSY;
+	return 0;
+}
+
+static void moxtet_dev_release(struct device *dev)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+
+	put_device(mdev->moxtet->dev);
+	kfree(mdev);
+}
+
+static struct moxtet_device *
+moxtet_alloc_device(struct moxtet *moxtet)
+{
+	struct moxtet_device *dev;
+
+	if (!get_device(moxtet->dev))
+		return NULL;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		put_device(moxtet->dev);
+		return NULL;
+	}
+
+	dev->moxtet = moxtet;
+	dev->dev.parent = moxtet->dev;
+	dev->dev.bus = &moxtet_bus_type;
+	dev->dev.release = moxtet_dev_release;
+
+	device_initialize(&dev->dev);
+
+	return dev;
+}
+
+static int moxtet_add_device(struct moxtet_device *dev)
+{
+	static DEFINE_MUTEX(add_mutex);
+	int ret;
+
+	if (dev->idx >= TURRIS_MOX_MAX_MODULES || dev->id > 0xf)
+		return -EINVAL;
+
+	dev_set_name(&dev->dev, "moxtet-%s.%u",
+		     turris_mox_module_name(dev->id), dev->idx);
+
+	mutex_lock(&add_mutex);
+
+	ret = bus_for_each_dev(&moxtet_bus_type, NULL, dev,
+			       moxtet_dev_check);
+	if (ret)
+		goto done;
+
+	ret = device_add(&dev->dev);
+	if (ret < 0)
+		dev_err(dev->moxtet->dev, "can't add %s, status %d\n",
+			dev_name(dev->moxtet->dev), ret);
+
+done:
+	mutex_unlock(&add_mutex);
+	return ret;
+}
+
+static int __unregister(struct device *dev, void *null)
+{
+	if (dev->of_node) {
+		of_node_clear_flag(dev->of_node, OF_POPULATED);
+		of_node_put(dev->of_node);
+	}
+
+	device_unregister(dev);
+
+	return 0;
+}
+
+static struct moxtet_device *
+of_register_moxtet_device(struct moxtet *moxtet, struct device_node *nc)
+{
+	struct moxtet_device *dev;
+	u32 val;
+	int ret;
+
+	dev = moxtet_alloc_device(moxtet);
+	if (!dev) {
+		dev_err(moxtet->dev,
+			"Moxtet device alloc error for %pOF\n", nc);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ret = of_property_read_u32(nc, "reg", &val);
+	if (ret || val >= TURRIS_MOX_MAX_MODULES) {
+		dev_err(moxtet->dev, "%pOF has no valid 'reg' property (%d)\n",
+			nc, ret);
+		goto err_put;
+	}
+	dev->idx = val;
+
+	ret = of_property_read_u32(nc, "moxtet,id", &val);
+	if (ret || val > 0xf) {
+		dev_err(moxtet->dev,
+			"%pOF has no valid 'moxtet,id' property (%d)\n", nc,
+			ret);
+		goto err_put;
+	}
+	dev->id = val;
+
+	if (moxtet->modules[dev->idx] != dev->id) {
+		dev_err(moxtet->dev,
+			"%pOF requested Moxtet device ID 0x%x, 0x%x found\n",
+			nc, dev->id, moxtet->modules[dev->idx]);
+		goto err_put;
+	}
+
+	of_node_get(nc);
+	dev->dev.of_node = nc;
+
+	ret = moxtet_add_device(dev);
+	if (ret) {
+		dev_err(moxtet->dev,
+			"Moxtet device register error for %pOF\n", nc);
+		of_node_put(nc);
+		goto err_put;
+	}
+
+	return dev;
+
+err_put:
+	put_device(&dev->dev);
+	return ERR_PTR(ret);
+}
+
+static void of_register_moxtet_devices(struct moxtet *moxtet)
+{
+	struct moxtet_device *dev;
+	struct device_node *nc;
+
+	if (!moxtet->dev->of_node)
+		return;
+
+	for_each_available_child_of_node(moxtet->dev->of_node, nc) {
+		if (of_node_test_and_set_flag(nc, OF_POPULATED))
+			continue;
+		dev = of_register_moxtet_device(moxtet, nc);
+		if (IS_ERR(dev)) {
+			dev_warn(moxtet->dev,
+				 "Failed to create Moxtet device for %pOF\n",
+				 nc);
+			of_node_clear_flag(nc, OF_POPULATED);
+		}
+	}
+}
+
+static void
+moxtet_register_devices_from_topology(struct moxtet *moxtet)
+{
+	struct moxtet_device *dev;
+	int i, ret;
+
+	for (i = 0; i < moxtet->count; ++i) {
+		dev = moxtet_alloc_device(moxtet);
+		if (!dev) {
+			dev_err(moxtet->dev, "Moxtet device %u alloc error\n",
+				i, moxtet->modules[i]);
+			continue;
+		}
+
+		dev->idx = i;
+		dev->id = moxtet->modules[i];
+
+		ret = moxtet_add_device(dev);
+		if (ret && ret != -EBUSY) {
+			dev_err(moxtet->dev,
+				"Moxtet device %u register error: %i\n", i,
+				moxtet->modules[i], ret);
+		}
+	}
+}
+
+static int moxtet_find_topology(struct moxtet *moxtet)
+{
+	u8 buf[TURRIS_MOX_MAX_MODULES];
+	int i, ret;
+
+	ret = spi_read(to_spi_device(moxtet->dev), buf, TURRIS_MOX_MAX_MODULES);
+	if (ret < 0)
+		return ret;
+
+	if (buf[0] == TURRIS_MOX_CPU_ID_EMMC) {
+		dev_info(moxtet->dev, "Found eMMC Turris Mox CPU module\n");
+	} else if (buf[0] == TURRIS_MOX_CPU_ID_SD) {
+		dev_info(moxtet->dev, "Found SD Turris Mox CPU module\n");
+	} else {
+		dev_err(moxtet->dev, "Invalid Turris Mox CPU module 0x%02x\n",
+			buf[0]);
+		return -ENODEV;
+	}
+
+	moxtet->count = 0;
+
+	for (i = 1; i < TURRIS_MOX_MAX_MODULES; ++i) {
+		int module_id;
+
+		if (buf[i] == 0xff)
+			break;
+
+		module_id = buf[i] & 0xf;
+
+		moxtet->modules[i-1] = module_id;
+		++moxtet->count;
+
+		switch (module_id) {
+		case TURRIS_MOX_MODULE_SFP:
+			dev_info(moxtet->dev, "SFP module found\n");
+			break;
+		case TURRIS_MOX_MODULE_PCI:
+			dev_info(moxtet->dev, "PCIe module found\n");
+			break;
+		case TURRIS_MOX_MODULE_TOPAZ:
+			dev_info(moxtet->dev, "Topaz Switch module found\n");
+			break;
+		case TURRIS_MOX_MODULE_PERIDOT:
+			dev_info(moxtet->dev, "Peridot Switch module found\n");
+			break;
+		default:
+			dev_info(moxtet->dev,
+				 "Unknown Moxtet module found (ID 0x%02x)\n",
+				 module_id);
+		}
+	}
+
+	return 0;
+}
+
+int moxtet_device_read(struct device *dev)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+	struct moxtet *moxtet = mdev->moxtet;
+	u8 buf[TURRIS_MOX_MAX_MODULES];
+	struct spi_transfer xfer = {
+		.rx_buf = buf,
+		.tx_buf = moxtet->tx,
+		.len = moxtet->count + 1
+	};
+	int ret;
+
+	if (mdev->idx >= moxtet->count)
+		return -EINVAL;
+
+	mutex_lock(&moxtet->lock);
+
+	ret = spi_sync_transfer(to_spi_device(moxtet->dev), &xfer, 1);
+
+	mutex_unlock(&moxtet->lock);
+
+	if (ret < 0)
+		return ret;
+
+	return buf[mdev->idx + 1] >> 4;
+}
+EXPORT_SYMBOL_GPL(moxtet_device_read);
+
+int moxtet_device_write(struct device *dev, u8 val)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+	struct moxtet *moxtet = mdev->moxtet;
+	int ret;
+
+	if (mdev->idx >= moxtet->count)
+		return -EINVAL;
+
+	mutex_lock(&moxtet->lock);
+
+	moxtet->tx[moxtet->count - mdev->idx] = val;
+
+	ret = spi_write(to_spi_device(moxtet->dev), moxtet->tx,
+			moxtet->count + 1);
+
+	mutex_unlock(&moxtet->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(moxtet_device_write);
+
+int moxtet_device_written(struct device *dev)
+{
+	struct moxtet_device *mdev = to_moxtet_device(dev);
+	struct moxtet *moxtet = mdev->moxtet;
+
+	if (mdev->idx >= moxtet->count)
+		return -EINVAL;
+
+	return moxtet->tx[moxtet->count - mdev->idx];
+}
+EXPORT_SYMBOL_GPL(moxtet_device_written);
+
+static int moxtet_probe(struct spi_device *spi)
+{
+	struct moxtet *moxtet;
+	int ret;
+
+	ret = spi_setup(spi);
+	if (ret < 0)
+		return ret;
+
+	moxtet = devm_kzalloc(&spi->dev, sizeof(struct moxtet),
+			      GFP_KERNEL);
+	if (!moxtet)
+		return -ENOMEM;
+
+	moxtet->dev = &spi->dev;
+	spi_set_drvdata(spi, moxtet);
+
+	mutex_init(&moxtet->lock);
+
+	ret = moxtet_find_topology(moxtet);
+	if (ret < 0)
+		return ret;
+
+	of_register_moxtet_devices(moxtet);
+	moxtet_register_devices_from_topology(moxtet);
+
+	return 0;
+}
+
+static int moxtet_remove(struct spi_device *spi)
+{
+	struct moxtet *moxtet = spi_get_drvdata(spi);
+	int dummy;
+
+	dummy = device_for_each_child(moxtet->dev, NULL, __unregister);
+
+	mutex_destroy(&moxtet->lock);
+
+	return 0;
+}
+
+static const struct of_device_id moxtet_dt_ids[] = {
+	{ .compatible = "cznic,moxtet" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, moxtet_dt_ids);
+
+static struct spi_driver moxtet_driver = {
+	.driver = {
+		.name		= "moxtet",
+		.of_match_table = moxtet_dt_ids,
+	},
+	.probe		= moxtet_probe,
+	.remove		= moxtet_remove,
+};
+module_spi_driver(moxtet_driver);
+
+static int __init moxtet_init(void)
+{
+	return bus_register(&moxtet_bus_type);
+}
+
+postcore_initcall(moxtet_init);
+
+MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");
+MODULE_DESCRIPTION("CZ.NIC's Turris Mox module configuration bus");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/moxtet.h b/include/linux/mfd/moxtet.h
new file mode 100644
index 000000000000..f818039c2c2e
--- /dev/null
+++ b/include/linux/mfd/moxtet.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Turris Mox module configuration bus driver
+ *
+ * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
+ */
+
+#ifndef __LINUX_MFD_MOXTET_H
+#define __LINUX_MFD_MOXTET_H
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+#define TURRIS_MOX_MAX_MODULES	10
+
+enum turris_mox_cpu_module_id {
+	TURRIS_MOX_CPU_ID_EMMC	= 0x00,
+	TURRIS_MOX_CPU_ID_SD	= 0x10,
+};
+
+enum turris_mox_module_id {
+	TURRIS_MOX_MODULE_SFP		= 0x01,
+	TURRIS_MOX_MODULE_PCI		= 0x02,
+	TURRIS_MOX_MODULE_TOPAZ		= 0x03,
+	TURRIS_MOX_MODULE_PERIDOT	= 0x04,
+};
+
+static inline const char *turris_mox_module_name(unsigned int id)
+{
+	switch (id) {
+	case TURRIS_MOX_MODULE_SFP:
+		return "sfp";
+	case TURRIS_MOX_MODULE_PCI:
+		return "pci";
+	case TURRIS_MOX_MODULE_TOPAZ:
+		return "topaz";
+	case TURRIS_MOX_MODULE_PERIDOT:
+		return "peridot";
+	default:
+		return "unknown";
+	}
+}
+
+extern struct bus_type moxtet_type;
+
+struct moxtet {
+	struct device	*dev;
+	struct mutex	lock;
+	u8		modules[TURRIS_MOX_MAX_MODULES];
+	int		count;
+	u8		tx[TURRIS_MOX_MAX_MODULES];
+	char		module_topology[128];
+};
+
+struct moxtet_driver {
+	const enum turris_mox_module_id	*id_table;
+	struct device_driver		driver;
+};
+
+static inline struct moxtet_driver *
+to_moxtet_driver(struct device_driver *drv)
+{
+	if (!drv)
+		return NULL;
+	return container_of(drv, struct moxtet_driver, driver);
+}
+
+extern int __moxtet_register_driver(struct module *owner,
+				    struct moxtet_driver *mdrv);
+
+static inline void moxtet_unregister_driver(struct moxtet_driver *mdrv)
+{
+	if (mdrv)
+		driver_unregister(&mdrv->driver);
+}
+
+#define moxtet_register_driver(driver) \
+	__moxtet_register_driver(THIS_MODULE, driver)
+
+#define module_moxtet_driver(__moxtet_driver) \
+	module_driver(__moxtet_driver, moxtet_register_driver, \
+			moxtet_unregister_driver)
+
+struct moxtet_device {
+	struct device			dev;
+	struct moxtet			*moxtet;
+	enum turris_mox_module_id	id;
+	unsigned int			idx;
+};
+
+extern int moxtet_device_read(struct device *dev);
+extern int moxtet_device_write(struct device *dev, u8 val);
+extern int moxtet_device_written(struct device *dev);
+
+static inline struct moxtet_device *
+to_moxtet_device(struct device *dev)
+{
+	if (!dev)
+		return NULL;
+	return container_of(dev, struct moxtet_device, dev);
+}
+
+#endif /* __LINUX_MFD_MOXTET_H */
-- 
2.16.4

  parent reply	other threads:[~2018-08-08 15:27 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-08 15:26 [PATCH v1 0/7] Add support for the Turris Mox router Marek Behún
2018-08-08 15:27 ` [PATCH v1 1/7] From: Ken Ma <make@marvell.com> Marek Behún
2018-08-08 16:49   ` Andrew Lunn
2018-08-08 15:27 ` Marek Behún [this message]
2018-08-08 15:32   ` [PATCH v1 2/7] drivers: mfd: Add support for Moxtet bus Marek Behún
2018-08-08 15:27 ` [PATCH v1 3/7] drivers: gpio: Add support for Turris Mox SFP GPIOs Marek Behún
2018-08-08 16:55   ` Andrew Lunn
2018-08-08 20:40     ` Marek Behun
2018-08-08 15:27 ` [PATCH v1 4/7] watchdog: Add support for Armada 37xx CPU watchdog Marek Behún
2018-08-08 15:27 ` [PATCH v1 5/7] arm64: dts: marvell: armada-37xx: add nodes to support watchdog Marek Behún
2018-08-08 15:27 ` [PATCH v1 6/7] net: mvneta: Don't use GRO on Armada 3720 Marek Behún
2018-08-08 15:27   ` Marek Behún
2018-08-08 16:58   ` Andrew Lunn
2018-08-08 16:58     ` Andrew Lunn
2018-08-08 17:57     ` Dave Taht
2018-08-08 17:57       ` Dave Taht
2018-08-09  4:40   ` Jisheng Zhang
2018-08-09  4:40     ` Jisheng Zhang
2018-08-09 11:27     ` Jisheng Zhang
2018-08-09 11:27       ` Jisheng Zhang
2018-08-09 12:08       ` Jisheng Zhang
2018-08-09 12:08         ` Jisheng Zhang
2018-08-21 10:07         ` Marek Behún
2018-08-21 10:07           ` Marek Behún
2018-08-08 15:27 ` [PATCH v1 7/7] ARM64: dts: marvell: Add DTS files for Turris Mox Marek Behún

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=20180808152706.21727-3-marek.behun@nic.cz \
    --to=marek.behun@nic.cz \
    --cc=linux-arm-kernel@lists.infradead.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.