-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Finn Thain
authored and
Geert Uytterhoeven
committed
Jan 16, 2018
1 parent
b87eaec
commit 7f86c76
Showing
5 changed files
with
161 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// | ||
// Bus implementation for the NuBus subsystem. | ||
// | ||
// Copyright (C) 2017 Finn Thain | ||
|
||
#include <linux/device.h> | ||
#include <linux/list.h> | ||
#include <linux/nubus.h> | ||
#include <linux/seq_file.h> | ||
#include <linux/slab.h> | ||
|
||
#define to_nubus_board(d) container_of(d, struct nubus_board, dev) | ||
#define to_nubus_driver(d) container_of(d, struct nubus_driver, driver) | ||
|
||
static int nubus_bus_match(struct device *dev, struct device_driver *driver) | ||
{ | ||
return 1; | ||
} | ||
|
||
static int nubus_device_probe(struct device *dev) | ||
{ | ||
struct nubus_driver *ndrv = to_nubus_driver(dev->driver); | ||
int err = -ENODEV; | ||
|
||
if (ndrv->probe) | ||
err = ndrv->probe(to_nubus_board(dev)); | ||
return err; | ||
} | ||
|
||
static int nubus_device_remove(struct device *dev) | ||
{ | ||
struct nubus_driver *ndrv = to_nubus_driver(dev->driver); | ||
int err = -ENODEV; | ||
|
||
if (dev->driver && ndrv->remove) | ||
err = ndrv->remove(to_nubus_board(dev)); | ||
return err; | ||
} | ||
|
||
struct bus_type nubus_bus_type = { | ||
.name = "nubus", | ||
.match = nubus_bus_match, | ||
.probe = nubus_device_probe, | ||
.remove = nubus_device_remove, | ||
}; | ||
EXPORT_SYMBOL(nubus_bus_type); | ||
|
||
int nubus_driver_register(struct nubus_driver *ndrv) | ||
{ | ||
ndrv->driver.bus = &nubus_bus_type; | ||
return driver_register(&ndrv->driver); | ||
} | ||
EXPORT_SYMBOL(nubus_driver_register); | ||
|
||
void nubus_driver_unregister(struct nubus_driver *ndrv) | ||
{ | ||
driver_unregister(&ndrv->driver); | ||
} | ||
EXPORT_SYMBOL(nubus_driver_unregister); | ||
|
||
static struct device nubus_parent = { | ||
.init_name = "nubus", | ||
}; | ||
|
||
int __init nubus_bus_register(void) | ||
{ | ||
int err; | ||
|
||
err = device_register(&nubus_parent); | ||
if (err) | ||
return err; | ||
|
||
err = bus_register(&nubus_bus_type); | ||
if (!err) | ||
return 0; | ||
|
||
device_unregister(&nubus_parent); | ||
return err; | ||
} | ||
|
||
static void nubus_device_release(struct device *dev) | ||
{ | ||
struct nubus_board *board = to_nubus_board(dev); | ||
struct nubus_rsrc *fres, *tmp; | ||
|
||
list_for_each_entry_safe(fres, tmp, &nubus_func_rsrcs, list) | ||
if (fres->board == board) { | ||
list_del(&fres->list); | ||
kfree(fres); | ||
} | ||
kfree(board); | ||
} | ||
|
||
int nubus_device_register(struct nubus_board *board) | ||
{ | ||
board->dev.parent = &nubus_parent; | ||
board->dev.release = nubus_device_release; | ||
board->dev.bus = &nubus_bus_type; | ||
dev_set_name(&board->dev, "slot.%X", board->slot); | ||
return device_register(&board->dev); | ||
} | ||
|
||
static int nubus_print_device_name_fn(struct device *dev, void *data) | ||
{ | ||
struct nubus_board *board = to_nubus_board(dev); | ||
struct seq_file *m = data; | ||
|
||
seq_printf(m, "Slot %X: %s\n", board->slot, board->name); | ||
return 0; | ||
} | ||
|
||
int nubus_proc_show(struct seq_file *m, void *data) | ||
{ | ||
return bus_for_each_dev(&nubus_bus_type, NULL, m, | ||
nubus_print_device_name_fn); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters