diff mbox

[v4,13/21] misc: support for LP-8x4x custom parallel bus

Message ID 1397668667-27328-7-git-send-email-ynvich@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sergey Yanovich April 16, 2014, 5:17 p.m. UTC
This patch implements probing for the bus and reporting the number
of available expansion slots.

Signed-off-by: Sergei Ianovich <ynvich@gmail.com>
---
   v3..v4
   * move DTS binding to a different patch (8/21)

   v2..v3
   * fixed goto after bus_register
   * number change (11/16 -> 13/21)

   v0..v2
   * use device tree
   * use devm helpers where possible

 .../devicetree/bindings/misc/lp8x4x-bus.txt        |  16 ++
 Documentation/misc-devices/lp8x4x_bus.txt          |  30 ++++
 arch/arm/configs/lp8x4x_defconfig                  |   1 +
 drivers/misc/Kconfig                               |  13 ++
 drivers/misc/Makefile                              |   1 +
 drivers/misc/lp8x4x_bus.c                          | 167 +++++++++++++++++++++
 6 files changed, 228 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
 create mode 100644 Documentation/misc-devices/lp8x4x_bus.txt
 create mode 100644 drivers/misc/lp8x4x_bus.c

Comments

Alan Cox April 16, 2014, 6:41 p.m. UTC | #1
On Wed, 16 Apr 2014 21:17:18 +0400
Sergei Ianovich <ynvich@gmail.com> wrote:

> This patch implements probing for the bus and reporting the number
> of available expansion slots.

This appears to be a bus not a misc device. I don't think it belongs in
misc. As you've got devices on this bus (or nailed into the 'bus' driver)
perhaps this belongs as drivers/platform/lp8x4x or similar with any
specific drivers split out - or even drivers/lp8x4x if there will be more
of them and more than one platform using it ?

Alan
Arnd Bergmann April 16, 2014, 6:42 p.m. UTC | #2
On Wednesday 16 April 2014 19:41:09 One Thousand Gnomes wrote:
> On Wed, 16 Apr 2014 21:17:18 +0400
> Sergei Ianovich <ynvich@gmail.com> wrote:
> 
> > This patch implements probing for the bus and reporting the number
> > of available expansion slots.
> 
> This appears to be a bus not a misc device. I don't think it belongs in
> misc. As you've got devices on this bus (or nailed into the 'bus' driver)
> perhaps this belongs as drivers/platform/lp8x4x or similar with any
> specific drivers split out - or even drivers/lp8x4x if there will be more
> of them and more than one platform using it ?

We have drivers/bus now, I think it could fit well in there.

	Arnd
Sergey Yanovich April 16, 2014, 7:53 p.m. UTC | #3
One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> wrote:
>On Wed, 16 Apr 2014 21:17:18 +0400
>Sergei Ianovich <ynvich@gmail.com> wrote:
>
>> This patch implements probing for the bus and reporting the number
>> of available expansion slots.
>
>This appears to be a bus not a misc device. I don't think it belongs in
>misc. As you've got devices on this bus (or nailed into the 'bus'
>driver)
>perhaps this belongs as drivers/platform/lp8x4x or similar with any
>specific drivers split out - or even drivers/lp8x4x if there will be
>more
>of them and more than one platform using it ?

Thanks again for responding. I don't have a clear idea about proper code organization concering this bus.

The total number of possible bus devices is quite large, around 30. Half of them would take less than 10 extra lines to get support. The rest is more complicated.

LP-8x4x has several features that would require a misc device anyway. It has a rotary switch which isn't an input device, because it produces no interrupts. The device also has a similar DIP switch. In addition, it acts as a kind of RS-485-port-to-multi-RS-232-ports logical bridge. It has a multiplexer which allows to talk to several serial modules which support a custom protocol designed for RS-485 using a RS-232 port.
Alan Cox April 16, 2014, 8:29 p.m. UTC | #4
On Wed, 16 Apr 2014 20:42:39 +0200
Arnd Bergmann <arnd@arndb.de> wrote:

