acpi_bus.h 15.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 *  acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
 *
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  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; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#ifndef __ACPI_BUS_H__
#define __ACPI_BUS_H__

29
#include <linux/device.h>
L
Linus Torvalds 已提交
30 31 32 33 34 35

#include <acpi/acpi.h>

/* TBD: Make dynamic */
#define ACPI_MAX_HANDLES	10
struct acpi_handle_list {
L
Len Brown 已提交
36 37
	u32 count;
	acpi_handle handles[ACPI_MAX_HANDLES];
L
Linus Torvalds 已提交
38 39 40 41
};

/* acpi_utils.h */
acpi_status
L
Len Brown 已提交
42 43
acpi_extract_package(union acpi_object *package,
		     struct acpi_buffer *format, struct acpi_buffer *buffer);
L
Linus Torvalds 已提交
44
acpi_status
L
Len Brown 已提交
45 46
acpi_evaluate_integer(acpi_handle handle,
		      acpi_string pathname,
47
		      struct acpi_object_list *arguments, unsigned long long *data);
L
Linus Torvalds 已提交
48
acpi_status
L
Len Brown 已提交
49 50 51 52
acpi_evaluate_reference(acpi_handle handle,
			acpi_string pathname,
			struct acpi_object_list *arguments,
			struct acpi_handle_list *list);
53 54 55
acpi_status
acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event,
			u32 status_code, struct acpi_buffer *status_buf);
L
Linus Torvalds 已提交
56

M
Matthew Garrett 已提交
57
acpi_status
58
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
L
Len Brown 已提交
59
#ifdef CONFIG_ACPI
L
Linus Torvalds 已提交
60 61 62 63

#include <linux/proc_fs.h>

#define ACPI_BUS_FILE_ROOT	"acpi"
L
Len Brown 已提交
64
extern struct proc_dir_entry *acpi_root_dir;
L
Linus Torvalds 已提交
65 66

enum acpi_bus_removal_type {
L
Len Brown 已提交
67
	ACPI_BUS_REMOVAL_NORMAL = 0,
L
Linus Torvalds 已提交
68 69 70 71 72 73
	ACPI_BUS_REMOVAL_EJECT,
	ACPI_BUS_REMOVAL_SUPRISE,
	ACPI_BUS_REMOVAL_TYPE_COUNT
};

enum acpi_bus_device_type {
L
Len Brown 已提交
74
	ACPI_BUS_TYPE_DEVICE = 0,
L
Linus Torvalds 已提交
75 76 77 78 79 80 81 82 83 84 85
	ACPI_BUS_TYPE_POWER,
	ACPI_BUS_TYPE_PROCESSOR,
	ACPI_BUS_TYPE_THERMAL,
	ACPI_BUS_TYPE_POWER_BUTTON,
	ACPI_BUS_TYPE_SLEEP_BUTTON,
	ACPI_BUS_DEVICE_TYPE_COUNT
};

struct acpi_driver;
struct acpi_device;

86 87 88 89 90 91 92 93 94 95 96 97
/*
 * ACPI Scan Handler
 * -----------------
 */

struct acpi_scan_handler {
	const struct acpi_device_id *ids;
	struct list_head list_node;
	int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
	void (*detach)(struct acpi_device *dev);
};

L
Linus Torvalds 已提交
98 99 100 101 102
/*
 * ACPI Driver
 * -----------
 */

L
Len Brown 已提交
103
typedef int (*acpi_op_add) (struct acpi_device * device);
104
typedef int (*acpi_op_remove) (struct acpi_device * device);
105
typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
L
Linus Torvalds 已提交
106 107

struct acpi_device_ops {
L
Len Brown 已提交
108 109
	acpi_op_add add;
	acpi_op_remove remove;
110
	acpi_op_notify notify;
L
Linus Torvalds 已提交
111 112
};

113 114
#define ACPI_DRIVER_ALL_NOTIFY_EVENTS	0x1	/* system AND device events */

L
Linus Torvalds 已提交
115
struct acpi_driver {
L
Len Brown 已提交
116 117
	char name[80];
	char class[80];
118
	const struct acpi_device_id *ids; /* Supported Hardware IDs */
119
	unsigned int flags;
L
Len Brown 已提交
120
	struct acpi_device_ops ops;
121
	struct device_driver drv;
122
	struct module *owner;
L
Linus Torvalds 已提交
123 124 125 126 127 128 129 130 131 132
};

