All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Mundt <paul.mundt@nokia.com>
To: Greg KH <greg@kroah.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] SuperHyway bus support
Date: Fri, 7 Jan 2005 18:29:45 +0200	[thread overview]
Message-ID: <20050107162945.GA19043@pointless.research.nokia.com> (raw)
In-Reply-To: <20050107094103.GA7408@pointless.research.nokia.com>

[-- Attachment #1: Type: text/plain, Size: 9879 bytes --]

On Fri, Jan 07, 2005 at 11:41:04AM +0200, Paul Mundt wrote:
> > Also, why have a local list of devices and not just use the list the
> > driver core provides for you?
> > 
> Probably because I wasn't aware that the driver core provided one. Now that I
> see the bus_for_each_xxx() stuff I'll drop the list and use that instead.
> 
I dropped this entirely as the release() stuff did what I was looking for..

> Thanks for looking at this, I'll post a cleaned up version shortly.

Here it is against current BK.. let me know if you have any other issues.

Signed-off-by: Paul Mundt <paul.mundt@nokia.com>

 drivers/Makefile                         |    1 
 drivers/sh/Makefile                      |    6 
 drivers/sh/superhyway/Makefile           |    7 +
 drivers/sh/superhyway/superhyway-sysfs.c |   47 +++++++
 drivers/sh/superhyway/superhyway.c       |  205 +++++++++++++++++++++++++++++++
 5 files changed, 266 insertions(+)

--- linux-2.6/drivers/Makefile	2004-12-31 03:37:37.000000000 +0200
+++ linux-sh64-2.6/drivers/Makefile	2005-01-07 18:18:42.055174960 +0200
@@ -62,3 +62,4 @@
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
+obj-$(CONFIG_SUPERH)		+= sh/
diff -urN linux-2.6/drivers/sh/Makefile linux-sh64-2.6/drivers/sh/Makefile
--- linux-2.6/drivers/sh/Makefile	1970-01-01 02:00:00.000000000 +0200
+++ linux-sh64-2.6/drivers/sh/Makefile	2004-12-07 14:16:02.000000000 +0200
@@ -0,0 +1,6 @@
+#
+# Makefile for the SuperH specific drivers.
+#
+
+obj-$(CONFIG_SUPERHYWAY) += superhyway/
+
diff -urN linux-2.6/drivers/sh/superhyway/Makefile linux-sh64-2.6/drivers/sh/superhyway/Makefile
--- linux-2.6/drivers/sh/superhyway/Makefile	1970-01-01 02:00:00.000000000 +0200
+++ linux-sh64-2.6/drivers/sh/superhyway/Makefile	2005-01-07 18:19:26.394434368 +0200
@@ -0,0 +1,7 @@
+#
+# Makefile for the SuperHyway bus drivers.
+#
+
+obj-$(CONFIG_SUPERHYWAY)	+= superhyway.o
+obj-$(CONFIG_SYSFS)		+= superhyway-sysfs.o
+
diff -urN linux-2.6/drivers/sh/superhyway/superhyway.c linux-sh64-2.6/drivers/sh/superhyway/superhyway.c
--- linux-2.6/drivers/sh/superhyway/superhyway.c	1970-01-01 02:00:00.000000000 +0200
+++ linux-sh64-2.6/drivers/sh/superhyway/superhyway.c	2005-01-07 18:15:08.102700680 +0200
@@ -0,0 +1,205 @@
+/*
+ * drivers/sh/superhyway/superhyway.c
+ *
+ * SuperHyway Bus Driver
+ *
+ * Copyright (C) 2004, 2005  Paul Mundt <lethal@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/superhyway.h>
+
+static int superhyway_devices;
+
+static struct device superhyway_bus_device = {
+	.bus_id = "superhyway",
+};
+
+static void superhyway_device_release(struct device *dev)
+{
+	kfree(to_superhyway_device(dev));
+}
+
+/**
+ * superhyway_add_device - Add a SuperHyway module
+ * @mod_id: Module ID (taken from MODULE.VCR.MOD_ID).
+ * @base: Physical address where module is mapped.
+ * @vcr: VCR value.
+ *
+ * This is responsible for adding a new SuperHyway module. This sets up a new
+ * struct superhyway_device for the module being added. Each one of @mod_id,
+ * @base, and @vcr are registered with the new device for further use
+ * elsewhere.
+ *
+ * Devices are initially added in the order that they are scanned (from the
+ * top-down of the memory map), and are assigned an ID based on the order that
+ * they are added. Any manual addition of a module will thus get the ID after
+ * the devices already discovered regardless of where it resides in memory.
+ *
+ * Further work can and should be done in superhyway_scan_bus(), to be sure
+ * that any new modules are properly discovered and subsequently registered.
+ */
+int superhyway_add_device(unsigned int mod_id, unsigned long base,
+			  unsigned long long vcr)
+{
+	struct superhyway_device *dev;
+
+	dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	memset(dev, 0, sizeof(struct superhyway_device));
+
+	dev->id.id = mod_id;
+	sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
+
+	dev->vcr		= *((struct vcr_info *)(&vcr));
+	dev->resource.name	= dev->name;
+	dev->resource.start	= base;
+	dev->resource.end	= dev->resource.start + 0x01000000;
+	dev->dev.parent		= &superhyway_bus_device;
+	dev->dev.bus		= &superhyway_bus_type;
+	dev->dev.release	= superhyway_device_release;
+
+	sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
+
+	superhyway_devices++;
+
+	return device_register(&dev->dev);
+}
+
+static int __init superhyway_init(void)
+{
+	extern int superhyway_scan_bus(void);
+
+	device_register(&superhyway_bus_device);
+
+	return superhyway_scan_bus();
+}
+
+postcore_initcall(superhyway_init);
+
+static const struct superhyway_device_id *
+superhyway_match_id(const struct superhyway_device_id *ids,
+		    struct superhyway_device *dev)
+{
+	while (ids->id) {
+		if (ids->id == dev->id.id)
+			return ids;
+
+		ids++;
+	}
+
+	return NULL;
+}
+
+static int superhyway_device_probe(struct device *dev)
+{
+	struct superhyway_device *shyway_dev = to_superhyway_device(dev);
+	struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver);
+
+	if (shyway_drv && shyway_drv->probe) {
+		const struct superhyway_device_id *id;
+
+		id = superhyway_match_id(shyway_drv->id_table, shyway_dev);
+		if (id)
+			return shyway_drv->probe(shyway_dev, id);
+	}
+
+	return -ENODEV;
+}
+
+static int superhyway_device_remove(struct device *dev)
+{
+	struct superhyway_device *shyway_dev = to_superhyway_device(dev);
+	struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver);
+
+	if (shyway_drv && shyway_drv->remove) {
+		shyway_drv->remove(shyway_dev);
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
+/**
+ * superhyway_register_driver - Register a new SuperHyway driver
+ * @drv: SuperHyway driver to register.
+ *
+ * This registers the passed in @drv. Any devices matching the id table will
+ * automatically be populated and handed off to the driver's specified probe
+ * routine.
+ */
+int superhyway_register_driver(struct superhyway_driver *drv)
+{
+	drv->drv.name	= drv->name;
+	drv->drv.bus	= &superhyway_bus_type;
+	drv->drv.probe	= superhyway_device_probe;
+	drv->drv.remove	= superhyway_device_remove;
+
+	return driver_register(&drv->drv);
+}
+
+/**
+ * superhyway_unregister_driver - Unregister a SuperHyway driver
+ * @drv: SuperHyway driver to unregister.
+ *
+ * This cleans up after superhyway_register_driver(), and should be invoked in
+ * the exit path of any module drivers.
+ */
+void superhyway_unregister_driver(struct superhyway_driver *drv)
+{
+	driver_unregister(&drv->drv);
+}
+
+static int superhyway_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct superhyway_device *shyway_dev = to_superhyway_device(dev);
+	struct superhyway_driver *shyway_drv = to_superhyway_driver(drv);
+	const struct superhyway_device_id *ids = shyway_drv->id_table;
+
+	if (!ids)
+		return -EINVAL;
+	if (superhyway_match_id(ids, shyway_dev))
+		return 1;
+
+	return -ENODEV;
+}
+
+struct bus_type superhyway_bus_type = {
+	.name		= "superhyway",
+	.match		= superhyway_bus_match,
+#ifdef CONFIG_SYSFS
+	.dev_attrs	= superhyway_dev_attrs,
+#endif
+};
+
+static int __init superhyway_bus_init(void)
+{
+	return bus_register(&superhyway_bus_type);
+}
+
+static void __exit superhyway_bus_exit(void)
+{
+	device_unregister(&superhyway_bus_device);
+	bus_unregister(&superhyway_bus_type);
+}
+
+core_initcall(superhyway_bus_init);
+module_exit(superhyway_bus_exit);
+
+EXPORT_SYMBOL(superhyway_bus_type);
+EXPORT_SYMBOL(superhyway_add_device);
+EXPORT_SYMBOL(superhyway_register_driver);
+EXPORT_SYMBOL(superhyway_unregister_driver);
+
diff -urN linux-2.6/drivers/sh/superhyway/superhyway-sysfs.c linux-sh64-2.6/drivers/sh/superhyway/superhyway-sysfs.c
--- linux-2.6/drivers/sh/superhyway/superhyway-sysfs.c	1970-01-01 02:00:00.000000000 +0200
+++ linux-sh64-2.6/drivers/sh/superhyway/superhyway-sysfs.c	2005-01-07 18:08:57.463046472 +0200
@@ -0,0 +1,47 @@
+/*
+ * drivers/sh/superhyway/superhyway-sysfs.c
+ *
+ * SuperHyway Bus sysfs interface
+ *
+ * Copyright (C) 2004, 2005  Paul Mundt <lethal@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/superhyway.h>
+
+#define superhyway_ro_attr(name, fmt, field)				\
+static ssize_t name##_show(struct device *dev, char *buf)		\
+{									\
+	struct superhyway_device *s = to_superhyway_device(dev);	\
+	return sprintf(buf, fmt, s->field);				\
+}
+
+/* VCR flags */
+superhyway_ro_attr(perr_flags, "0x%02x\n", vcr.perr_flags);
+superhyway_ro_attr(merr_flags, "0x%02x\n", vcr.merr_flags);
+superhyway_ro_attr(mod_vers, "0x%04x\n", vcr.mod_vers);
+superhyway_ro_attr(mod_id, "0x%04x\n", vcr.mod_id);
+superhyway_ro_attr(bot_mb, "0x%02x\n", vcr.bot_mb);
+superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb);
+
+/* Misc */
+superhyway_ro_attr(resource, "0x%08lx\n", resource.start);
+
+struct device_attribute superhyway_dev_attrs[] = {
+	__ATTR_RO(perr_flags),
+	__ATTR_RO(merr_flags),
+	__ATTR_RO(mod_vers),
+	__ATTR_RO(mod_id),
+	__ATTR_RO(bot_mb),
+	__ATTR_RO(top_mb),
+	__ATTR_RO(resource),
+	__ATTR_NULL,
+};
+

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

  reply	other threads:[~2005-01-07 16:33 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-27  7:52 [PATCH] SuperHyway bus support Paul Mundt
2005-01-07  7:22 ` Greg KH
2005-01-07  9:41   ` Paul Mundt
2005-01-07 16:29     ` Paul Mundt [this message]
2005-01-12  8:17       ` Greg KH
2005-01-12 12:48         ` Paul Mundt
2005-01-25 14:08           ` Paul Mundt
2005-01-25 20:30             ` Greg KH
2005-02-01 22:05           ` Greg KH
2005-02-01 22:23             ` Sam Ravnborg
2005-02-01 22:30               ` Greg KH
2005-02-02  7:04                 ` Paul Mundt
2005-02-02  7:10             ` Paul Mundt
2005-02-02 22:19               ` Greg KH

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=20050107162945.GA19043@pointless.research.nokia.com \
    --to=paul.mundt@nokia.com \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.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 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.