Refactor slightly to create acpi_rescan(), a hook for rescanning the
devices that attach at acpi(4). Begin deriving an acpi(4) device-detachment hook, acpi_detach(), from acpi_attach(). The code between #if 0 and #endif still needs to be turned to the opposite calls (enables to disables, maps to unmaps, attaches to detaches), which should be run in the opposite order. Somebody with deep ACPI knowledge can probably finish this off without too much trouble.
This commit is contained in:
parent
5b0576e7eb
commit
222f7adf37
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: acpi.c,v 1.123 2009/01/30 12:51:03 jmcneill Exp $ */
|
||||
/* $NetBSD: acpi.c,v 1.124 2009/04/08 00:23:30 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
|
||||
@ -70,7 +70,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.123 2009/01/30 12:51:03 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.124 2009/04/08 00:23:30 dyoung Exp $");
|
||||
|
||||
#include "opt_acpi.h"
|
||||
#include "opt_pcifixup.h"
|
||||
@ -120,6 +120,11 @@ static ACPI_TABLE_DESC acpi_initial_tables[128];
|
||||
static int acpi_match(device_t, struct cfdata *, void *);
|
||||
static void acpi_attach(device_t, device_t, void *);
|
||||
static void acpi_childdet(device_t, device_t);
|
||||
static int acpi_detach(device_t, int);
|
||||
|
||||
static int acpi_rescan(device_t, const char *, const int *);
|
||||
static void acpi_rescan1(struct acpi_softc *, const char *, const int *);
|
||||
static void acpi_rescan_nodes(struct acpi_softc *);
|
||||
|
||||
static int acpi_print(void *aux, const char *);
|
||||
|
||||
@ -128,7 +133,7 @@ static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS);
|
||||
extern struct cfdriver acpi_cd;
|
||||
|
||||
CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
|
||||
acpi_match, acpi_attach, NULL, NULL, NULL, acpi_childdet);
|
||||
acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
|
||||
|
||||
/*
|
||||
* This is a flag we set when the ACPI subsystem is active. Machine
|
||||
@ -386,6 +391,9 @@ acpi_childdet(device_t self, device_t child)
|
||||
struct acpi_scope *as;
|
||||
struct acpi_devnode *ad;
|
||||
|
||||
if (sc->sc_apmbus == child)
|
||||
sc->sc_apmbus = NULL;
|
||||
|
||||
TAILQ_FOREACH(as, &sc->sc_scopes, as_list) {
|
||||
TAILQ_FOREACH(ad, &as->as_devnodes, ad_list) {
|
||||
if (ad->ad_device == child)
|
||||
@ -525,6 +533,81 @@ acpi_attach(device_t parent, device_t self, void *aux)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_detach(device_t self, int flags)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#ifdef ACPI_DEBUGGER
|
||||
if (acpi_dbgr & ACPI_DBGR_RUNNING)
|
||||
acpi_osd_debugger();
|
||||
#endif
|
||||
|
||||
if ((rc = config_detach_children(self, flags)) != 0)
|
||||
return rc;
|
||||
|
||||
#ifdef ACPI_DEBUGGER
|
||||
if (acpi_dbgr & ACPI_DBGR_PROBE)
|
||||
acpi_osd_debugger();
|
||||
#endif
|
||||
|
||||
if ((rc = acpitimer_detach()) != 0)
|
||||
return rc;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Bring ACPI on-line.
|
||||
*/
|
||||
#ifdef ACPI_DEBUGGER
|
||||
if (acpi_dbgr & ACPI_DBGR_ENABLE)
|
||||
acpi_osd_debugger();
|
||||
#endif
|
||||
|
||||
#define ACPI_ENABLE_PHASE1 \
|
||||
(ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
|
||||
#define ACPI_ENABLE_PHASE2 \
|
||||
(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
|
||||
ACPI_NO_ADDRESS_SPACE_INIT)
|
||||
|
||||
rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
|
||||
if (ACPI_FAILURE(rv)) {
|
||||
aprint_error_dev(self, "unable to enable ACPI: %s\n",
|
||||
AcpiFormatException(rv));
|
||||
return;
|
||||
}
|
||||
|
||||
rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
|
||||
if (ACPI_FAILURE(rv)) {
|
||||
aprint_error_dev(self, "unable to enable ACPI: %s\n",
|
||||
AcpiFormatException(rv));
|
||||
return;
|
||||
}
|
||||
|
||||
/* early EC handler initialization if ECDT table is available */
|
||||
config_found_ia(self, "acpiecdtbus", NULL, NULL);
|
||||
|
||||
rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
|
||||
if (ACPI_FAILURE(rv)) {
|
||||
aprint_error_dev(self,
|
||||
"unable to initialize ACPI objects: %s\n",
|
||||
AcpiFormatException(rv));
|
||||
return;
|
||||
}
|
||||
acpi_active = 1;
|
||||
|
||||
acpi_enable_fixed_events(sc);
|
||||
#endif
|
||||
|
||||
pmf_device_deregister(self);
|
||||
|
||||
#if 0
|
||||
sysmon_power_settype("acpi");
|
||||
#endif
|
||||
acpi_softc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
acpi_suspend(device_t dv PMF_FN_ARGS)
|
||||
{
|
||||
@ -580,10 +663,8 @@ acpi_build_tree(struct acpi_softc *sc)
|
||||
"\\_TZ_", /* ACPI 1.0 thermal zone namespace */
|
||||
NULL,
|
||||
};
|
||||
struct acpi_attach_args aa;
|
||||
struct acpi_make_devnode_state state;
|
||||
struct acpi_scope *as;
|
||||
struct acpi_devnode *ad;
|
||||
ACPI_HANDLE parent;
|
||||
ACPI_STATUS rv;
|
||||
int i;
|
||||
@ -610,9 +691,54 @@ acpi_build_tree(struct acpi_softc *sc)
|
||||
AcpiWalkNamespace(ACPI_TYPE_ANY, parent, 100,
|
||||
acpi_make_devnode, &state, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, for this namespace, try and attach the devices. */
|
||||
acpi_rescan1(sc, NULL, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_rescan(device_t self, const char *ifattr, const int *locators)
|
||||
{
|
||||
struct acpi_softc *sc = device_private(self);
|
||||
|
||||
acpi_rescan1(sc, ifattr, locators);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX share this with sys/arch/i386/pci/elan520.c */
|
||||
static bool
|
||||
ifattr_match(const char *snull, const char *t)
|
||||
{
|
||||
return (snull == NULL) || strcmp(snull, t) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_rescan1(struct acpi_softc *sc, const char *ifattr, const int *locators)
|
||||
{
|
||||
if (ifattr_match(ifattr, "acpinodebus"))
|
||||
acpi_rescan_nodes(sc);
|
||||
|
||||
if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL) {
|
||||
sc->sc_apmbus = config_found_ia(sc->sc_dev, "acpiapmbus", NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_rescan_nodes(struct acpi_softc *sc)
|
||||
{
|
||||
struct acpi_scope *as;
|
||||
|
||||
TAILQ_FOREACH(as, &sc->sc_scopes, as_list) {
|
||||
struct acpi_devnode *ad;
|
||||
|
||||
/* Now, for this namespace, try to attach the devices. */
|
||||
TAILQ_FOREACH(ad, &as->as_devnodes, ad_list) {
|
||||
struct acpi_attach_args aa;
|
||||
|
||||
if (ad->ad_device != NULL)
|
||||
continue;
|
||||
|
||||
aa.aa_node = ad;
|
||||
aa.aa_iot = sc->sc_iot;
|
||||
aa.aa_memt = sc->sc_memt;
|
||||
@ -669,7 +795,6 @@ acpi_build_tree(struct acpi_softc *sc)
|
||||
"acpinodebus", &aa, acpi_print);
|
||||
}
|
||||
}
|
||||
config_found_ia(sc->sc_dev, "acpiapmbus", NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef ACPI_ACTIVATE_DEV
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: acpivar.h,v 1.34 2008/11/17 23:29:49 joerg Exp $ */
|
||||
/* $NetBSD: acpivar.h,v 1.35 2009/04/08 00:23:30 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Wasabi Systems, Inc.
|
||||
@ -136,6 +136,7 @@ struct acpi_softc {
|
||||
* Scopes we manage.
|
||||
*/
|
||||
TAILQ_HEAD(, acpi_scope) sc_scopes;
|
||||
device_t sc_apmbus;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user