/*
 * ACPI Device
 * -----------
 */

/* Status (_STA) */

struct acpi_device_status {
L
Len Brown 已提交
133 134 135 136 137 138
	u32 present:1;
	u32 enabled:1;
	u32 show_in_ui:1;
	u32 functional:1;
	u32 battery_present:1;
	u32 reserved:27;
L
Linus Torvalds 已提交
139 140 141 142 143
};

/* Flags */

struct acpi_device_flags {
L
Len Brown 已提交
144 145 146 147 148 149 150
	u32 dynamic_status:1;
	u32 bus_address:1;
	u32 removable:1;
	u32 ejectable:1;
	u32 suprise_removal_ok:1;
	u32 power_manageable:1;
	u32 performance_manageable:1;
151
	u32 eject_pending:1;
152 153
	u32 match_driver:1;
	u32 reserved:23;
L
Linus Torvalds 已提交
154 155 156 157 158
};

/* File System */

struct acpi_device_dir {
L
Len Brown 已提交
159
	struct proc_dir_entry *entry;
L
Linus Torvalds 已提交
160 161 162 163 164 165
};

#define acpi_device_dir(d)	((d)->dir.entry)

/* Plug and Play */

166
typedef char acpi_bus_id[8];
L
Len Brown 已提交
167 168 169
typedef unsigned long acpi_bus_address;
typedef char acpi_device_name[40];
typedef char acpi_device_class[20];
L
Linus Torvalds 已提交
170

171 172 173 174 175
struct acpi_hardware_id {
	struct list_head list;
	char *id;
};

L
Linus Torvalds 已提交
176
struct acpi_device_pnp {
L
Len Brown 已提交
177 178
	acpi_bus_id bus_id;	/* Object name */
	acpi_bus_address bus_address;	/* _ADR */
179
	char *unique_id;	/* _UID */
180
	struct list_head ids;		/* _HID and _CIDs */
L
Len Brown 已提交
181 182
	acpi_device_name device_name;	/* Driver-determined */
	acpi_device_class device_class;	/*        "          */
183
	union acpi_object *str_obj;	/* unicode string for _STR method */
Y
Yasuaki Ishimatsu 已提交
184
	unsigned long sun;		/* _SUN */
L
Linus Torvalds 已提交
185 186 187 188
};

#define acpi_device_bid(d)	((d)->pnp.bus_id)
#define acpi_device_adr(d)	((d)->pnp.bus_address)
189
const char *acpi_device_hid(struct acpi_device *device);
L
Linus Torvalds 已提交
190 191 192 193 194 195
#define acpi_device_name(d)	((d)->pnp.device_name)
#define acpi_device_class(d)	((d)->pnp.device_class)

/* Power Management */

struct acpi_device_power_flags {
L
Len Brown 已提交
196 197 198 199 200
	u32 explicit_get:1;	/* _PSC present? */
	u32 power_resources:1;	/* Power resources */
	u32 inrush_current:1;	/* Serialize Dx->D0 */
	u32 power_removed:1;	/* Optimize Dx->D0 */
	u32 reserved:28;
L
Linus Torvalds 已提交
201 202 203 204
};

struct acpi_device_power_state {
	struct {
L
Len Brown 已提交
205
		u8 valid:1;
206
		u8 os_accessible:1;
L
Len Brown 已提交
207 208 209 210 211
		u8 explicit_set:1;	/* _PSx present? */
		u8 reserved:6;
	} flags;
	int power;		/* % Power (compared to D0) */
	int latency;		/* Dx->D0 time (microseconds) */
212
	struct list_head resources;	/* Power resources referenced */
L
Linus Torvalds 已提交
213 214 215
};

struct acpi_device_power {
L
Len Brown 已提交
216
	int state;		/* Current state */
L
Linus Torvalds 已提交
217
	struct acpi_device_power_flags flags;
218
	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
L
Linus Torvalds 已提交
219 220 221 222 223
};

/* Performance Management */

