1 /* 2 * Link physical devices with ACPI devices support 3 * 4 * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com> 5 * Copyright (c) 2005 Intel Corp. 6 * 7 * This file is released under the GPLv2. 8 */ 9 #include <linux/init.h> 10 #include <linux/list.h> 11 #include <linux/device.h> 12 #include <linux/rwsem.h> 13 #include <linux/acpi.h> 14 15 #define ACPI_GLUE_DEBUG 0 16 #if ACPI_GLUE_DEBUG 17 #define DBG(x...) printk(PREFIX x) 18 #else 19 #define DBG(x...) do { } while(0) 20 #endif 21 static LIST_HEAD(bus_type_list); 22 static DECLARE_RWSEM(bus_type_sem); 23 24 int register_acpi_bus_type(struct acpi_bus_type *type) 25 { 26 if (acpi_disabled) 27 return -ENODEV; 28 if (type && type->bus && type->find_device) { 29 down_write(&bus_type_sem); 30 list_add_tail(&type->list, &bus_type_list); 31 up_write(&bus_type_sem); 32 printk(KERN_INFO PREFIX "bus type %s registered\n", 33 type->bus->name); 34 return 0; 35 } 36 return -ENODEV; 37 } 38 39 EXPORT_SYMBOL(register_acpi_bus_type); 40 41 int unregister_acpi_bus_type(struct acpi_bus_type *type) 42 { 43 if (acpi_disabled) 44 return 0; 45 if (type) { 46 down_write(&bus_type_sem); 47 list_del_init(&type->list); 48 up_write(&bus_type_sem); 49 printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", 50 type->bus->name); 51 return 0; 52 } 53 return -ENODEV; 54 } 55 56 EXPORT_SYMBOL(unregister_acpi_bus_type); 57 58 static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) 59 { 60 struct acpi_bus_type *tmp, *ret = NULL; 61 62 down_read(&bus_type_sem); 63 list_for_each_entry(tmp, &bus_type_list, list) { 64 if (tmp->bus == type) { 65 ret = tmp; 66 break; 67 } 68 } 69 up_read(&bus_type_sem); 70 return ret; 71 } 72 73 static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) 74 { 75 struct acpi_bus_type *tmp; 76 int ret = -ENODEV; 77 78 down_read(&bus_type_sem); 79 list_for_each_entry(tmp, &bus_type_list, list) { 80 if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) { 81 ret = 0; 82 break; 83 } 84 } 85 up_read(&bus_type_sem); 86 return ret; 87 } 88 89 /* Get device's handler per its address under its parent */ 90 struct acpi_find_child { 91 acpi_handle handle; 92 acpi_integer address; 93 }; 94 95 static acpi_status 96 do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) 97 { 98 acpi_status status; 99 struct acpi_device_info *info; 100 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 101 struct acpi_find_child *find = context; 102 103 status = acpi_get_object_info(handle, &buffer); 104 if (ACPI_SUCCESS(status)) { 105 info = buffer.pointer; 106 if (info->address == find->address) 107 find->handle = handle; 108 kfree(buffer.pointer); 109 } 110 return AE_OK; 111 } 112 113 acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address) 114 { 115 struct acpi_find_child find = { NULL, address }; 116 117 if (!parent) 118 return NULL; 119 acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 120 1, do_acpi_find_child, &find, NULL); 121 return find.handle; 122 } 123 124 EXPORT_SYMBOL(acpi_get_child); 125 126 /* Link ACPI devices with physical devices */ 127 static void acpi_glue_data_handler(acpi_handle handle, 128 u32 function, void *context) 129 { 130 /* we provide an empty handler */ 131 } 132 133 /* Note: a success call will increase reference count by one */ 134 struct device *acpi_get_physical_device(acpi_handle handle) 135 { 136 acpi_status status; 137 struct device *dev; 138 139 status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev); 140 if (ACPI_SUCCESS(status)) 141 return get_device(dev); 142 return NULL; 143 } 144 145 EXPORT_SYMBOL(acpi_get_physical_device); 146 147 static int acpi_bind_one(struct device *dev, acpi_handle handle) 148 { 149 acpi_status status; 150 151 if (dev->archdata.acpi_handle) { 152 printk(KERN_WARNING PREFIX 153 "Drivers changed 'acpi_handle' for %s\n", dev->bus_id); 154 return -EINVAL; 155 } 156 get_device(dev); 157 status = acpi_attach_data(handle, acpi_glue_data_handler, dev); 158 if (ACPI_FAILURE(status)) { 159 put_device(dev); 160 return -EINVAL; 161 } 162 dev->archdata.acpi_handle = handle; 163 164 return 0; 165 } 166 167 static int acpi_unbind_one(struct device *dev) 168 { 169 if (!dev->archdata.acpi_handle) 170 return 0; 171 if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { 172 /* acpi_get_physical_device increase refcnt by one */ 173 put_device(dev); 174 acpi_detach_data(dev->archdata.acpi_handle, 175 acpi_glue_data_handler); 176 dev->archdata.acpi_handle = NULL; 177 /* acpi_bind_one increase refcnt by one */ 178 put_device(dev); 179 } else { 180 printk(KERN_ERR PREFIX 181 "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id); 182 } 183 return 0; 184 } 185 186 static int acpi_platform_notify(struct device *dev) 187 { 188 struct acpi_bus_type *type; 189 acpi_handle handle; 190 int ret = -EINVAL; 191 192 if (!dev->bus || !dev->parent) { 193 /* bridge devices genernally haven't bus or parent */ 194 ret = acpi_find_bridge_device(dev, &handle); 195 goto end; 196 } 197 type = acpi_get_bus_type(dev->bus); 198 if (!type) { 199 DBG("No ACPI bus support for %s\n", dev->bus_id); 200 ret = -EINVAL; 201 goto end; 202 } 203 if ((ret = type->find_device(dev, &handle)) != 0) 204 DBG("Can't get handler for %s\n", dev->bus_id); 205 end: 206 if (!ret) 207 acpi_bind_one(dev, handle); 208 209 #if ACPI_GLUE_DEBUG 210 if (!ret) { 211 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 212 213 acpi_get_name(dev->archdata.acpi_handle, 214 ACPI_FULL_PATHNAME, &buffer); 215 DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); 216 kfree(buffer.pointer); 217 } else 218 DBG("Device %s -> No ACPI support\n", dev->bus_id); 219 #endif 220 221 return ret; 222 } 223 224 static int acpi_platform_notify_remove(struct device *dev) 225 { 226 acpi_unbind_one(dev); 227 return 0; 228 } 229 230 static int __init init_acpi_device_notify(void) 231 { 232 if (acpi_disabled) 233 return 0; 234 if (platform_notify || platform_notify_remove) { 235 printk(KERN_ERR PREFIX "Can't use platform_notify\n"); 236 return 0; 237 } 238 platform_notify = acpi_platform_notify; 239 platform_notify_remove = acpi_platform_notify_remove; 240 return 0; 241 } 242 243 arch_initcall(init_acpi_device_notify); 244 245 246 #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 247 248 #ifdef CONFIG_PM 249 static u32 rtc_handler(void *context) 250 { 251 acpi_clear_event(ACPI_EVENT_RTC); 252 acpi_disable_event(ACPI_EVENT_RTC, 0); 253 return ACPI_INTERRUPT_HANDLED; 254 } 255 256 static inline void rtc_wake_setup(void) 257 { 258 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); 259 } 260 261 static void rtc_wake_on(struct device *dev) 262 { 263 acpi_clear_event(ACPI_EVENT_RTC); 264 acpi_enable_event(ACPI_EVENT_RTC, 0); 265 } 266 267 static void rtc_wake_off(struct device *dev) 268 { 269 acpi_disable_event(ACPI_EVENT_RTC, 0); 270 } 271 #else 272 #define rtc_wake_setup() do{}while(0) 273 #define rtc_wake_on NULL 274 #define rtc_wake_off NULL 275 #endif 276 277 /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find 278 * its device node and pass extra config data. This helps its driver use 279 * capabilities that the now-obsolete mc146818 didn't have, and informs it 280 * that this board's RTC is wakeup-capable (per ACPI spec). 281 */ 282 #include <linux/mc146818rtc.h> 283 284 static struct cmos_rtc_board_info rtc_info; 285 286 287 /* PNP devices are registered in a subsys_initcall(); 288 * ACPI specifies the PNP IDs to use. 289 */ 290 #include <linux/pnp.h> 291 292 static int __init pnp_match(struct device *dev, void *data) 293 { 294 static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", }; 295 struct pnp_dev *pnp = to_pnp_dev(dev); 296 int i; 297 298 for (i = 0; i < ARRAY_SIZE(ids); i++) { 299 if (compare_pnp_id(pnp->id, ids[i]) != 0) 300 return 1; 301 } 302 return 0; 303 } 304 305 static struct device *__init get_rtc_dev(void) 306 { 307 return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); 308 } 309 310 static int __init acpi_rtc_init(void) 311 { 312 struct device *dev = get_rtc_dev(); 313 314 if (dev) { 315 rtc_wake_setup(); 316 rtc_info.wake_on = rtc_wake_on; 317 rtc_info.wake_off = rtc_wake_off; 318 319 /* workaround bug in some ACPI tables */ 320 if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { 321 DBG("bogus FADT month_alarm\n"); 322 acpi_gbl_FADT.month_alarm = 0; 323 } 324 325 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; 326 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; 327 rtc_info.rtc_century = acpi_gbl_FADT.century; 328 329 /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ 330 if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) 331 printk(PREFIX "RTC can wake from S4\n"); 332 333 334 dev->platform_data = &rtc_info; 335 336 /* RTC always wakes from S1/S2/S3, and often S4/STD */ 337 device_init_wakeup(dev, 1); 338 339 put_device(dev); 340 } else 341 DBG("RTC unavailable?\n"); 342 return 0; 343 } 344 /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ 345 fs_initcall(acpi_rtc_init); 346 347 #endif 348