1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

Add status initialization code for acpi_cmbat and acpi_acad,

acpi_cmbat_init_battery() and acpi_cmbat_init_acline() respectively.
Call acpi_cmbat_init_battery() from acpi_cmbat_resume() too just in
case.
This is a workaround for embedded controller operations which is
unstable for about a minute (typically 30 or 40 sec.) at boot time.
This commit is contained in:
Mitsuru IWASAKI 2002-11-03 10:49:24 +00:00
parent 3592796a98
commit 9bb04eb483
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=106377
2 changed files with 120 additions and 7 deletions

View File

@ -59,9 +59,12 @@ static int acpi_acad_probe(device_t);
static int acpi_acad_attach(device_t);
static int acpi_acad_ioctl(u_long, caddr_t, void *);
static int acpi_acad_sysctl(SYSCTL_HANDLER_ARGS);
static void acpi_acad_init_acline(void *arg);
struct acpi_acad_softc {
int status;
int initializing;
};
static void
@ -157,7 +160,9 @@ acpi_acad_attach(device_t dev)
/* Get initial status after whole system is up. */
sc->status = -1;
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_acad_get_status, dev);
sc->initializing = 0;
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_acad_init_acline, dev);
return(0);
}
@ -215,6 +220,37 @@ acpi_acad_sysctl(SYSCTL_HANDLER_ARGS)
return (error);
}
static void
acpi_acad_init_acline(void *arg)
{
int retry;
int status;
device_t dev = (device_t)arg;
struct acpi_acad_softc *sc = device_get_softc(dev);
#define ACPI_ACAD_RETRY_MAX 6
if (sc->initializing) {
return;
}
sc->initializing = 1;
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"acline initialization start\n");
status = 0;
for (retry = 0; retry < ACPI_ACAD_RETRY_MAX; retry++, AcpiOsSleep(10, 0)) {
acpi_acad_get_status(dev);
if (status != sc->status)
break;
}
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"acline initialization done, tried %d times\n", retry+1);
sc->initializing = 0;
}
/*
* Public interfaces.
*/

View File

@ -113,6 +113,7 @@ struct acpi_cmbat_softc {
int cap;
int min;
int full_charge_time;
int initializing;
};
static struct timespec acpi_cmbat_info_lastupdated;
@ -129,7 +130,10 @@ static int acpi_cmbat_probe(device_t);
static int acpi_cmbat_attach(device_t);
static int acpi_cmbat_resume(device_t);
static int acpi_cmbat_ioctl(u_long, caddr_t, void *);
static int acpi_cmbat_is_bst_valid(struct acpi_bst*);
static int acpi_cmbat_is_bif_valid(struct acpi_bif*);
static int acpi_cmbat_get_total_battinfo(struct acpi_battinfo *);
static void acpi_cmbat_init_battery(void *);
static __inline int
acpi_cmbat_info_expired(struct timespec *lastupdated)
@ -350,8 +354,9 @@ acpi_cmbat_attach(device_t dev)
acpi_cmbat_units++;
timespecclear(&acpi_cmbat_info_lastupdated);
sc->initializing = 0;
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_get_bif, dev);
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
return (0);
}
@ -359,7 +364,7 @@ static int
acpi_cmbat_resume(device_t dev)
{
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_get_bif, dev);
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
return (0);
}
@ -435,6 +440,28 @@ acpi_cmbat_ioctl(u_long cmd, caddr_t addr, void *arg)
return (0);
}
static __inline int
acpi_cmbat_is_bst_valid(struct acpi_bst *bst)
{
if (bst->state >= ACPI_BATT_STAT_MAX ||
bst->cap == 0xffffffff ||
bst->volt == 0xffffffff) {
return (0);
}
return (1);
}
static __inline int
acpi_cmbat_is_bif_valid(struct acpi_bif *bif)
{
if (bif->lfcap == 0) {
return (0);
}
return (1);
}
static int
acpi_cmbat_get_total_battinfo(struct acpi_battinfo *battinfo)
{
@ -496,10 +523,8 @@ acpi_cmbat_get_total_battinfo(struct acpi_battinfo *battinfo)
acpi_cmbat_get_bst(bat[i]->dev);
/* If battey not installed, we get strange values */
if (bat[i]->bst.state >= ACPI_BATT_STAT_MAX ||
bat[i]->bst.cap == 0xffffffff ||
bat[i]->bst.volt == 0xffffffff ||
bat[i]->bif.lfcap == 0) {
if (!acpi_cmbat_is_bst_valid(&(bat[i]->bst)) ||
!acpi_cmbat_is_bif_valid(&(bat[i]->bif))) {
bat[i]->present = 0;
continue;
}
@ -580,6 +605,58 @@ acpi_cmbat_get_total_battinfo(struct acpi_battinfo *battinfo)
return (error);
}
static void
acpi_cmbat_init_battery(void *arg)
{
int retry;
device_t dev = (device_t)arg;
struct acpi_cmbat_softc *sc = device_get_softc(dev);
#define ACPI_CMBAT_RETRY_MAX 6
if (sc->initializing) {
return;
}
sc->initializing = 1;
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"battery initialization start\n");
for (retry = 0; retry < ACPI_CMBAT_RETRY_MAX; retry++, AcpiOsSleep(10, 0)) {
sc->present = acpi_BatteryIsPresent(dev);
if (!sc->present) {
continue;
}
timespecclear(&sc->bst_lastupdated);
timespecclear(&sc->bif_lastupdated);
acpi_cmbat_get_bst(dev);
if (!acpi_cmbat_is_bst_valid(&sc->bst)) {
continue;
}
acpi_cmbat_get_bif(dev);
if (!acpi_cmbat_is_bif_valid(&sc->bif)) {
continue;
}
break;
}
if (retry == ACPI_CMBAT_RETRY_MAX)
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"battery initialization failed, giving up\n");
else
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"battery initialization done, tried %d times\n",
retry+1);
sc->initializing = 0;
}
/*
* Public interfaces.
*/