Pull battery-sbs-ac into release branch
This commit is contained in:
commit
e270051d9c
10 changed files with 1378 additions and 1963 deletions
|
@ -88,7 +88,7 @@ config ACPI_PROC_EVENT
|
|||
|
||||
config ACPI_AC
|
||||
tristate "AC Adapter"
|
||||
depends on X86
|
||||
depends on X86 && POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
This driver adds support for the AC Adapter object, which indicates
|
||||
|
@ -97,7 +97,7 @@ config ACPI_AC
|
|||
|
||||
config ACPI_BATTERY
|
||||
tristate "Battery"
|
||||
depends on X86
|
||||
depends on X86 && POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
This driver adds support for battery information through
|
||||
|
@ -350,12 +350,11 @@ config ACPI_HOTPLUG_MEMORY
|
|||
$>modprobe acpi_memhotplug
|
||||
|
||||
config ACPI_SBS
|
||||
tristate "Smart Battery System (EXPERIMENTAL)"
|
||||
tristate "Smart Battery System"
|
||||
depends on X86
|
||||
depends on EXPERIMENTAL
|
||||
depends on POWER_SUPPLY
|
||||
help
|
||||
This driver adds support for the Smart Battery System.
|
||||
A "Smart Battery" is quite old and quite rare compared
|
||||
to today's ACPI "Control Method" battery.
|
||||
This driver adds support for the Smart Battery System, another
|
||||
type of access to battery information, found on some laptops.
|
||||
|
||||
endif # ACPI
|
||||
|
|
|
@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
|
|||
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
|
||||
obj-y += cm_sbs.o
|
||||
obj-$(CONFIG_ACPI_SBS) += sbs.o
|
||||
obj-$(CONFIG_ACPI_SBS) += sbshc.o
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
|
@ -72,16 +73,37 @@ static struct acpi_driver acpi_ac_driver = {
|
|||
};
|
||||
|
||||
struct acpi_ac {
|
||||
struct power_supply charger;
|
||||
struct acpi_device * device;
|
||||
unsigned long state;
|
||||
};
|
||||
|
||||
#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
|
||||
|
||||
static const struct file_operations acpi_ac_fops = {
|
||||
.open = acpi_ac_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
static int get_ac_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct acpi_ac *ac = to_acpi_ac(psy);
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
val->intval = ac->state;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum power_supply_property ac_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
AC Adapter Management
|
||||
|
@ -208,6 +230,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
|
|||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
device->dev.bus_id, event,
|
||||
(u32) ac->state);
|
||||
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
|
||||
break;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
|
@ -244,7 +267,12 @@ static int acpi_ac_add(struct acpi_device *device)
|
|||
result = acpi_ac_add_fs(device);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
ac->charger.name = acpi_device_bid(device);
|
||||
ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
|
||||
ac->charger.properties = ac_props;
|
||||
ac->charger.num_properties = ARRAY_SIZE(ac_props);
|
||||
ac->charger.get_property = get_ac_property;
|
||||
power_supply_register(&ac->device->dev, &ac->charger);
|
||||
status = acpi_install_notify_handler(device->handle,
|
||||
ACPI_ALL_NOTIFY, acpi_ac_notify,
|
||||
ac);
|
||||
|
@ -279,7 +307,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
|
|||
|
||||
status = acpi_remove_notify_handler(device->handle,
|
||||
ACPI_ALL_NOTIFY, acpi_ac_notify);
|
||||
|
||||
if (ac->charger.dev)
|
||||
power_supply_unregister(&ac->charger);
|
||||
acpi_ac_remove_fs(device);
|
||||
|
||||
kfree(ac);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -284,15 +284,11 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
|
|||
|
||||
extern int event_is_open;
|
||||
|
||||
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
|
||||
int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
|
||||
{
|
||||
struct acpi_bus_event *event = NULL;
|
||||
struct acpi_bus_event *event;
|
||||
unsigned long flags = 0;
|
||||
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
/* drop event on the floor if no one's listening */
|
||||
if (!event_is_open)
|
||||
return 0;
|
||||
|
@ -301,8 +297,8 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
|
|||
if (!event)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(event->device_class, device->pnp.device_class);
|
||||
strcpy(event->bus_id, device->pnp.bus_id);
|
||||
strcpy(event->device_class, device_class);
|
||||
strcpy(event->bus_id, bus_id);
|
||||
event->type = type;
|
||||
event->data = data;
|
||||
|
||||
|
@ -313,6 +309,17 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
|
|||
wake_up_interruptible(&acpi_bus_event_queue);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
|
||||
|
||||
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
|
||||
{
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
return acpi_bus_generate_proc_event4(device->pnp.device_class,
|
||||
device->pnp.bus_id, type, data);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_bus_generate_proc_event);
|
||||
|
|
|
@ -425,7 +425,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
|
|||
handler->func = func;
|
||||
handler->data = data;
|
||||
mutex_lock(&ec->lock);
|
||||
list_add_tail(&handler->node, &ec->list);
|
||||
list_add(&handler->node, &ec->list);
|
||||
mutex_unlock(&ec->lock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -440,7 +440,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
|
|||
if (query_bit == handler->query_bit) {
|
||||
list_del(&handler->node);
|
||||
kfree(handler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ec->lock);
|
||||
|
|
1901
drivers/acpi/sbs.c
1901
drivers/acpi/sbs.c
File diff suppressed because it is too large
Load diff
309
drivers/acpi/sbshc.c
Normal file
309
drivers/acpi/sbshc.c
Normal file
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* SMBus driver for ACPI Embedded Controller (v0.1)
|
||||
*
|
||||
* Copyright (c) 2007 Alexey Starikovskiy
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation version 2.
|
||||
*/
|
||||
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <acpi/actypes.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include "sbshc.h"
|
||||
|
||||
#define ACPI_SMB_HC_CLASS "smbus_host_controller"
|
||||
#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC"
|
||||
|
||||
struct acpi_smb_hc {
|
||||
struct acpi_ec *ec;
|
||||
struct mutex lock;
|
||||
wait_queue_head_t wait;
|
||||
u8 offset;
|
||||
u8 query_bit;
|
||||
smbus_alarm_callback callback;
|
||||
void *context;
|
||||
};
|
||||
|
||||
static int acpi_smbus_hc_add(struct acpi_device *device);
|
||||
static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
|
||||
|
||||
static const struct acpi_device_id sbs_device_ids[] = {
|
||||
{"ACPI0001", 0},
|
||||
{"ACPI0005", 0},
|
||||
{"", 0},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
|
||||
|
||||
static struct acpi_driver acpi_smb_hc_driver = {
|
||||
.name = "smbus_hc",
|
||||
.class = ACPI_SMB_HC_CLASS,
|
||||
.ids = sbs_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_smbus_hc_add,
|
||||
.remove = acpi_smbus_hc_remove,
|
||||
},
|
||||
};
|
||||
|
||||
union acpi_smb_status {
|
||||
u8 raw;
|
||||
struct {
|
||||
u8 status:5;
|
||||
u8 reserved:1;
|
||||
u8 alarm:1;
|
||||
u8 done:1;
|
||||
} fields;
|
||||
};
|
||||
|
||||
enum acpi_smb_status_codes {
|
||||
SMBUS_OK = 0,
|
||||
SMBUS_UNKNOWN_FAILURE = 0x07,
|
||||
SMBUS_DEVICE_ADDRESS_NACK = 0x10,
|
||||
SMBUS_DEVICE_ERROR = 0x11,
|
||||
SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
|
||||
SMBUS_UNKNOWN_ERROR = 0x13,
|
||||
SMBUS_DEVICE_ACCESS_DENIED = 0x17,
|
||||
SMBUS_TIMEOUT = 0x18,
|
||||
SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
|
||||
SMBUS_BUSY = 0x1a,
|
||||
SMBUS_PEC_ERROR = 0x1f,
|
||||
};
|
||||
|
||||
enum acpi_smb_offset {
|
||||
ACPI_SMB_PROTOCOL = 0, /* protocol, PEC */
|
||||
ACPI_SMB_STATUS = 1, /* status */
|
||||
ACPI_SMB_ADDRESS = 2, /* address */
|
||||
ACPI_SMB_COMMAND = 3, /* command */
|
||||
ACPI_SMB_DATA = 4, /* 32 data registers */
|
||||
ACPI_SMB_BLOCK_COUNT = 0x24, /* number of data bytes */
|
||||
ACPI_SMB_ALARM_ADDRESS = 0x25, /* alarm address */
|
||||
ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
|
||||
};
|
||||
|
||||
static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
|
||||
{
|
||||
return ec_read(hc->offset + address, data);
|
||||
}
|
||||
|
||||
static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
|
||||
{
|
||||
return ec_write(hc->offset + address, data);
|
||||
}
|
||||
|
||||
static inline int smb_check_done(struct acpi_smb_hc *hc)
|
||||
{
|
||||
union acpi_smb_status status = {.raw = 0};
|
||||
smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
|
||||
return status.fields.done && (status.fields.status == SMBUS_OK);
|
||||
}
|
||||
|
||||
static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
|
||||
{
|
||||
if (wait_event_timeout(hc->wait, smb_check_done(hc),
|
||||
msecs_to_jiffies(timeout)))
|
||||
return 0;
|
||||
else
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
|
||||
u8 command, u8 *data, u8 length)
|
||||
{
|
||||
int ret = -EFAULT, i;
|
||||
u8 temp, sz = 0;
|
||||
|
||||
mutex_lock(&hc->lock);
|
||||
if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
|
||||
goto end;
|
||||
if (temp) {
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
smb_hc_write(hc, ACPI_SMB_COMMAND, command);
|
||||
smb_hc_write(hc, ACPI_SMB_COMMAND, command);
|
||||
if (!(protocol & 0x01)) {
|
||||
smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
|
||||
for (i = 0; i < length; ++i)
|
||||
smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
|
||||
}
|
||||
smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
|
||||
smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
|
||||
/*
|
||||
* Wait for completion. Save the status code, data size,
|
||||
* and data into the return package (if required by the protocol).
|
||||
*/
|
||||
ret = wait_transaction_complete(hc, 1000);
|
||||
if (ret || !(protocol & 0x01))
|
||||
goto end;
|
||||
switch (protocol) {
|
||||
case SMBUS_RECEIVE_BYTE:
|
||||
case SMBUS_READ_BYTE:
|
||||
sz = 1;
|
||||
break;
|
||||
case SMBUS_READ_WORD:
|
||||
sz = 2;
|
||||
break;
|
||||
case SMBUS_READ_BLOCK:
|
||||
if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
|
||||
ret = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
sz &= 0x1f;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < sz; ++i)
|
||||
smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
|
||||
end:
|
||||
mutex_unlock(&hc->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
|
||||
u8 command, u8 *data)
|
||||
{
|
||||
return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_smbus_read);
|
||||
|
||||
int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
|
||||
u8 command, u8 *data, u8 length)
|
||||
{
|
||||
return acpi_smbus_transaction(hc, protocol, address, command, data, length);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_smbus_write);
|
||||
|
||||
int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
|
||||
smbus_alarm_callback callback, void *context)
|
||||
{
|
||||
mutex_lock(&hc->lock);
|
||||
hc->callback = callback;
|
||||
hc->context = context;
|
||||
mutex_unlock(&hc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
|
||||
|
||||
int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
|
||||
{
|
||||
mutex_lock(&hc->lock);
|
||||
hc->callback = NULL;
|
||||
hc->context = NULL;
|
||||
mutex_unlock(&hc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
|
||||
|
||||
static void acpi_smbus_callback(void *context)
|
||||
{
|
||||
struct acpi_smb_hc *hc = context;
|
||||
|
||||
if (hc->callback)
|
||||
hc->callback(hc->context);
|
||||
}
|
||||
|
||||
static int smbus_alarm(void *context)
|
||||
{
|
||||
struct acpi_smb_hc *hc = context;
|
||||
union acpi_smb_status status;
|
||||
if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
|
||||
return 0;
|
||||
/* Check if it is only a completion notify */
|
||||
if (status.fields.done)
|
||||
wake_up(&hc->wait);
|
||||
if (!status.fields.alarm)
|
||||
return 0;
|
||||
mutex_lock(&hc->lock);
|
||||
smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
|
||||
if (hc->callback)
|
||||
acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
|
||||
mutex_unlock(&hc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*acpi_ec_query_func) (void *data);
|
||||
|
||||
extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
|
||||
acpi_handle handle, acpi_ec_query_func func,
|
||||
void *data);
|
||||
|
||||
static int acpi_smbus_hc_add(struct acpi_device *device)
|
||||
{
|
||||
int status;
|
||||
unsigned long val;
|
||||
struct acpi_smb_hc *hc;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_ERR PREFIX "error obtaining _EC.\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
|
||||
|
||||
hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
|
||||
if (!hc)
|
||||
return -ENOMEM;
|
||||
mutex_init(&hc->lock);
|
||||
init_waitqueue_head(&hc->wait);
|
||||
|
||||
hc->ec = acpi_driver_data(device->parent);
|
||||
hc->offset = (val >> 8) & 0xff;
|
||||
hc->query_bit = val & 0xff;
|
||||
acpi_driver_data(device) = hc;
|
||||
|
||||
acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
|
||||
printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
|
||||
hc->ec, hc->offset, hc->query_bit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
|
||||
|
||||
static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_smb_hc *hc;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
hc = acpi_driver_data(device);
|
||||
acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
|
||||
kfree(hc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init acpi_smb_hc_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_smb_hc_driver);
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_smb_hc_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_smb_hc_driver);
|
||||
}
|
||||
|
||||
module_init(acpi_smb_hc_init);
|
||||
module_exit(acpi_smb_hc_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Alexey Starikovskiy");
|
||||
MODULE_DESCRIPTION("ACPI SMBus HC driver");
|
27
drivers/acpi/sbshc.h
Normal file
27
drivers/acpi/sbshc.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
struct acpi_smb_hc;
|
||||
enum acpi_smb_protocol {
|
||||
SMBUS_WRITE_QUICK = 2,
|
||||
SMBUS_READ_QUICK = 3,
|
||||
SMBUS_SEND_BYTE = 4,
|
||||
SMBUS_RECEIVE_BYTE = 5,
|
||||
SMBUS_WRITE_BYTE = 6,
|
||||
SMBUS_READ_BYTE = 7,
|
||||
SMBUS_WRITE_WORD = 8,
|
||||
SMBUS_READ_WORD = 9,
|
||||
SMBUS_WRITE_BLOCK = 0xa,
|
||||
SMBUS_READ_BLOCK = 0xb,
|
||||
SMBUS_PROCESS_CALL = 0xc,
|
||||
SMBUS_BLOCK_PROCESS_CALL = 0xd,
|
||||
};
|
||||
|
||||
static const u8 SMBUS_PEC = 0x80;
|
||||
|
||||
typedef void (*smbus_alarm_callback)(void *context);
|
||||
|
||||
extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
|
||||
u8 command, u8 * data);
|
||||
extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
|
||||
u8 command, u8 * data, u8 length);
|
||||
extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
|
||||
smbus_alarm_callback callback, void *context);
|
||||
extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);
|
|
@ -333,6 +333,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state);
|
|||
int acpi_bus_set_power(acpi_handle handle, int state);
|
||||
#ifdef CONFIG_ACPI_PROC_EVENT
|
||||
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
|
||||
int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
|
||||
int acpi_bus_receive_event(struct acpi_bus_event *event);
|
||||
#else
|
||||
static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
|
||||
|
|
Loading…
Reference in a new issue