event.c revision 962ce8ca0604af0c3c5609f7613d4ec5fcfac623
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * event.c - exporting ACPI events via procfs 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/spinlock.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/proc_fs.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/poll.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi_drivers.h> 14864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#include <net/netlink.h> 15864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#include <net/genetlink.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT ACPI_SYSTEM_COMPONENT 18f52fd66d2ea794010c2d7536cf8e6abed0ac4947Len BrownACPI_MODULE_NAME("event"); 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Global vars for handling event proc entry */ 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEFINE_SPINLOCK(acpi_system_event_lock); 224be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownint event_is_open = 0; 234be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownextern struct list_head acpi_bus_event_list; 244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownextern wait_queue_head_t acpi_bus_event_queue; 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 264be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_system_open_event(struct inode *inode, struct file *file) 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28c65ade4dc8b486e8c8b9b0a6399789a5428e2039Pavel Machek spin_lock_irq(&acpi_system_event_lock); 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30c65ade4dc8b486e8c8b9b0a6399789a5428e2039Pavel Machek if (event_is_open) 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_busy; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds event_is_open = 1; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35c65ade4dc8b486e8c8b9b0a6399789a5428e2039Pavel Machek spin_unlock_irq(&acpi_system_event_lock); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 384be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown out_busy: 39c65ade4dc8b486e8c8b9b0a6399789a5428e2039Pavel Machek spin_unlock_irq(&acpi_system_event_lock); 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_system_read_event(struct file *file, char __user * buffer, size_t count, 454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown loff_t * ppos) 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 474be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown int result = 0; 484be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_bus_event event; 494be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown static char str[ACPI_MAX_STRING]; 504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown static int chars_remaining = 0; 514be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown static char *ptr; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chars_remaining) { 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&event, 0, sizeof(struct acpi_bus_event)); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_NONBLOCK) 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (list_empty(&acpi_bus_event_list))) 58d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EAGAIN; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_bus_receive_event(&event); 615cc9eeef9a9567acdfc2f6943f24381bf460f008Pavel Machek if (result) 62d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return result; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 644be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown chars_remaining = sprintf(str, "%s %s %08x %08x\n", 654be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown event.device_class ? event. 664be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown device_class : "<unknown>", 674be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown event.bus_id ? event. 684be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown bus_id : "<unknown>", event.type, 694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown event.data); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = str; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chars_remaining < count) { 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = chars_remaining; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_to_user(buffer, ptr, count)) 78d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EFAULT; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ppos += count; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chars_remaining -= count; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr += count; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 84d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return count; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 874be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_system_close_event(struct inode *inode, struct file *file) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown spin_lock_irq(&acpi_system_event_lock); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds event_is_open = 0; 914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown spin_unlock_irq(&acpi_system_event_lock); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 954be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic unsigned int acpi_system_poll_event(struct file *file, poll_table * wait) 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &acpi_bus_event_queue, wait); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!list_empty(&acpi_bus_event_list)) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return POLLIN | POLLRDNORM; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 103d75080328affb4b268da430b7074cc8139cc662aArjan van de Venstatic const struct file_operations acpi_system_event_ops = { 1044be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .open = acpi_system_open_event, 1054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .read = acpi_system_read_event, 1064be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .release = acpi_system_close_event, 1074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .poll = acpi_system_poll_event, 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 110864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#ifdef CONFIG_NET 111e13d87473284131a7ead8121d5d29345101f68a4Adrian Bunkstatic unsigned int acpi_event_seqnum; 112864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruistruct acpi_genl_event { 113864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui acpi_device_class device_class; 114864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui char bus_id[15]; 115864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui u32 type; 116864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui u32 data; 117864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui}; 118864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 119864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui/* attributes of acpi_genl_family */ 120864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruienum { 121864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui ACPI_GENL_ATTR_UNSPEC, 122864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */ 123864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui __ACPI_GENL_ATTR_MAX, 124864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui}; 125864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1) 126864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 127864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui/* commands supported by the acpi_genl_family */ 128864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruienum { 129864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui ACPI_GENL_CMD_UNSPEC, 130864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */ 131864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui __ACPI_GENL_CMD_MAX, 132864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui}; 133864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1) 134864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 1359c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui#define ACPI_GENL_FAMILY_NAME "acpi_event" 1369c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui#define ACPI_GENL_VERSION 0x01 1379c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group" 138864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 139864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruistatic struct genl_family acpi_event_genl_family = { 140864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui .id = GENL_ID_GENERATE, 1419c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui .name = ACPI_GENL_FAMILY_NAME, 142864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui .version = ACPI_GENL_VERSION, 143864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui .maxattr = ACPI_GENL_ATTR_MAX, 144864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui}; 145864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 1469c977a453ed62396d067b75f3f272b3fb1ea3accZhang Ruistatic struct genl_multicast_group acpi_event_mcgrp = { 1479c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui .name = ACPI_GENL_MCAST_GROUP_NAME, 148864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui}; 149864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 150962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Ruiint acpi_bus_generate_netlink_event(const char *device_class, 151962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui const char *bus_id, 152864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui u8 type, int data) 153864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui{ 154864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui struct sk_buff *skb; 155864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui struct nlattr *attr; 156864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui struct acpi_genl_event *event; 157864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui void *msg_header; 158864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui int size; 159864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui int result; 160864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 161864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui /* allocate memory */ 162864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui size = nla_total_size(sizeof(struct acpi_genl_event)) + 163864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui nla_total_size(0); 164864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 165864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui skb = genlmsg_new(size, GFP_ATOMIC); 166864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (!skb) 167864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return -ENOMEM; 168864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 169864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui /* add the genetlink message header */ 170864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++, 171864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui &acpi_event_genl_family, 0, 172864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui ACPI_GENL_CMD_EVENT); 173864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (!msg_header) { 174864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui nlmsg_free(skb); 175864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return -ENOMEM; 176864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui } 177864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 178864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui /* fill the data */ 179864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui attr = 180864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui nla_reserve(skb, ACPI_GENL_ATTR_EVENT, 181864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui sizeof(struct acpi_genl_event)); 182864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (!attr) { 183864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui nlmsg_free(skb); 184864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return -EINVAL; 185864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui } 186864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 187864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui event = nla_data(attr); 188864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (!event) { 189864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui nlmsg_free(skb); 190864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return -EINVAL; 191864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui } 192864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 193864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui memset(event, 0, sizeof(struct acpi_genl_event)); 194864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 195962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui strcpy(event->device_class, device_class); 196962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui strcpy(event->bus_id, bus_id); 197864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui event->type = type; 198864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui event->data = data; 199864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 200864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui /* send multicast genetlink message */ 201864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui result = genlmsg_end(skb, msg_header); 202864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (result < 0) { 203864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui nlmsg_free(skb); 204864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return result; 205864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui } 206864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 207864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui result = 2089c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC); 209864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (result) 210864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui ACPI_DEBUG_PRINT((ACPI_DB_INFO, 211864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui "Failed to send a Genetlink message!\n")); 212864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return 0; 213864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui} 214864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 215962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang RuiEXPORT_SYMBOL(acpi_bus_generate_netlink_event); 216962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui 217864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruistatic int acpi_event_genetlink_init(void) 218864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui{ 219864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui int result; 220864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 221864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui result = genl_register_family(&acpi_event_genl_family); 222864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (result) 223864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return result; 224864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 2259c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui result = genl_register_mc_group(&acpi_event_genl_family, 2269c977a453ed62396d067b75f3f272b3fb1ea3accZhang Rui &acpi_event_mcgrp); 227864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (result) 228864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui genl_unregister_family(&acpi_event_genl_family); 229864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 230864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return result; 231864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui} 232864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 233864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#else 234962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Ruiint acpi_bus_generate_netlink_event(struct acpi_device *device, u8 type, 235864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui int data) 236864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui{ 237864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return 0; 238864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui} 239864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 240962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang RuiEXPORT_SYMBOL(acpi_generate_netlink_event); 241962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui 242864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruistatic int acpi_event_genetlink_init(void) 243864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui{ 244864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return -ENODEV; 245864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui} 246864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui#endif 247864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init acpi_event_init(void) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct proc_dir_entry *entry; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_disabled) 254d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 256864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui /* create genetlink for acpi event */ 257864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui error = acpi_event_genetlink_init(); 258864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui if (error) 259864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui printk(KERN_WARNING PREFIX 260864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui "Failed to create genetlink family for ACPI event\n"); 261864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 'event' [R] */ 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (entry) 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry->proc_fops = &acpi_system_event_ops; 266864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui else 267864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return -ENODEV; 268864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui 269864bdfb912e372670b5b2541dac9d273a4a7722aZhang Rui return 0; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 272864bdfb912e372670b5b2541dac9d273a4a7722aZhang Ruifs_initcall(acpi_event_init); 273