struct acpi_device_perf_flags {
L
Len Brown 已提交
224
	u8 reserved:8;
L
Linus Torvalds 已提交
225 226 227 228
};

struct acpi_device_perf_state {
	struct {
L
Len Brown 已提交
229 230 231 232 233 234
		u8 valid:1;
		u8 reserved:7;
	} flags;
	u8 power;		/* % Power (compared to P0) */
	u8 performance;		/* % Performance (    "   ) */
	int latency;		/* Px->P0 time (microseconds) */
L
Linus Torvalds 已提交
235 236 237
};

struct acpi_device_perf {
L
Len Brown 已提交
238
	int state;
L
Linus Torvalds 已提交
239
	struct acpi_device_perf_flags flags;
L
Len Brown 已提交
240
	int state_count;
L
Linus Torvalds 已提交
241 242 243 244 245
	struct acpi_device_perf_state *states;
};

/* Wakeup Management */
struct acpi_device_wakeup_flags {
L
Len Brown 已提交
246 247
	u8 valid:1;		/* Can successfully enable wakeup? */
	u8 run_wake:1;		/* Run-Wake GPE devices */
248
	u8 notifier_present:1;  /* Wake-up notify handler has been installed */
L
Linus Torvalds 已提交
249 250 251
};

struct acpi_device_wakeup {
L
Len Brown 已提交
252
	acpi_handle gpe_device;
L
Lin Ming 已提交
253 254
	u64 gpe_number;
	u64 sleep_state;
255
	struct list_head resources;
L
Len Brown 已提交
256
	struct acpi_device_wakeup_flags flags;
257
	int prepare_count;
L
Linus Torvalds 已提交
258 259
};

260 261 262 263 264
struct acpi_device_physical_node {
	u8 node_id;
	struct list_head node;
	struct device *dev;
};
L
Linus Torvalds 已提交
265

266 267
/* set maximum of physical nodes to 32 for expansibility */
#define ACPI_MAX_PHYSICAL_NODE	32
L
Linus Torvalds 已提交
268

269
/* Device */
L
Linus Torvalds 已提交
270
struct acpi_device {
271 272
	int device_type;
	acpi_handle handle;		/* no handle for fixed hardware */
L
Len Brown 已提交
273 274 275 276
	struct acpi_device *parent;
	struct list_head children;
	struct list_head node;
	struct list_head wakeup_list;
L
Linus Torvalds 已提交
277 278
	struct acpi_device_status status;
	struct acpi_device_flags flags;
L
Len Brown 已提交
279
	struct acpi_device_pnp pnp;
L
Linus Torvalds 已提交
280 281
	struct acpi_device_power power;
	struct acpi_device_wakeup wakeup;
L
Len Brown 已提交
282 283
	struct acpi_device_perf performance;
	struct acpi_device_dir dir;
284
	struct acpi_scan_handler *handler;
L
Len Brown 已提交
285 286
	struct acpi_driver *driver;
	void *driver_data;
287
	struct device dev;
L
Len Brown 已提交
288
	enum acpi_bus_removal_type removal_type;	/* indicate for different removal type */
289 290 291 292
	u8 physical_node_count;
	struct list_head physical_node_list;
	struct mutex physical_node_lock;
	DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
293
	struct list_head power_dependent;
294
	void (*remove)(struct acpi_device *);
L
Linus Torvalds 已提交
295 296
};

297 298 299 300 301
static inline void *acpi_driver_data(struct acpi_device *d)
{
	return d->driver_data;
}

302 303
#define to_acpi_device(d)	container_of(d, struct acpi_device, dev)
#define to_acpi_driver(d)	container_of(d, struct acpi_driver, drv)
L
Linus Torvalds 已提交
304

305 306 307
/* acpi_device.dev.bus == &acpi_bus_type */
extern struct bus_type acpi_bus_type;

L
Linus Torvalds 已提交
308 309 310 311 312 313
/*
 * Events
 * ------
 */

struct acpi_bus_event {
L
Len Brown 已提交
314 315 316 317 318
	struct list_head node;
	acpi_device_class device_class;
	acpi_bus_id bus_id;
	u32 type;
	u32 data;
L
Linus Torvalds 已提交
319 320
};

321
struct acpi_eject_event {
322
	struct acpi_device	*device;
323 324 325
	u32		event;
};

