diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2018-01-13 23:37:14 +0100 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2018-01-16 16:47:29 +0100 |
commit | 7f86c765a6a2bb837c45f11526176125ff50e21f (patch) | |
tree | 6279c4d31d2bd999852544da73e446e0c28f901d /drivers/nubus/nubus.c | |
parent | nubus: Add expansion_type values for various Mac models (diff) | |
download | linux-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.c | 24 |
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; } |