> On Wednesday 16 April 2014 19:41:09 One Thousand Gnomes wrote:
> > On Wed, 16 Apr 2014 21:17:18 +0400
> > Sergei Ianovich <ynvich@gmail.com> wrote:
> > 
> > > This patch implements probing for the bus and reporting the number
> > > of available expansion slots.
> > 
> > This appears to be a bus not a misc device. I don't think it belongs in
> > misc. As you've got devices on this bus (or nailed into the 'bus' driver)
> > perhaps this belongs as drivers/platform/lp8x4x or similar with any
> > specific drivers split out - or even drivers/lp8x4x if there will be more
> > of them and more than one platform using it ?
> 
> We have drivers/bus now, I think it could fit well in there.

Agreed
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
new file mode 100644
index 0000000..1c87a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/lp8x4x-bus.txt
@@ -0,0 +1,16 @@ 
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+See Documentation/misc-devices/lp8x4x_bus.txt for details.
+
+Required properties:
+- compatible : should be "icpdas,backplane-lp8x4x"
+
+- reg: physical base address of the slot count register and the length
+       of the memory mapped region.
+
+Example:
+
+	backplane {
+		compatible = "icpdas,backplane-lp8x4x";
+		reg = <0x17009046 0x2>;
+	};
diff --git a/Documentation/misc-devices/lp8x4x_bus.txt b/Documentation/misc-devices/lp8x4x_bus.txt
new file mode 100644
index 0000000..f5392b3
--- /dev/null
+++ b/Documentation/misc-devices/lp8x4x_bus.txt
@@ -0,0 +1,30 @@ 
+Kernel driver lpx8x4x_bus
+======================
+
+Supported hardare:
+Custom parallel bus on ICP DAS LP-8x4x industrial computers
+
+Data sheet:
+Not freely available
+
+Author:
+Sergei Ianovich <ynvich@gmail.com>
+
+Description
+-----------
+
+http://www.icpdas.com/root/product/solutions/pac/linpac/lp-8x4x_hardware.html
+
+LP-8x4x is an ARM-based industrial computer with a custom parallel bus to
+connect expansion modules with digital input/output, analog input/output,
+serial, CAN and other types of ports.
+
+The bus is implemented by a FPGA.
+
+SYSFS
+-----
+
+/sys/bus/icpdas/devices/backplane:
+
+slot_count
+	RO - shows total number of expansion slots on the device
diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig
index 9116ce1..c34eb2a 100644
--- a/arch/arm/configs/lp8x4x_defconfig
+++ b/arch/arm/configs/lp8x4x_defconfig
@@ -62,6 +62,7 @@  CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
 CONFIG_EEPROM_AT24=m
+CONFIG_LP8X4X_BUS=m
 CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1cb7408..08ffe63 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -515,6 +515,19 @@  config SRAM
 	  the genalloc API. It is supposed to be used for small on-chip SRAM
 	  areas found on many SoCs.
 
+config LP8X4X_BUS
+	tristate "ICP DAS LP-8x4x industrial IO bus"
+	depends on OF && ARCH_PXA
+	select SYSFS
+	---help---
+	  This is a driver for ICP DAS LP-8x4x programmable automation
+	  controller. It exposes a custom parallel bus. The bus services
+	  data acquisition and control modules.
+
+	  Say N, unless you plan to run this kernel on a LP-8x4x system.
+
+	  If you say M here, the module will be called lp8x4x_bus.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7eb4b69..2bfe25d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,3 +55,4 @@  obj-$(CONFIG_SRAM)		+= sram.o
 obj-y				+= mic/
 obj-$(CONFIG_GENWQE)		+= genwqe/
 obj-$(CONFIG_ECHO)		+= echo/