326
extern struct kobject *acpi_kobj;
327
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
328
void acpi_bus_private_data_handler(acpi_handle, void *);
Z
Zhang Rui 已提交
329
int acpi_bus_get_private_data(acpi_handle, void **);
330 331 332
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
extern int register_acpi_notifier(struct notifier_block *);
extern int unregister_acpi_notifier(struct notifier_block *);
333 334 335

extern int register_acpi_bus_notifier(struct notifier_block *nb);
extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
L
Linus Torvalds 已提交
336 337 338 339 340
/*
 * External Functions
 */

int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
341
void acpi_bus_data_handler(acpi_handle handle, void *context);
342 343
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
				       unsigned long long *sta);
L
Len Brown 已提交
344
int acpi_bus_get_status(struct acpi_device *device);
345 346

#ifdef CONFIG_PM
L
Len Brown 已提交
347
int acpi_bus_set_power(acpi_handle handle, int state);
348
const char *acpi_power_state_string(int state);
349
int acpi_device_get_power(struct acpi_device *device, int *state);
350
int acpi_device_set_power(struct acpi_device *device, int state);
351
int acpi_bus_init_power(struct acpi_device *device);
352
int acpi_bus_update_power(acpi_handle handle, int *state_p);
353
bool acpi_bus_power_manageable(acpi_handle handle);
354
bool acpi_bus_can_wakeup(acpi_handle handle);
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
#else /* !CONFIG_PM */
static inline int acpi_bus_set_power(acpi_handle handle, int state)
{
	return 0;
}
static inline const char *acpi_power_state_string(int state)
{
	return "D0";
}
static inline int acpi_device_get_power(struct acpi_device *device, int *state)
{
	return 0;
}
static inline int acpi_device_set_power(struct acpi_device *device, int state)
{
	return 0;
}
static inline int acpi_bus_init_power(struct acpi_device *device)
{
	return 0;
}
static inline int acpi_bus_update_power(acpi_handle handle, int *state_p)
{
	return 0;
}
static inline bool acpi_bus_power_manageable(acpi_handle handle)
{
	return false;
}
static inline bool acpi_bus_can_wakeup(acpi_handle handle)
{
	return false;
}
#endif /* !CONFIG_PM */

390 391
#ifdef CONFIG_ACPI_PROC_EVENT
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
392
int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
L
Len Brown 已提交
393
int acpi_bus_receive_event(struct acpi_bus_event *event);
394 395 396 397
#else
static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
	{ return 0; }
#endif
398
int acpi_scan_add_handler(struct acpi_scan_handler *handler);
L
Len Brown 已提交
399
int acpi_bus_register_driver(struct acpi_driver *driver);
400
void acpi_bus_unregister_driver(struct acpi_driver *driver);
401
int acpi_bus_scan(acpi_handle handle);
402
void acpi_bus_hot_remove_device(void *context);
403
void acpi_bus_trim(struct acpi_device *start);
L
Len Brown 已提交
404
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
405 406
int acpi_match_device_ids(struct acpi_device *device,
			  const struct acpi_device_id *ids);
L
Linus Torvalds 已提交
407 408 409
int acpi_create_dir(struct acpi_device *);
void acpi_remove_dir(struct acpi_device *);

410 411 412 413 414 415 416 417 418 419 420 421 422

/**
 * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver
 * @__acpi_driver: acpi_driver struct
 *
 * Helper macro for ACPI drivers which do not do anything special in module
 * init/exit. This eliminates a lot of boilerplate. Each module may only
 * use this macro once, and calling it replaces module_init() and module_exit()
 */
#define module_acpi_driver(__acpi_driver) \
	module_driver(__acpi_driver, acpi_bus_register_driver, \
		      acpi_bus_unregister_driver)

423 424 425 426
/*
 * Bind physical devices with ACPI devices
 */
struct acpi_bus_type {
L
Len Brown 已提交
427 428 429 430
	struct list_head list;
	struct bus_type *bus;
	/* For general devices under the bus */
	int (*find_device) (struct device *, acpi_handle *);
431
	/* For bridges, such as PCI root bridge, IDE controller */
L
Len Brown 已提交
432
	int (*find_bridge) (struct device *, acpi_handle *);
433 434
	void (*setup)(struct device *);
	void (*cleanup)(struct device *);
435 436 437
};
int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *);
438

