summaryrefslogtreecommitdiffstats
path: root/drivers/nubus/nubus.c
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2018-01-13 23:37:14 +0100
committerGeert Uytterhoeven <geert@linux-m68k.org>2018-01-16 16:47:29 +0100
commit7f86c765a6a2bb837c45f11526176125ff50e21f (patch)
tree6279c4d31d2bd999852544da73e446e0c28f901d /drivers/nubus/nubus.c
parentnubus: Add expansion_type values for various Mac models (diff)
downloadlinux-7f86c765a6a2bb837c45f11526176125ff50e21f.tar.xz
linux-7f86c765a6a2bb837c45f11526176125ff50e21f.zip
nubus: Add support for the driver model
This patch brings basic support for the Linux Driver Model to the NuBus subsystem. For flexibility, the matching of boards with drivers is left up to the drivers. This is also the approach taken by NetBSD. A board may have many functions, and drivers may have to consider many functional resources and board resources in order to match a device. This implementation does not bind drivers to resources (nor does it bind many drivers to the same board). Apple's NuBus declaration ROM design is flexible enough to allow that, but I don't see a need to support it as we don't use the "slot zero" resources (in the main logic board ROM). Eliminate the global nubus_boards linked list by rewriting the procfs board iterator around bus_for_each_dev(). Hence the nubus device refcount can be used to determine the lifespan of board objects. Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Tested-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'drivers/nubus/nubus.c')
-rw-r--r--drivers/nubus/nubus.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 0bb54ccd7a1a..4621ff98138c 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -33,7 +33,6 @@
/* Globals */
LIST_HEAD(nubus_func_rsrcs);
-struct nubus_board *nubus_boards;
/* Meaning of "bytelanes":
@@ -715,10 +714,9 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
return 0;
}
-static struct nubus_board * __init nubus_add_board(int slot, int bytelanes)
+static void __init nubus_add_board(int slot, int bytelanes)
{
struct nubus_board *board;
- struct nubus_board **boardp;
unsigned char *rp;
unsigned long dpat;
struct nubus_dir dir;
@@ -731,7 +729,7 @@ static struct nubus_board * __init nubus_add_board(int slot, int bytelanes)
/* Actually we should probably panic if this fails */
if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
- return NULL;
+ return;
board->fblock = rp;
/* Dump the format block for debugging purposes */
@@ -794,7 +792,8 @@ static struct nubus_board * __init nubus_add_board(int slot, int bytelanes)
if (nubus_readdir(&dir, &ent) == -1) {
/* We can't have this! */
pr_err("Slot %X: Board resource not found!\n", slot);
- return NULL;
+ kfree(board);
+ return;
}
if (ent.type < 1 || ent.type > 127)
@@ -823,14 +822,8 @@ static struct nubus_board * __init nubus_add_board(int slot, int bytelanes)
list_add_tail(&fres->list, &nubus_func_rsrcs);
}
- /* Put it on the global NuBus board chain. Keep entries in order. */
- for (boardp = &nubus_boards; *boardp != NULL;
- boardp = &((*boardp)->next))
- /* spin */;
- *boardp = board;
- board->next = NULL;
-
- return board;
+ if (nubus_device_register(board))
+ put_device(&board->dev);
}
static void __init nubus_probe_slot(int slot)
@@ -876,10 +869,15 @@ static void __init nubus_scan_bus(void)
static int __init nubus_init(void)
{
+ int err;
+
if (!MACH_IS_MAC)
return 0;
nubus_proc_init();
+ err = nubus_bus_register();
+ if (err)
+ return err;
nubus_scan_bus();
return 0;
}