From: Joachim Fenkes <fenkes@de.ibm.com>
To: Paul Mackerras <paulus@samba.org>,
"LinuxPPC-Dev" <linuxppc-dev@ozlabs.org>,
LKML <linux-kernel@vger.kernel.org>
Cc: Thomas Klein <tklein@de.ibm.com>, Arnd Bergmann <arnd@arndb.de>,
Jan-Bernd Themann <themann@de.ibm.com>,
Paul Mackerras <pmac@au1.ibm.com>,
Christoph Raisch <raisch@de.ibm.com>,
Stefan Roscher <stefan.roscher@de.ibm.com>
Subject: [PATCH 3/5] ibmebus: Add device creation and bus probing based on of_device
Date: Tue, 25 Sep 2007 14:12:27 +0200 [thread overview]
Message-ID: <200709251412.27896.fenkes@de.ibm.com> (raw)
In-Reply-To: <200709251410.29780.fenkes@de.ibm.com>
The devtree root is now searched for devices matching a built-in whitelist
during boot, so these devices appear on the bus from the beginning. It is
still possible to manually add/remove devices to/from the bus by using the
probe/remove sysfs interface. Also, when a device driver registers itself,
the devtree is matched against its matchlist.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
arch/powerpc/kernel/ibmebus.c | 97 ++++++++++++++++++++++++++++++++++-------
1 files changed, 81 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index cc80f84..c506e0d 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -51,6 +51,15 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
struct bus_type ibmebus_bus_type;
+/* These devices will automatically be added to the bus during init */
+static struct of_device_id builtin_matches[] = {
+ { .name = "lhca" },
+ { .compatible = "IBM,lhca" },
+ { .name = "lhea" },
+ { .compatible = "IBM,lhea" },
+ {},
+};
+
static void *ibmebus_alloc_coherent(struct device *dev,
size_t size,
dma_addr_t *dma_handle,
@@ -124,6 +133,67 @@ static struct dma_mapping_ops ibmebus_dma_ops = {
.dma_supported = ibmebus_dma_supported,
};
+static int ibmebus_match_path(struct device *dev, void *data)
+{
+ struct device_node *dn = to_of_device(dev)->node;
+ return (dn->full_name &&
+ (strcasecmp((char *)data, dn->full_name) == 0));
+}
+
+static int ibmebus_match_node(struct device *dev, void *data)
+{
+ return to_of_device(dev)->node == data;
+}
+
+static int ibmebus_create_device(struct device_node *dn)
+{
+ struct of_device *dev;
+ int ret;
+
+ dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->dev.bus = &ibmebus_bus_type;
+ dev->dev.archdata.dma_ops = &ibmebus_dma_ops;
+
+ ret = of_device_register(dev);
+ if (ret) {
+ of_device_free(dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ibmebus_create_devices(const struct of_device_id *matches)
+{
+ struct device_node *root, *child;
+ int ret = 0;
+
+ root = of_find_node_by_path("/");
+
+ for (child = NULL; (child = of_get_next_child(root, child)); ) {
+ if (!of_match_node(matches, child))
+ continue;
+
+ if (bus_find_device(&ibmebus_bus_type, NULL, child,
+ ibmebus_match_node))
+ continue;
+
+ ret = ibmebus_create_device(child);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to create device (%i)",
+ __FUNCTION__, ret);
+ of_node_put(child);
+ break;
+ }
+ }
+
+ of_node_put(root);
+ return ret;
+}
+
int ibmebus_register_driver(struct ibmebus_driver *drv)
{
return 0;
@@ -172,18 +242,6 @@ static struct device_attribute ibmebus_dev_attrs[] = {
__ATTR_NULL
};
-static int ibmebus_match_path(struct device *dev, void *data)
-{
- int rc;
- struct device_node *dn =
- of_node_get(to_ibmebus_dev(dev)->ofdev.node);
-
- rc = (dn->full_name && (strcasecmp((char*)data, dn->full_name) == 0));
-
- of_node_put(dn);
- return rc;
-}
-
static char *ibmebus_chomp(const char *in, size_t count)
{
char *out = (char*)kmalloc(count + 1, GFP_KERNEL);
@@ -202,7 +260,6 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
const char *buf, size_t count)
{
struct device_node *dn = NULL;
- struct ibmebus_dev *dev;
char *path;
ssize_t rc;
@@ -219,9 +276,9 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
}
if ((dn = of_find_node_by_path(path))) {
-/* dev = ibmebus_register_device_node(dn); */
+ rc = ibmebus_create_device(dn);
of_node_put(dn);
- rc = IS_ERR(dev) ? PTR_ERR(dev) : count;
+ rc = rc ? rc : count;
} else {
printk(KERN_WARNING "%s: no such device node: %s\n",
__FUNCTION__, path);
@@ -245,7 +302,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
ibmebus_match_path))) {
-/* ibmebus_unregister_device(dev); */
+ of_device_unregister(to_of_device(dev));
kfree(path);
return count;
@@ -265,6 +322,7 @@ static struct bus_attribute ibmebus_bus_attrs[] = {
};
struct bus_type ibmebus_bus_type = {
+ .uevent = of_device_uevent,
.dev_attrs = ibmebus_dev_attrs,
.bus_attrs = ibmebus_bus_attrs
};
@@ -292,6 +350,13 @@ static int __init ibmebus_bus_init(void)
return err;
}
+ err = ibmebus_create_devices(builtin_matches);
+ if (err) {
+ device_unregister(&ibmebus_bus_device);
+ bus_unregister(&ibmebus_bus_type);
+ return err;
+ }
+
return 0;
}
postcore_initcall(ibmebus_bus_init);
--
1.5.2
WARNING: multiple messages have this Message-ID (diff)
From: Joachim Fenkes <fenkes@de.ibm.com>
To: Paul Mackerras <paulus@samba.org>,
"LinuxPPC-Dev" <linuxppc-dev@ozlabs.org>,
LKML <linux-kernel@vger.kernel.org>
Cc: Christoph Raisch <raisch@de.ibm.com>,
"Hoang-Nam Nguyen" <hnguyen@de.ibm.com>,
"Jan-Bernd Themann" <themann@de.ibm.com>,
Stefan Roscher <stefan.roscher@de.ibm.com>,
Thomas Klein <tklein@de.ibm.com>, Arnd Bergmann <arnd@arndb.de>,
Paul Mackerras <pmac@au1.ibm.com>
Subject: [PATCH 3/5] ibmebus: Add device creation and bus probing based on of_device
Date: Tue, 25 Sep 2007 14:12:27 +0200 [thread overview]
Message-ID: <200709251412.27896.fenkes@de.ibm.com> (raw)
In-Reply-To: <200709251410.29780.fenkes@de.ibm.com>
The devtree root is now searched for devices matching a built-in whitelist
during boot, so these devices appear on the bus from the beginning. It is
still possible to manually add/remove devices to/from the bus by using the
probe/remove sysfs interface. Also, when a device driver registers itself,
the devtree is matched against its matchlist.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
arch/powerpc/kernel/ibmebus.c | 97 ++++++++++++++++++++++++++++++++++-------
1 files changed, 81 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index cc80f84..c506e0d 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -51,6 +51,15 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
struct bus_type ibmebus_bus_type;
+/* These devices will automatically be added to the bus during init */
+static struct of_device_id builtin_matches[] = {
+ { .name = "lhca" },
+ { .compatible = "IBM,lhca" },
+ { .name = "lhea" },
+ { .compatible = "IBM,lhea" },
+ {},
+};
+
static void *ibmebus_alloc_coherent(struct device *dev,
size_t size,
dma_addr_t *dma_handle,
@@ -124,6 +133,67 @@ static struct dma_mapping_ops ibmebus_dma_ops = {
.dma_supported = ibmebus_dma_supported,
};
+static int ibmebus_match_path(struct device *dev, void *data)
+{
+ struct device_node *dn = to_of_device(dev)->node;
+ return (dn->full_name &&
+ (strcasecmp((char *)data, dn->full_name) == 0));
+}
+
+static int ibmebus_match_node(struct device *dev, void *data)
+{
+ return to_of_device(dev)->node == data;
+}
+
+static int ibmebus_create_device(struct device_node *dn)
+{
+ struct of_device *dev;
+ int ret;
+
+ dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->dev.bus = &ibmebus_bus_type;
+ dev->dev.archdata.dma_ops = &ibmebus_dma_ops;
+
+ ret = of_device_register(dev);
+ if (ret) {
+ of_device_free(dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ibmebus_create_devices(const struct of_device_id *matches)
+{
+ struct device_node *root, *child;
+ int ret = 0;
+
+ root = of_find_node_by_path("/");
+
+ for (child = NULL; (child = of_get_next_child(root, child)); ) {
+ if (!of_match_node(matches, child))
+ continue;
+
+ if (bus_find_device(&ibmebus_bus_type, NULL, child,
+ ibmebus_match_node))
+ continue;
+
+ ret = ibmebus_create_device(child);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to create device (%i)",
+ __FUNCTION__, ret);
+ of_node_put(child);
+ break;
+ }
+ }
+
+ of_node_put(root);
+ return ret;
+}
+
int ibmebus_register_driver(struct ibmebus_driver *drv)
{
return 0;
@@ -172,18 +242,6 @@ static struct device_attribute ibmebus_dev_attrs[] = {
__ATTR_NULL
};
-static int ibmebus_match_path(struct device *dev, void *data)
-{
- int rc;
- struct device_node *dn =
- of_node_get(to_ibmebus_dev(dev)->ofdev.node);
-
- rc = (dn->full_name && (strcasecmp((char*)data, dn->full_name) == 0));
-
- of_node_put(dn);
- return rc;
-}
-
static char *ibmebus_chomp(const char *in, size_t count)
{
char *out = (char*)kmalloc(count + 1, GFP_KERNEL);
@@ -202,7 +260,6 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
const char *buf, size_t count)
{
struct device_node *dn = NULL;
- struct ibmebus_dev *dev;
char *path;
ssize_t rc;
@@ -219,9 +276,9 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
}
if ((dn = of_find_node_by_path(path))) {
-/* dev = ibmebus_register_device_node(dn); */
+ rc = ibmebus_create_device(dn);
of_node_put(dn);
- rc = IS_ERR(dev) ? PTR_ERR(dev) : count;
+ rc = rc ? rc : count;
} else {
printk(KERN_WARNING "%s: no such device node: %s\n",
__FUNCTION__, path);
@@ -245,7 +302,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
ibmebus_match_path))) {
-/* ibmebus_unregister_device(dev); */
+ of_device_unregister(to_of_device(dev));
kfree(path);
return count;
@@ -265,6 +322,7 @@ static struct bus_attribute ibmebus_bus_attrs[] = {
};
struct bus_type ibmebus_bus_type = {
+ .uevent = of_device_uevent,
.dev_attrs = ibmebus_dev_attrs,
.bus_attrs = ibmebus_bus_attrs
};
@@ -292,6 +350,13 @@ static int __init ibmebus_bus_init(void)
return err;
}
+ err = ibmebus_create_devices(builtin_matches);
+ if (err) {
+ device_unregister(&ibmebus_bus_device);
+ bus_unregister(&ibmebus_bus_type);
+ return err;
+ }
+
return 0;
}
postcore_initcall(ibmebus_bus_init);
--
1.5.2
next prev parent reply other threads:[~2007-09-25 12:12 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-25 12:10 [PATCH 0/5] PowerPC: ibmebus refactoring and fixes Joachim Fenkes
2007-09-25 12:10 ` Joachim Fenkes
2007-09-25 12:11 ` [PATCH 1/5] PowerPC: Move of_device allocation into of_device.[ch] Joachim Fenkes
2007-09-25 12:11 ` Joachim Fenkes
2007-09-25 14:27 ` Arnd Bergmann
2007-09-25 14:27 ` Arnd Bergmann
2007-09-26 9:07 ` Joachim Fenkes
2007-09-26 9:07 ` Joachim Fenkes
2007-09-25 12:11 ` [PATCH 2/5] ibmebus: Remove bus match/probe/remove functions Joachim Fenkes
2007-09-25 12:11 ` Joachim Fenkes
2007-09-25 14:29 ` Arnd Bergmann
2007-09-25 14:29 ` Arnd Bergmann
2007-09-26 9:04 ` Joachim Fenkes
2007-09-26 9:04 ` Joachim Fenkes
2007-09-25 12:12 ` Joachim Fenkes [this message]
2007-09-25 12:12 ` [PATCH 3/5] ibmebus: Add device creation and bus probing based on of_device Joachim Fenkes
2007-09-25 14:39 ` Arnd Bergmann
2007-09-25 14:39 ` Arnd Bergmann
2007-09-26 8:58 ` Joachim Fenkes
2007-09-26 8:58 ` Joachim Fenkes
2007-09-25 12:12 ` [PATCH 4/5] ibmebus: Move to of_device and of_platform_driver, match eHCA and eHEA drivers Joachim Fenkes
2007-09-25 12:12 ` Joachim Fenkes
2007-09-25 14:42 ` Arnd Bergmann
2007-09-25 14:42 ` Arnd Bergmann
2007-09-26 8:43 ` Joachim Fenkes
2007-09-26 8:43 ` Joachim Fenkes
2007-09-25 12:13 ` [PATCH 5/5] ibmebus: More speaking error return code in ibmebus_store_probe() Joachim Fenkes
2007-09-25 12:13 ` Joachim Fenkes
-- strict thread matches above, loose matches on Subject: below --
2007-09-26 9:43 [PATCH 0/5] [REPOST] PowerPC: ibmebus refactoring and fixes Joachim Fenkes
2007-09-26 9:45 ` [PATCH 3/5] ibmebus: Add device creation and bus probing based on of_device Joachim Fenkes
2007-09-26 9:45 ` Joachim Fenkes
2007-09-27 11:27 ` Arnd Bergmann
2007-09-27 11:27 ` Arnd Bergmann
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=200709251412.27896.fenkes@de.ibm.com \
--to=fenkes@de.ibm.com \
--cc=arnd@arndb.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=paulus@samba.org \
--cc=pmac@au1.ibm.com \
--cc=raisch@de.ibm.com \
--cc=stefan.roscher@de.ibm.com \
--cc=themann@de.ibm.com \
--cc=tklein@de.ibm.com \
/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.