439 440 441 442 443
struct acpi_pci_root {
	struct list_head node;
	struct acpi_device * device;
	struct pci_bus *bus;
	u16 segment;
444
	struct resource secondary;	/* downstream bus range */
445 446 447

	u32 osc_support_set;	/* _OSC state of support bits */
	u32 osc_control_set;	/* _OSC state of control bits */
448
	phys_addr_t mcfg_addr;
449 450
};

451
/* helper */
L
Lin Ming 已提交
452
acpi_handle acpi_get_child(acpi_handle, u64);
453
int acpi_is_root_bridge(acpi_handle);
454
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
455
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
456
#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
457

458 459 460
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
int acpi_disable_wakeup_device_power(struct acpi_device *dev);

R
Rafael J. Wysocki 已提交
461
#ifdef CONFIG_PM
462 463 464 465
acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
				 acpi_notify_handler handler, void *context);
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
				    acpi_notify_handler handler);
466 467
int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
			    u32 target_state, int d_max_in, int *d_min_p);
468
int acpi_pm_device_sleep_state(struct device *, int *, int);
469 470
void acpi_dev_pm_add_dependent(acpi_handle handle, struct device *depdev);
void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev);
471
#else
472 473 474 475 476 477 478 479 480 481 482
static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
					       acpi_notify_handler handler,
					       void *context)
{
	return AE_SUPPORT;
}
static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
						  acpi_notify_handler handler)
{
	return AE_SUPPORT;
}
483
static inline int __acpi_device_power_state(int m, int *p)
484 485 486
{
	if (p)
		*p = ACPI_STATE_D0;
487
	return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0;
488
}
489 490 491 492 493 494 495 496 497 498 499
static inline int acpi_device_power_state(struct device *dev,
					  struct acpi_device *adev,
					  u32 target_state, int d_max_in,
					  int *d_min_p)
{
	return __acpi_device_power_state(d_max_in, d_min_p);
}
static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
{
	return __acpi_device_power_state(m, p);
}
500 501 502 503
static inline void acpi_dev_pm_add_dependent(acpi_handle handle,
					     struct device *depdev) {}
static inline void acpi_dev_pm_remove_dependent(acpi_handle handle,
						struct device *depdev) {}
504 505
#endif

506
#ifdef CONFIG_PM_RUNTIME
507
int __acpi_device_run_wake(struct acpi_device *, bool);
508
int acpi_pm_device_run_wake(struct device *, bool);
509
#else
510 511 512 513
static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en)
{
	return -ENODEV;
}
514 515 516 517
static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
{
	return -ENODEV;
}
518 519 520
#endif

#ifdef CONFIG_PM_SLEEP
521
int __acpi_device_sleep_wake(struct acpi_device *, u32, bool);
522 523
int acpi_pm_device_sleep_wake(struct device *, bool);
#else
524 525 526 527 528
static inline int __acpi_device_sleep_wake(struct acpi_device *adev,
					   u32 target_state, bool enable)
{
	return -ENODEV;
}
529 530 531 532
static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
{
	return -ENODEV;
}
533
#endif
534

535 536 537 538 539 540
#ifdef CONFIG_ACPI_SLEEP
u32 acpi_target_system_state(void);
#else
static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; }
#endif

541 542 543 544 545 546 547 548 549 550
static inline bool acpi_device_power_manageable(struct acpi_device *adev)
{
	return adev->flags.power_manageable;
}

static inline bool acpi_device_can_wakeup(struct acpi_device *adev)
{
	return adev->wakeup.flags.valid;
}

551 552 553 554 555
static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
{
	return adev->power.states[ACPI_STATE_D3_COLD].flags.os_accessible;
}

556 557
#else	/* CONFIG_ACPI */

558 559
static inline int register_acpi_bus_type(void *bus) { return 0; }
static inline int unregister_acpi_bus_type(void *bus) { return 0; }
560

L
Len Brown 已提交
561
#endif				/* CONFIG_ACPI */
L
Linus Torvalds 已提交
562 563

#endif /*__ACPI_BUS_H__*/