1 /* 2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. 3 * <benh@kernel.crashing.org> 4 * and Arnd Bergmann, IBM Corp. 5 * Merged from powerpc/kernel/of_platform.c and 6 * sparc{,64}/kernel/of_device.c by Stephen Rothwell 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 * 13 */ 14 #include <linux/errno.h> 15 #include <linux/module.h> 16 #include <linux/device.h> 17 #include <linux/of_device.h> 18 #include <linux/of_platform.h> 19 20 extern struct device_attribute of_platform_device_attrs[]; 21 22 static int of_platform_bus_match(struct device *dev, struct device_driver *drv) 23 { 24 struct of_device *of_dev = to_of_device(dev); 25 struct of_platform_driver *of_drv = to_of_platform_driver(drv); 26 const struct of_device_id *matches = of_drv->match_table; 27 28 if (!matches) 29 return 0; 30 31 return of_match_device(matches, of_dev) != NULL; 32 } 33 34 static int of_platform_device_probe(struct device *dev) 35 { 36 int error = -ENODEV; 37 struct of_platform_driver *drv; 38 struct of_device *of_dev; 39 const struct of_device_id *match; 40 41 drv = to_of_platform_driver(dev->driver); 42 of_dev = to_of_device(dev); 43 44 if (!drv->probe) 45 return error; 46 47 of_dev_get(of_dev); 48 49 match = of_match_device(drv->match_table, of_dev); 50 if (match) 51 error = drv->probe(of_dev, match); 52 if (error) 53 of_dev_put(of_dev); 54 55 return error; 56 } 57 58 static int of_platform_device_remove(struct device *dev) 59 { 60 struct of_device *of_dev = to_of_device(dev); 61 struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 62 63 if (dev->driver && drv->remove) 64 drv->remove(of_dev); 65 return 0; 66 } 67 68 static void of_platform_device_shutdown(struct device *dev) 69 { 70 struct of_device *of_dev = to_of_device(dev); 71 struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 72 73 if (dev->driver && drv->shutdown) 74 drv->shutdown(of_dev); 75 } 76 77 #ifdef CONFIG_PM_SLEEP 78 79 static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg) 80 { 81 struct of_device *of_dev = to_of_device(dev); 82 struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 83 int ret = 0; 84 85 if (dev->driver && drv->suspend) 86 ret = drv->suspend(of_dev, mesg); 87 return ret; 88 } 89 90 static int of_platform_legacy_resume(struct device *dev) 91 { 92 struct of_device *of_dev = to_of_device(dev); 93 struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 94 int ret = 0; 95 96 if (dev->driver && drv->resume) 97 ret = drv->resume(of_dev); 98 return ret; 99 } 100 101 static int of_platform_pm_prepare(struct device *dev) 102 { 103 struct device_driver *drv = dev->driver; 104 int ret = 0; 105 106 if (drv && drv->pm && drv->pm->prepare) 107 ret = drv->pm->prepare(dev); 108 109 return ret; 110 } 111 112 static void of_platform_pm_complete(struct device *dev) 113 { 114 struct device_driver *drv = dev->driver; 115 116 if (drv && drv->pm && drv->pm->complete) 117 drv->pm->complete(dev); 118 } 119 120 #ifdef CONFIG_SUSPEND 121 122 static int of_platform_pm_suspend(struct device *dev) 123 { 124 struct device_driver *drv = dev->driver; 125 int ret = 0; 126 127 if (!drv) 128 return 0; 129 130 if (drv->pm) { 131 if (drv->pm->suspend) 132 ret = drv->pm->suspend(dev); 133 } else { 134 ret = of_platform_legacy_suspend(dev, PMSG_SUSPEND); 135 } 136 137 return ret; 138 } 139 140 static int of_platform_pm_suspend_noirq(struct device *dev) 141 { 142 struct device_driver *drv = dev->driver; 143 int ret = 0; 144 145 if (!drv) 146 return 0; 147 148 if (drv->pm) { 149 if (drv->pm->suspend_noirq) 150 ret = drv->pm->suspend_noirq(dev); 151 } 152 153 return ret; 154 } 155 156 static int of_platform_pm_resume(struct device *dev) 157 { 158 struct device_driver *drv = dev->driver; 159 int ret = 0; 160 161 if (!drv) 162 return 0; 163 164 if (drv->pm) { 165 if (drv->pm->resume) 166 ret = drv->pm->resume(dev); 167 } else { 168 ret = of_platform_legacy_resume(dev); 169 } 170 171 return ret; 172 } 173 174 static int of_platform_pm_resume_noirq(struct device *dev) 175 { 176 struct device_driver *drv = dev->driver; 177 int ret = 0; 178 179 if (!drv) 180 return 0; 181 182 if (drv->pm) { 183 if (drv->pm->resume_noirq) 184 ret = drv->pm->resume_noirq(dev); 185 } 186 187 return ret; 188 } 189 190 #else /* !CONFIG_SUSPEND */ 191 192 #define of_platform_pm_suspend NULL 193 #define of_platform_pm_resume NULL 194 #define of_platform_pm_suspend_noirq NULL 195 #define of_platform_pm_resume_noirq NULL 196 197 #endif /* !CONFIG_SUSPEND */ 198 199 #ifdef CONFIG_HIBERNATION 200 201 static int of_platform_pm_freeze(struct device *dev) 202 { 203 struct device_driver *drv = dev->driver; 204 int ret = 0; 205 206 if (!drv) 207 return 0; 208 209 if (drv->pm) { 210 if (drv->pm->freeze) 211 ret = drv->pm->freeze(dev); 212 } else { 213 ret = of_platform_legacy_suspend(dev, PMSG_FREEZE); 214 } 215 216 return ret; 217 } 218 219 static int of_platform_pm_freeze_noirq(struct device *dev) 220 { 221 struct device_driver *drv = dev->driver; 222 int ret = 0; 223 224 if (!drv) 225 return 0; 226 227 if (drv->pm) { 228 if (drv->pm->freeze_noirq) 229 ret = drv->pm->freeze_noirq(dev); 230 } 231 232 return ret; 233 } 234 235 static int of_platform_pm_thaw(struct device *dev) 236 { 237 struct device_driver *drv = dev->driver; 238 int ret = 0; 239 240 if (!drv) 241 return 0; 242 243 if (drv->pm) { 244 if (drv->pm->thaw) 245 ret = drv->pm->thaw(dev); 246 } else { 247 ret = of_platform_legacy_resume(dev); 248 } 249 250 return ret; 251 } 252 253 static int of_platform_pm_thaw_noirq(struct device *dev) 254 { 255 struct device_driver *drv = dev->driver; 256 int ret = 0; 257 258 if (!drv) 259 return 0; 260 261 if (drv->pm) { 262 if (drv->pm->thaw_noirq) 263 ret = drv->pm->thaw_noirq(dev); 264 } 265 266 return ret; 267 } 268 269 static int of_platform_pm_poweroff(struct device *dev) 270 { 271 struct device_driver *drv = dev->driver; 272 int ret = 0; 273 274 if (!drv) 275 return 0; 276 277 if (drv->pm) { 278 if (drv->pm->poweroff) 279 ret = drv->pm->poweroff(dev); 280 } else { 281 ret = of_platform_legacy_suspend(dev, PMSG_HIBERNATE); 282 } 283 284 return ret; 285 } 286 287 static int of_platform_pm_poweroff_noirq(struct device *dev) 288 { 289 struct device_driver *drv = dev->driver; 290 int ret = 0; 291 292 if (!drv) 293 return 0; 294 295 if (drv->pm) { 296 if (drv->pm->poweroff_noirq) 297 ret = drv->pm->poweroff_noirq(dev); 298 } 299 300 return ret; 301 } 302 303 static int of_platform_pm_restore(struct device *dev) 304 { 305 struct device_driver *drv = dev->driver; 306 int ret = 0; 307 308 if (!drv) 309 return 0; 310 311 if (drv->pm) { 312 if (drv->pm->restore) 313 ret = drv->pm->restore(dev); 314 } else { 315 ret = of_platform_legacy_resume(dev); 316 } 317 318 return ret; 319 } 320 321 static int of_platform_pm_restore_noirq(struct device *dev) 322 { 323 struct device_driver *drv = dev->driver; 324 int ret = 0; 325 326 if (!drv) 327 return 0; 328 329 if (drv->pm) { 330 if (drv->pm->restore_noirq) 331 ret = drv->pm->restore_noirq(dev); 332 } 333 334 return ret; 335 } 336 337 #else /* !CONFIG_HIBERNATION */ 338 339 #define of_platform_pm_freeze NULL 340 #define of_platform_pm_thaw NULL 341 #define of_platform_pm_poweroff NULL 342 #define of_platform_pm_restore NULL 343 #define of_platform_pm_freeze_noirq NULL 344 #define of_platform_pm_thaw_noirq NULL 345 #define of_platform_pm_poweroff_noirq NULL 346 #define of_platform_pm_restore_noirq NULL 347 348 #endif /* !CONFIG_HIBERNATION */ 349 350 static struct dev_pm_ops of_platform_dev_pm_ops = { 351 .prepare = of_platform_pm_prepare, 352 .complete = of_platform_pm_complete, 353 .suspend = of_platform_pm_suspend, 354 .resume = of_platform_pm_resume, 355 .freeze = of_platform_pm_freeze, 356 .thaw = of_platform_pm_thaw, 357 .poweroff = of_platform_pm_poweroff, 358 .restore = of_platform_pm_restore, 359 .suspend_noirq = of_platform_pm_suspend_noirq, 360 .resume_noirq = of_platform_pm_resume_noirq, 361 .freeze_noirq = of_platform_pm_freeze_noirq, 362 .thaw_noirq = of_platform_pm_thaw_noirq, 363 .poweroff_noirq = of_platform_pm_poweroff_noirq, 364 .restore_noirq = of_platform_pm_restore_noirq, 365 }; 366 367 #define OF_PLATFORM_PM_OPS_PTR (&of_platform_dev_pm_ops) 368 369 #else /* !CONFIG_PM_SLEEP */ 370 371 #define OF_PLATFORM_PM_OPS_PTR NULL 372 373 #endif /* !CONFIG_PM_SLEEP */ 374 375 int of_bus_type_init(struct bus_type *bus, const char *name) 376 { 377 bus->name = name; 378 bus->match = of_platform_bus_match; 379 bus->probe = of_platform_device_probe; 380 bus->remove = of_platform_device_remove; 381 bus->shutdown = of_platform_device_shutdown; 382 bus->dev_attrs = of_platform_device_attrs; 383 bus->pm = OF_PLATFORM_PM_OPS_PTR; 384 return bus_register(bus); 385 } 386 387 int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) 388 { 389 /* initialize common driver fields */ 390 if (!drv->driver.name) 391 drv->driver.name = drv->name; 392 if (!drv->driver.owner) 393 drv->driver.owner = drv->owner; 394 drv->driver.bus = bus; 395 396 /* register with core */ 397 return driver_register(&drv->driver); 398 } 399 EXPORT_SYMBOL(of_register_driver); 400 401 void of_unregister_driver(struct of_platform_driver *drv) 402 { 403 driver_unregister(&drv->driver); 404 } 405 EXPORT_SYMBOL(of_unregister_driver); 406