spec(reimaden): add platform support kernel module
This commit is contained in:
parent
1c95aba389
commit
a23ec8f250
26 changed files with 2071 additions and 0 deletions
101
spec/reimaden/ac71/ec.c
Normal file
101
spec/reimaden/ac71/ec.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "pr.h"
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/compiler_types.h>
|
||||
#include <linux/error-injection.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/wmi.h>
|
||||
|
||||
#include "ec.h"
|
||||
#include "wmi.h"
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
static DECLARE_RWSEM(ec_lock);
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
int __must_check ac71_ec_lock(void)
|
||||
{
|
||||
return down_write_killable(&ec_lock);
|
||||
}
|
||||
|
||||
void ac71_ec_unlock(void)
|
||||
{
|
||||
up_write(&ec_lock);
|
||||
}
|
||||
|
||||
int __must_check ac71_ec_transaction(uint16_t addr, uint16_t data,
|
||||
union ac71_ec_result *result, bool read)
|
||||
{
|
||||
uint8_t buf[] = {
|
||||
addr & 0xFF,
|
||||
addr >> 8,
|
||||
data & 0xFF,
|
||||
data >> 8,
|
||||
0,
|
||||
read ? 1 : 0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
static_assert(ARRAY_SIZE(buf) == 8);
|
||||
|
||||
/* the returned ACPI_TYPE_BUFFER is 40 bytes long for some reason ... */
|
||||
uint8_t output_buf[sizeof(union acpi_object) + 40];
|
||||
|
||||
struct acpi_buffer input = { sizeof(buf), buf },
|
||||
output = { sizeof(output_buf), output_buf };
|
||||
union acpi_object *obj;
|
||||
acpi_status status = AE_OK;
|
||||
int err;
|
||||
|
||||
if (read) err = down_read_killable(&ec_lock);
|
||||
else err = down_write_killable(&ec_lock);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
memset(output_buf, 0, sizeof(output_buf));
|
||||
|
||||
status = wmi_evaluate_method(AC71_WMI_WMBC_GUID, 0,
|
||||
AC71_WMBC_GETSETULONG_ID, &input, &output);
|
||||
|
||||
if (read) up_read(&ec_lock);
|
||||
else up_write(&ec_lock);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
obj = output.pointer;
|
||||
|
||||
if (result) {
|
||||
if (obj && obj->type == ACPI_TYPE_BUFFER && obj->buffer.length >= sizeof(*result)) {
|
||||
memcpy(result, obj->buffer.pointer, sizeof(*result));
|
||||
} else {
|
||||
err = -ENODATA;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
pr_debug(
|
||||
"%s(addr=%#06x, data=%#06x, result=%c, read=%c)"
|
||||
": (%d) [%#010lx] %s"
|
||||
": [%*ph]\n",
|
||||
|
||||
__func__, (unsigned int) addr, (unsigned int) data,
|
||||
result ? 'y' : 'n', read ? 'y' : 'n',
|
||||
err, (unsigned long) status, acpi_format_exception(status),
|
||||
(obj && obj->type == ACPI_TYPE_BUFFER) ?
|
||||
(int) min(sizeof(*result), (size_t) obj->buffer.length) : 0,
|
||||
(obj && obj->type == ACPI_TYPE_BUFFER) ?
|
||||
obj->buffer.pointer : NULL
|
||||
);
|
||||
|
||||
return err;
|
||||
}
|
||||
ALLOW_ERROR_INJECTION(ac71_ec_transaction, ERRNO);
|
Loading…
Add table
Add a link
Reference in a new issue