/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Gregoire Sutre.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
static int
fujitsu_hk_detach(device_t self, int flags)
{
struct fujitsu_hk_softc *sc = device_private(self);
int i;
pmf_device_deregister(self);
if (sc->sc_log != NULL)
sysctl_teardown(&sc->sc_log);
acpi_deregister_notify(sc->sc_node);
for (i = 0; i < FUJITSU_HK_PSW_COUNT; i++)
sysmon_pswitch_unregister(&sc->sc_smpsw[i]);
mutex_destroy(&sc->sc_mtx);
return 0;
}
/*
* On the P7120, the backlight needs to be enabled after resume, since the
* laptop wakes up with the backlight off (even if it was on before suspend).
*/
static bool
fujitsu_hk_suspend(device_t self, const pmf_qual_t *qual)
{
struct fujitsu_hk_softc *sc = device_private(self);
if (val == FUJITSU_FUNC_INVALID_ARGS)
return ENODEV;
return 0;
}
/*
* fujitsu_hk_cap:
*
* Returns true if and only if (a) the object handle.path exists and
* (b) this object is a method or has the given type.
*/
static bool
fujitsu_hk_cap(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type)
{
ACPI_HANDLE hdl;
ACPI_OBJECT_TYPE typ;
KASSERT(handle != NULL);
if (ACPI_FAILURE(AcpiGetHandle(handle, path, &hdl)))
return false;
if (ACPI_FAILURE(AcpiGetType(hdl, &typ)))
return false;
if (typ != ACPI_TYPE_METHOD && typ != type)
return false;
return true;
}
/*
* fujitsu_hk_eval_nary_integer:
*
* Evaluate an object that takes as input an arbitrary (possible null)
* number of integer parameters. If res is not NULL, then *res is filled
* with the result of the evaluation, and AE_NULL_OBJECT is returned if
* the evaluation produced no result.
*/
static ACPI_STATUS
fujitsu_hk_eval_nary_integer(ACPI_HANDLE handle, const char *path, const
ACPI_INTEGER *args, uint8_t count, ACPI_INTEGER *res)
{
ACPI_OBJECT_LIST paramlist;
ACPI_OBJECT retobj, objpool[4], *argobjs;
ACPI_BUFFER buf;
ACPI_STATUS rv;
uint8_t i;
/* Require that (args == NULL) if and only if (count == 0). */
KASSERT((args != NULL || count == 0) && (args == NULL || count != 0));
/* The object pool should be large enough for our callers. */
KASSERT(count <= __arraycount(objpool));
if (handle == NULL)
handle = ACPI_ROOT_OBJECT;
/* Convert the given array args into an array of ACPI objects. */
argobjs = objpool;
for (i = 0; i < count; i++) {
argobjs[i].Type = ACPI_TYPE_INTEGER;
argobjs[i].Integer.Value = args[i];
}
/*
* If a return value is expected and desired (i.e. res != NULL),
* then copy the result into *res.
*/
if (res != NULL) {
if (buf.Length == 0)
return AE_NULL_OBJECT;
if (retobj.Type != ACPI_TYPE_INTEGER)
return AE_TYPE;