ofwbus: remove handling of resources from ofwbus

The architecture nexus should handle allocation and release of memory and
interrupts. This is to ensure that system-wide resources such as these
are available to all devices, not just children of ofwbus0.

On powerpc this moves the ownership of these resources up one level,
from ofwbus0 to nexus0. Other architectures already have the required
logic in their nexus implementation, so this eliminates the duplication
of resources. An implementation of nexus_adjust_resource() is added for
arm, arm64, and riscv.

As noted by ian@ in the review, resource handling was the main bit of
logic distinguishing ofwbus from simplebus. With some attention to
detail, it should be possible to merge the two in the future.

Co-authored by:	mhorne
MFC after:	1 month
Differential Revision: https://reviews.freebsd.org/D30554
This commit is contained in:
Elliott Mitchell
2023-02-08 16:17:03 -04:00
committed by Mitchell Horne
parent 1d03c3578d
commit f9bdaab95e
5 changed files with 173 additions and 83 deletions
+24
View File
@@ -87,6 +87,8 @@ static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
rman_res_t, rman_res_t, rman_res_t, u_int);
static int nexus_activate_resource(device_t, device_t, int, int,
struct resource *);
static int nexus_adjust_resource(device_t, device_t, int, struct resource *,
rman_res_t, rman_res_t);
static bus_space_tag_t nexus_get_bus_tag(device_t, device_t);
static bus_dma_tag_t nexus_get_dma_tag(device_t dev, device_t child);
#ifdef SMP
@@ -126,6 +128,7 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_adjust_resource, nexus_adjust_resource),
DEVMETHOD(bus_config_intr, nexus_config_intr),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_release_resource, nexus_release_resource),
@@ -263,6 +266,27 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (rv);
}
static int
nexus_adjust_resource(device_t bus __unused, device_t child __unused, int type,
struct resource *r, rman_res_t start, rman_res_t end)
{
struct rman *rm;
switch (type) {
case SYS_RES_IRQ:
rm = &irq_rman;
break;
case SYS_RES_MEMORY:
rm = &mem_rman;
break;
default:
return (EINVAL);
}
if (rman_is_region_manager(r, rm) == 0)
return (EINVAL);
return (rman_adjust_resource(r, start, end));
}
static int
nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)