+obj-$(CONFIG_LP8X4X_BUS)	+= lp8x4x_bus.o
diff --git a/drivers/misc/lp8x4x_bus.c b/drivers/misc/lp8x4x_bus.c
new file mode 100644
index 0000000..7aa55cf
--- /dev/null
+++ b/drivers/misc/lp8x4x_bus.c
@@ -0,0 +1,167 @@ 
+/*
+ *  linux/misc/lp8x4x_bus.c
+ *
+ *  Support for ICP DAS LP-8x4x programmable automation controller bus
+ *  Copyright (C) 2013 Sergei Ianovich <ynvich@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 or any later version.
+ */
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME	"lp8x4x-bus"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sergei Ianovich <ynvich@gmail.com>");
+MODULE_DESCRIPTION("ICP DAS LP-8x4x parallel bus driver");
+
+struct lp8x4x_master {
+	unsigned int		slot_count;
+	void			*count_addr;
+	struct device		dev;
+};
+
+static int lp8x4x_match(struct device *dev, struct device_driver *drv)
+{
+	return 1;
+}
+
+static struct bus_type lp8x4x_bus_type = {
+	.name		= "icpdas",
+	.match		= lp8x4x_match,
+};
+
+static void lp8x4x_master_release(struct device *dev)
+{
+	struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+	WARN_ON(!dev);
+
+	kfree(m);
+}
+
+static ssize_t slot_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct lp8x4x_master *m = container_of(dev, struct lp8x4x_master, dev);
+
+	return sprintf(buf, "%u\n", m->slot_count);
+}
+
+static DEVICE_ATTR_RO(slot_count);
+
+static struct attribute *master_dev_attrs[] = {
+	&dev_attr_slot_count.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(master_dev);
+
+
+static void devm_lp8x4x_bus_release(struct device *dev, void *res)
+{
+	struct lp8x4x_master *m = *(struct lp8x4x_master **)res;
+
+	dev_dbg(dev, "releasing devices\n");
+	device_unregister(&m->dev);
+	bus_unregister(&lp8x4x_bus_type);
+}
+
+static int __init lp8x4x_bus_probe(struct platform_device *pdev)
+{
+	struct lp8x4x_master *m, **p;
+	struct resource *res;
+	int err = 0;
+
+	m = kzalloc(sizeof(*m), GFP_KERNEL);
+	if (!m)
+		return -ENOMEM;
+
+	p = devres_alloc(devm_lp8x4x_bus_release, sizeof(*p), GFP_KERNEL);
+	if (!p) {
+		err = -ENOMEM;
+		goto err1;
+	}
+	*p = m;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "could not get slot count address\n");
+		err = -ENODEV;
+		goto err2;
+	}
+
+	m->count_addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(m->count_addr)) {
+		dev_err(&pdev->dev, "Failed to ioremap slot count address\n");
+		err = PTR_ERR(m->count_addr);
+		goto err2;
+	}
+
+	m->slot_count = ioread8(m->count_addr);
+	switch (m->slot_count) {
+	case 1:
+	case 4:
+		break;
+	case 7:
+		m->slot_count = 8;
+		break;
+	default:
+		dev_err(&pdev->dev, "unexpected slot number(%u)",
+				m->slot_count);
+		err = -ENODEV;
+		goto err2;
+	};
+
+	dev_info(&pdev->dev, "found bus with up to %u slots\n", m->slot_count);
+
+	err = bus_register(&lp8x4x_bus_type);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to register bus type\n");
+		goto err2;
+	}
+
+	m->dev.bus = &lp8x4x_bus_type;
+	dev_set_name(&m->dev, "backplane");
+	m->dev.parent = &pdev->dev;
+	m->dev.release = lp8x4x_master_release;
+	m->dev.groups = master_dev_groups;
+
+	err = device_register(&m->dev);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to register backplane device\n");
+		goto err3;
+	}
+
+	devres_add(&pdev->dev, p);
+	return 0;
+
+err3:
+	bus_unregister(&lp8x4x_bus_type);
+err2:
+	devres_free(p);
+err1:
+	kfree(m);
+	return err;
+}
+
+static const struct of_device_id lp8x4x_bus_dt_ids[] = {
+	{ .compatible = "icpdas,backplane-lp8x4x" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lp8x4x_bus_dt_ids);
+
+static struct platform_driver lp8x4x_bus_driver = {
+	.driver		= {
+		.name	= MODULE_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = lp8x4x_bus_dt_ids,
+	},
+};
+
+module_platform_driver_probe(lp8x4x_bus_driver, lp8x4x_bus_probe);