13f23de10SStephen Rothwell /* 23f23de10SStephen Rothwell * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. 33f23de10SStephen Rothwell * <benh@kernel.crashing.org> 43f23de10SStephen Rothwell * and Arnd Bergmann, IBM Corp. 53f23de10SStephen Rothwell * Merged from powerpc/kernel/of_platform.c and 63f23de10SStephen Rothwell * sparc{,64}/kernel/of_device.c by Stephen Rothwell 73f23de10SStephen Rothwell * 83f23de10SStephen Rothwell * This program is free software; you can redistribute it and/or 93f23de10SStephen Rothwell * modify it under the terms of the GNU General Public License 103f23de10SStephen Rothwell * as published by the Free Software Foundation; either version 113f23de10SStephen Rothwell * 2 of the License, or (at your option) any later version. 123f23de10SStephen Rothwell * 133f23de10SStephen Rothwell */ 143f23de10SStephen Rothwell #include <linux/errno.h> 155c457083SStephen Rothwell #include <linux/module.h> 163f23de10SStephen Rothwell #include <linux/device.h> 175fd200f3SGrant Likely #include <linux/dma-mapping.h> 1850ef5284SGrant Likely #include <linux/slab.h> 199e3288dcSGrant Likely #include <linux/of_address.h> 203f23de10SStephen Rothwell #include <linux/of_device.h> 219e3288dcSGrant Likely #include <linux/of_irq.h> 223f23de10SStephen Rothwell #include <linux/of_platform.h> 23eca39301SGrant Likely #include <linux/platform_device.h> 24eca39301SGrant Likely 25eca39301SGrant Likely static int platform_driver_probe_shim(struct platform_device *pdev) 26eca39301SGrant Likely { 27eca39301SGrant Likely struct platform_driver *pdrv; 28eca39301SGrant Likely struct of_platform_driver *ofpdrv; 29eca39301SGrant Likely const struct of_device_id *match; 30eca39301SGrant Likely 31eca39301SGrant Likely pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); 32eca39301SGrant Likely ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); 33c1b6d380SGrant Likely 34c1b6d380SGrant Likely /* There is an unlikely chance that an of_platform driver might match 35c1b6d380SGrant Likely * on a non-OF platform device. If so, then of_match_device() will 36c1b6d380SGrant Likely * come up empty. Return -EINVAL in this case so other drivers get 37c1b6d380SGrant Likely * the chance to bind. */ 38eca39301SGrant Likely match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); 39c1b6d380SGrant Likely return match ? ofpdrv->probe(pdev, match) : -EINVAL; 40eca39301SGrant Likely } 41eca39301SGrant Likely 42eca39301SGrant Likely static void platform_driver_shutdown_shim(struct platform_device *pdev) 43eca39301SGrant Likely { 44eca39301SGrant Likely struct platform_driver *pdrv; 45eca39301SGrant Likely struct of_platform_driver *ofpdrv; 46eca39301SGrant Likely 47eca39301SGrant Likely pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); 48eca39301SGrant Likely ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); 49eca39301SGrant Likely ofpdrv->shutdown(pdev); 50eca39301SGrant Likely } 51eca39301SGrant Likely 52eca39301SGrant Likely /** 53eca39301SGrant Likely * of_register_platform_driver 54eca39301SGrant Likely */ 55eca39301SGrant Likely int of_register_platform_driver(struct of_platform_driver *drv) 56eca39301SGrant Likely { 57eca39301SGrant Likely /* setup of_platform_driver to platform_driver adaptors */ 58eca39301SGrant Likely drv->platform_driver.driver = drv->driver; 59eca39301SGrant Likely if (drv->probe) 60eca39301SGrant Likely drv->platform_driver.probe = platform_driver_probe_shim; 61eca39301SGrant Likely drv->platform_driver.remove = drv->remove; 62eca39301SGrant Likely if (drv->shutdown) 63eca39301SGrant Likely drv->platform_driver.shutdown = platform_driver_shutdown_shim; 64eca39301SGrant Likely drv->platform_driver.suspend = drv->suspend; 65eca39301SGrant Likely drv->platform_driver.resume = drv->resume; 66eca39301SGrant Likely 67eca39301SGrant Likely return platform_driver_register(&drv->platform_driver); 68eca39301SGrant Likely } 69eca39301SGrant Likely EXPORT_SYMBOL(of_register_platform_driver); 70eca39301SGrant Likely 71eca39301SGrant Likely void of_unregister_platform_driver(struct of_platform_driver *drv) 72eca39301SGrant Likely { 73eca39301SGrant Likely platform_driver_unregister(&drv->platform_driver); 74eca39301SGrant Likely } 75eca39301SGrant Likely EXPORT_SYMBOL(of_unregister_platform_driver); 763f23de10SStephen Rothwell 77596c955cSGrant Likely #if defined(CONFIG_PPC_DCR) 78596c955cSGrant Likely #include <asm/dcr.h> 79596c955cSGrant Likely #endif 80596c955cSGrant Likely 81140b932fSOlaf Hering extern struct device_attribute of_platform_device_attrs[]; 82140b932fSOlaf Hering 833f23de10SStephen Rothwell static int of_platform_bus_match(struct device *dev, struct device_driver *drv) 843f23de10SStephen Rothwell { 85597b9d1eSGrant Likely const struct of_device_id *matches = drv->of_match_table; 863f23de10SStephen Rothwell 873f23de10SStephen Rothwell if (!matches) 883f23de10SStephen Rothwell return 0; 893f23de10SStephen Rothwell 9044504b2bSGrant Likely return of_match_device(matches, dev) != NULL; 913f23de10SStephen Rothwell } 923f23de10SStephen Rothwell 933f23de10SStephen Rothwell static int of_platform_device_probe(struct device *dev) 943f23de10SStephen Rothwell { 953f23de10SStephen Rothwell int error = -ENODEV; 963f23de10SStephen Rothwell struct of_platform_driver *drv; 97*94a0cb1fSGrant Likely struct platform_device *of_dev; 983f23de10SStephen Rothwell const struct of_device_id *match; 993f23de10SStephen Rothwell 1003f23de10SStephen Rothwell drv = to_of_platform_driver(dev->driver); 101*94a0cb1fSGrant Likely of_dev = to_platform_device(dev); 1023f23de10SStephen Rothwell 1033f23de10SStephen Rothwell if (!drv->probe) 1043f23de10SStephen Rothwell return error; 1053f23de10SStephen Rothwell 1063f23de10SStephen Rothwell of_dev_get(of_dev); 1073f23de10SStephen Rothwell 10844504b2bSGrant Likely match = of_match_device(drv->driver.of_match_table, dev); 1093f23de10SStephen Rothwell if (match) 1103f23de10SStephen Rothwell error = drv->probe(of_dev, match); 1113f23de10SStephen Rothwell if (error) 1123f23de10SStephen Rothwell of_dev_put(of_dev); 1133f23de10SStephen Rothwell 1143f23de10SStephen Rothwell return error; 1153f23de10SStephen Rothwell } 1163f23de10SStephen Rothwell 1173f23de10SStephen Rothwell static int of_platform_device_remove(struct device *dev) 1183f23de10SStephen Rothwell { 119*94a0cb1fSGrant Likely struct platform_device *of_dev = to_platform_device(dev); 1203f23de10SStephen Rothwell struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 1213f23de10SStephen Rothwell 1223f23de10SStephen Rothwell if (dev->driver && drv->remove) 1233f23de10SStephen Rothwell drv->remove(of_dev); 1243f23de10SStephen Rothwell return 0; 1253f23de10SStephen Rothwell } 1263f23de10SStephen Rothwell 127a09ad3c4SMichael Ellerman static void of_platform_device_shutdown(struct device *dev) 128a09ad3c4SMichael Ellerman { 129*94a0cb1fSGrant Likely struct platform_device *of_dev = to_platform_device(dev); 130a09ad3c4SMichael Ellerman struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 131a09ad3c4SMichael Ellerman 132a09ad3c4SMichael Ellerman if (dev->driver && drv->shutdown) 133a09ad3c4SMichael Ellerman drv->shutdown(of_dev); 134a09ad3c4SMichael Ellerman } 135a09ad3c4SMichael Ellerman 136d35ef90bSAnton Vorontsov #ifdef CONFIG_PM_SLEEP 137d35ef90bSAnton Vorontsov 138d35ef90bSAnton Vorontsov static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg) 139d35ef90bSAnton Vorontsov { 140*94a0cb1fSGrant Likely struct platform_device *of_dev = to_platform_device(dev); 141d35ef90bSAnton Vorontsov struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 142d35ef90bSAnton Vorontsov int ret = 0; 143d35ef90bSAnton Vorontsov 144d35ef90bSAnton Vorontsov if (dev->driver && drv->suspend) 145d35ef90bSAnton Vorontsov ret = drv->suspend(of_dev, mesg); 146d35ef90bSAnton Vorontsov return ret; 147d35ef90bSAnton Vorontsov } 148d35ef90bSAnton Vorontsov 149d35ef90bSAnton Vorontsov static int of_platform_legacy_resume(struct device *dev) 150d35ef90bSAnton Vorontsov { 151*94a0cb1fSGrant Likely struct platform_device *of_dev = to_platform_device(dev); 152d35ef90bSAnton Vorontsov struct of_platform_driver *drv = to_of_platform_driver(dev->driver); 153d35ef90bSAnton Vorontsov int ret = 0; 154d35ef90bSAnton Vorontsov 155d35ef90bSAnton Vorontsov if (dev->driver && drv->resume) 156d35ef90bSAnton Vorontsov ret = drv->resume(of_dev); 157d35ef90bSAnton Vorontsov return ret; 158d35ef90bSAnton Vorontsov } 159d35ef90bSAnton Vorontsov 160d35ef90bSAnton Vorontsov static int of_platform_pm_prepare(struct device *dev) 161d35ef90bSAnton Vorontsov { 162d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 163d35ef90bSAnton Vorontsov int ret = 0; 164d35ef90bSAnton Vorontsov 165d35ef90bSAnton Vorontsov if (drv && drv->pm && drv->pm->prepare) 166d35ef90bSAnton Vorontsov ret = drv->pm->prepare(dev); 167d35ef90bSAnton Vorontsov 168d35ef90bSAnton Vorontsov return ret; 169d35ef90bSAnton Vorontsov } 170d35ef90bSAnton Vorontsov 171d35ef90bSAnton Vorontsov static void of_platform_pm_complete(struct device *dev) 172d35ef90bSAnton Vorontsov { 173d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 174d35ef90bSAnton Vorontsov 175d35ef90bSAnton Vorontsov if (drv && drv->pm && drv->pm->complete) 176d35ef90bSAnton Vorontsov drv->pm->complete(dev); 177d35ef90bSAnton Vorontsov } 178d35ef90bSAnton Vorontsov 179d35ef90bSAnton Vorontsov #ifdef CONFIG_SUSPEND 180d35ef90bSAnton Vorontsov 181d35ef90bSAnton Vorontsov static int of_platform_pm_suspend(struct device *dev) 182d35ef90bSAnton Vorontsov { 183d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 184d35ef90bSAnton Vorontsov int ret = 0; 185d35ef90bSAnton Vorontsov 186d35ef90bSAnton Vorontsov if (!drv) 187d35ef90bSAnton Vorontsov return 0; 188d35ef90bSAnton Vorontsov 189d35ef90bSAnton Vorontsov if (drv->pm) { 190d35ef90bSAnton Vorontsov if (drv->pm->suspend) 191d35ef90bSAnton Vorontsov ret = drv->pm->suspend(dev); 192d35ef90bSAnton Vorontsov } else { 193d35ef90bSAnton Vorontsov ret = of_platform_legacy_suspend(dev, PMSG_SUSPEND); 194d35ef90bSAnton Vorontsov } 195d35ef90bSAnton Vorontsov 196d35ef90bSAnton Vorontsov return ret; 197d35ef90bSAnton Vorontsov } 198d35ef90bSAnton Vorontsov 199d35ef90bSAnton Vorontsov static int of_platform_pm_suspend_noirq(struct device *dev) 200d35ef90bSAnton Vorontsov { 201d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 202d35ef90bSAnton Vorontsov int ret = 0; 203d35ef90bSAnton Vorontsov 204d35ef90bSAnton Vorontsov if (!drv) 205d35ef90bSAnton Vorontsov return 0; 206d35ef90bSAnton Vorontsov 207d35ef90bSAnton Vorontsov if (drv->pm) { 208d35ef90bSAnton Vorontsov if (drv->pm->suspend_noirq) 209d35ef90bSAnton Vorontsov ret = drv->pm->suspend_noirq(dev); 210d35ef90bSAnton Vorontsov } 211d35ef90bSAnton Vorontsov 212d35ef90bSAnton Vorontsov return ret; 213d35ef90bSAnton Vorontsov } 214d35ef90bSAnton Vorontsov 215d35ef90bSAnton Vorontsov static int of_platform_pm_resume(struct device *dev) 216d35ef90bSAnton Vorontsov { 217d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 218d35ef90bSAnton Vorontsov int ret = 0; 219d35ef90bSAnton Vorontsov 220d35ef90bSAnton Vorontsov if (!drv) 221d35ef90bSAnton Vorontsov return 0; 222d35ef90bSAnton Vorontsov 223d35ef90bSAnton Vorontsov if (drv->pm) { 224d35ef90bSAnton Vorontsov if (drv->pm->resume) 225d35ef90bSAnton Vorontsov ret = drv->pm->resume(dev); 226d35ef90bSAnton Vorontsov } else { 227d35ef90bSAnton Vorontsov ret = of_platform_legacy_resume(dev); 228d35ef90bSAnton Vorontsov } 229d35ef90bSAnton Vorontsov 230d35ef90bSAnton Vorontsov return ret; 231d35ef90bSAnton Vorontsov } 232d35ef90bSAnton Vorontsov 233d35ef90bSAnton Vorontsov static int of_platform_pm_resume_noirq(struct device *dev) 234d35ef90bSAnton Vorontsov { 235d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 236d35ef90bSAnton Vorontsov int ret = 0; 237d35ef90bSAnton Vorontsov 238d35ef90bSAnton Vorontsov if (!drv) 239d35ef90bSAnton Vorontsov return 0; 240d35ef90bSAnton Vorontsov 241d35ef90bSAnton Vorontsov if (drv->pm) { 242d35ef90bSAnton Vorontsov if (drv->pm->resume_noirq) 243d35ef90bSAnton Vorontsov ret = drv->pm->resume_noirq(dev); 244d35ef90bSAnton Vorontsov } 245d35ef90bSAnton Vorontsov 246d35ef90bSAnton Vorontsov return ret; 247d35ef90bSAnton Vorontsov } 248d35ef90bSAnton Vorontsov 249d35ef90bSAnton Vorontsov #else /* !CONFIG_SUSPEND */ 250d35ef90bSAnton Vorontsov 251d35ef90bSAnton Vorontsov #define of_platform_pm_suspend NULL 252d35ef90bSAnton Vorontsov #define of_platform_pm_resume NULL 253d35ef90bSAnton Vorontsov #define of_platform_pm_suspend_noirq NULL 254d35ef90bSAnton Vorontsov #define of_platform_pm_resume_noirq NULL 255d35ef90bSAnton Vorontsov 256d35ef90bSAnton Vorontsov #endif /* !CONFIG_SUSPEND */ 257d35ef90bSAnton Vorontsov 258d35ef90bSAnton Vorontsov #ifdef CONFIG_HIBERNATION 259d35ef90bSAnton Vorontsov 260d35ef90bSAnton Vorontsov static int of_platform_pm_freeze(struct device *dev) 261d35ef90bSAnton Vorontsov { 262d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 263d35ef90bSAnton Vorontsov int ret = 0; 264d35ef90bSAnton Vorontsov 265d35ef90bSAnton Vorontsov if (!drv) 266d35ef90bSAnton Vorontsov return 0; 267d35ef90bSAnton Vorontsov 268d35ef90bSAnton Vorontsov if (drv->pm) { 269d35ef90bSAnton Vorontsov if (drv->pm->freeze) 270d35ef90bSAnton Vorontsov ret = drv->pm->freeze(dev); 271d35ef90bSAnton Vorontsov } else { 272d35ef90bSAnton Vorontsov ret = of_platform_legacy_suspend(dev, PMSG_FREEZE); 273d35ef90bSAnton Vorontsov } 274d35ef90bSAnton Vorontsov 275d35ef90bSAnton Vorontsov return ret; 276d35ef90bSAnton Vorontsov } 277d35ef90bSAnton Vorontsov 278d35ef90bSAnton Vorontsov static int of_platform_pm_freeze_noirq(struct device *dev) 279d35ef90bSAnton Vorontsov { 280d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 281d35ef90bSAnton Vorontsov int ret = 0; 282d35ef90bSAnton Vorontsov 283d35ef90bSAnton Vorontsov if (!drv) 284d35ef90bSAnton Vorontsov return 0; 285d35ef90bSAnton Vorontsov 286d35ef90bSAnton Vorontsov if (drv->pm) { 287d35ef90bSAnton Vorontsov if (drv->pm->freeze_noirq) 288d35ef90bSAnton Vorontsov ret = drv->pm->freeze_noirq(dev); 289d35ef90bSAnton Vorontsov } 290d35ef90bSAnton Vorontsov 291d35ef90bSAnton Vorontsov return ret; 292d35ef90bSAnton Vorontsov } 293d35ef90bSAnton Vorontsov 294d35ef90bSAnton Vorontsov static int of_platform_pm_thaw(struct device *dev) 295d35ef90bSAnton Vorontsov { 296d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 297d35ef90bSAnton Vorontsov int ret = 0; 298d35ef90bSAnton Vorontsov 299d35ef90bSAnton Vorontsov if (!drv) 300d35ef90bSAnton Vorontsov return 0; 301d35ef90bSAnton Vorontsov 302d35ef90bSAnton Vorontsov if (drv->pm) { 303d35ef90bSAnton Vorontsov if (drv->pm->thaw) 304d35ef90bSAnton Vorontsov ret = drv->pm->thaw(dev); 305d35ef90bSAnton Vorontsov } else { 306d35ef90bSAnton Vorontsov ret = of_platform_legacy_resume(dev); 307d35ef90bSAnton Vorontsov } 308d35ef90bSAnton Vorontsov 309d35ef90bSAnton Vorontsov return ret; 310d35ef90bSAnton Vorontsov } 311d35ef90bSAnton Vorontsov 312d35ef90bSAnton Vorontsov static int of_platform_pm_thaw_noirq(struct device *dev) 313d35ef90bSAnton Vorontsov { 314d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 315d35ef90bSAnton Vorontsov int ret = 0; 316d35ef90bSAnton Vorontsov 317d35ef90bSAnton Vorontsov if (!drv) 318d35ef90bSAnton Vorontsov return 0; 319d35ef90bSAnton Vorontsov 320d35ef90bSAnton Vorontsov if (drv->pm) { 321d35ef90bSAnton Vorontsov if (drv->pm->thaw_noirq) 322d35ef90bSAnton Vorontsov ret = drv->pm->thaw_noirq(dev); 323d35ef90bSAnton Vorontsov } 324d35ef90bSAnton Vorontsov 325d35ef90bSAnton Vorontsov return ret; 326d35ef90bSAnton Vorontsov } 327d35ef90bSAnton Vorontsov 328d35ef90bSAnton Vorontsov static int of_platform_pm_poweroff(struct device *dev) 329d35ef90bSAnton Vorontsov { 330d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 331d35ef90bSAnton Vorontsov int ret = 0; 332d35ef90bSAnton Vorontsov 333d35ef90bSAnton Vorontsov if (!drv) 334d35ef90bSAnton Vorontsov return 0; 335d35ef90bSAnton Vorontsov 336d35ef90bSAnton Vorontsov if (drv->pm) { 337d35ef90bSAnton Vorontsov if (drv->pm->poweroff) 338d35ef90bSAnton Vorontsov ret = drv->pm->poweroff(dev); 339d35ef90bSAnton Vorontsov } else { 340d35ef90bSAnton Vorontsov ret = of_platform_legacy_suspend(dev, PMSG_HIBERNATE); 341d35ef90bSAnton Vorontsov } 342d35ef90bSAnton Vorontsov 343d35ef90bSAnton Vorontsov return ret; 344d35ef90bSAnton Vorontsov } 345d35ef90bSAnton Vorontsov 346d35ef90bSAnton Vorontsov static int of_platform_pm_poweroff_noirq(struct device *dev) 347d35ef90bSAnton Vorontsov { 348d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 349d35ef90bSAnton Vorontsov int ret = 0; 350d35ef90bSAnton Vorontsov 351d35ef90bSAnton Vorontsov if (!drv) 352d35ef90bSAnton Vorontsov return 0; 353d35ef90bSAnton Vorontsov 354d35ef90bSAnton Vorontsov if (drv->pm) { 355d35ef90bSAnton Vorontsov if (drv->pm->poweroff_noirq) 356d35ef90bSAnton Vorontsov ret = drv->pm->poweroff_noirq(dev); 357d35ef90bSAnton Vorontsov } 358d35ef90bSAnton Vorontsov 359d35ef90bSAnton Vorontsov return ret; 360d35ef90bSAnton Vorontsov } 361d35ef90bSAnton Vorontsov 362d35ef90bSAnton Vorontsov static int of_platform_pm_restore(struct device *dev) 363d35ef90bSAnton Vorontsov { 364d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 365d35ef90bSAnton Vorontsov int ret = 0; 366d35ef90bSAnton Vorontsov 367d35ef90bSAnton Vorontsov if (!drv) 368d35ef90bSAnton Vorontsov return 0; 369d35ef90bSAnton Vorontsov 370d35ef90bSAnton Vorontsov if (drv->pm) { 371d35ef90bSAnton Vorontsov if (drv->pm->restore) 372d35ef90bSAnton Vorontsov ret = drv->pm->restore(dev); 373d35ef90bSAnton Vorontsov } else { 374d35ef90bSAnton Vorontsov ret = of_platform_legacy_resume(dev); 375d35ef90bSAnton Vorontsov } 376d35ef90bSAnton Vorontsov 377d35ef90bSAnton Vorontsov return ret; 378d35ef90bSAnton Vorontsov } 379d35ef90bSAnton Vorontsov 380d35ef90bSAnton Vorontsov static int of_platform_pm_restore_noirq(struct device *dev) 381d35ef90bSAnton Vorontsov { 382d35ef90bSAnton Vorontsov struct device_driver *drv = dev->driver; 383d35ef90bSAnton Vorontsov int ret = 0; 384d35ef90bSAnton Vorontsov 385d35ef90bSAnton Vorontsov if (!drv) 386d35ef90bSAnton Vorontsov return 0; 387d35ef90bSAnton Vorontsov 388d35ef90bSAnton Vorontsov if (drv->pm) { 389d35ef90bSAnton Vorontsov if (drv->pm->restore_noirq) 390d35ef90bSAnton Vorontsov ret = drv->pm->restore_noirq(dev); 391d35ef90bSAnton Vorontsov } 392d35ef90bSAnton Vorontsov 393d35ef90bSAnton Vorontsov return ret; 394d35ef90bSAnton Vorontsov } 395d35ef90bSAnton Vorontsov 396d35ef90bSAnton Vorontsov #else /* !CONFIG_HIBERNATION */ 397d35ef90bSAnton Vorontsov 398d35ef90bSAnton Vorontsov #define of_platform_pm_freeze NULL 399d35ef90bSAnton Vorontsov #define of_platform_pm_thaw NULL 400d35ef90bSAnton Vorontsov #define of_platform_pm_poweroff NULL 401d35ef90bSAnton Vorontsov #define of_platform_pm_restore NULL 402d35ef90bSAnton Vorontsov #define of_platform_pm_freeze_noirq NULL 403d35ef90bSAnton Vorontsov #define of_platform_pm_thaw_noirq NULL 404d35ef90bSAnton Vorontsov #define of_platform_pm_poweroff_noirq NULL 405d35ef90bSAnton Vorontsov #define of_platform_pm_restore_noirq NULL 406d35ef90bSAnton Vorontsov 407d35ef90bSAnton Vorontsov #endif /* !CONFIG_HIBERNATION */ 408d35ef90bSAnton Vorontsov 409d35ef90bSAnton Vorontsov static struct dev_pm_ops of_platform_dev_pm_ops = { 410d35ef90bSAnton Vorontsov .prepare = of_platform_pm_prepare, 411d35ef90bSAnton Vorontsov .complete = of_platform_pm_complete, 412d35ef90bSAnton Vorontsov .suspend = of_platform_pm_suspend, 413d35ef90bSAnton Vorontsov .resume = of_platform_pm_resume, 414d35ef90bSAnton Vorontsov .freeze = of_platform_pm_freeze, 415d35ef90bSAnton Vorontsov .thaw = of_platform_pm_thaw, 416d35ef90bSAnton Vorontsov .poweroff = of_platform_pm_poweroff, 417d35ef90bSAnton Vorontsov .restore = of_platform_pm_restore, 418d35ef90bSAnton Vorontsov .suspend_noirq = of_platform_pm_suspend_noirq, 419d35ef90bSAnton Vorontsov .resume_noirq = of_platform_pm_resume_noirq, 420d35ef90bSAnton Vorontsov .freeze_noirq = of_platform_pm_freeze_noirq, 421d35ef90bSAnton Vorontsov .thaw_noirq = of_platform_pm_thaw_noirq, 422d35ef90bSAnton Vorontsov .poweroff_noirq = of_platform_pm_poweroff_noirq, 423d35ef90bSAnton Vorontsov .restore_noirq = of_platform_pm_restore_noirq, 424d35ef90bSAnton Vorontsov }; 425d35ef90bSAnton Vorontsov 426d35ef90bSAnton Vorontsov #define OF_PLATFORM_PM_OPS_PTR (&of_platform_dev_pm_ops) 427d35ef90bSAnton Vorontsov 428d35ef90bSAnton Vorontsov #else /* !CONFIG_PM_SLEEP */ 429d35ef90bSAnton Vorontsov 430d35ef90bSAnton Vorontsov #define OF_PLATFORM_PM_OPS_PTR NULL 431d35ef90bSAnton Vorontsov 432d35ef90bSAnton Vorontsov #endif /* !CONFIG_PM_SLEEP */ 433d35ef90bSAnton Vorontsov 4343f23de10SStephen Rothwell int of_bus_type_init(struct bus_type *bus, const char *name) 4353f23de10SStephen Rothwell { 4363f23de10SStephen Rothwell bus->name = name; 4373f23de10SStephen Rothwell bus->match = of_platform_bus_match; 4383f23de10SStephen Rothwell bus->probe = of_platform_device_probe; 4393f23de10SStephen Rothwell bus->remove = of_platform_device_remove; 440a09ad3c4SMichael Ellerman bus->shutdown = of_platform_device_shutdown; 441140b932fSOlaf Hering bus->dev_attrs = of_platform_device_attrs; 442d35ef90bSAnton Vorontsov bus->pm = OF_PLATFORM_PM_OPS_PTR; 4433f23de10SStephen Rothwell return bus_register(bus); 4443f23de10SStephen Rothwell } 4455c457083SStephen Rothwell 4465c457083SStephen Rothwell int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) 4475c457083SStephen Rothwell { 448eca39301SGrant Likely /* 449eca39301SGrant Likely * Temporary: of_platform_bus used to be distinct from the platform 450eca39301SGrant Likely * bus. It isn't anymore, and so drivers on the platform bus need 451eca39301SGrant Likely * to be registered in a special way. 452eca39301SGrant Likely * 453eca39301SGrant Likely * After all of_platform_bus_type drivers are converted to 454eca39301SGrant Likely * platform_drivers, this exception can be removed. 455eca39301SGrant Likely */ 456eca39301SGrant Likely if (bus == &platform_bus_type) 457eca39301SGrant Likely return of_register_platform_driver(drv); 4585c457083SStephen Rothwell 4595c457083SStephen Rothwell /* register with core */ 460eca39301SGrant Likely drv->driver.bus = bus; 4615c457083SStephen Rothwell return driver_register(&drv->driver); 4625c457083SStephen Rothwell } 4635c457083SStephen Rothwell EXPORT_SYMBOL(of_register_driver); 4645c457083SStephen Rothwell 4655c457083SStephen Rothwell void of_unregister_driver(struct of_platform_driver *drv) 4665c457083SStephen Rothwell { 467eca39301SGrant Likely if (drv->driver.bus == &platform_bus_type) 468eca39301SGrant Likely of_unregister_platform_driver(drv); 469eca39301SGrant Likely else 4705c457083SStephen Rothwell driver_unregister(&drv->driver); 4715c457083SStephen Rothwell } 4725c457083SStephen Rothwell EXPORT_SYMBOL(of_unregister_driver); 4735fd200f3SGrant Likely 4745fd200f3SGrant Likely #if !defined(CONFIG_SPARC) 4755fd200f3SGrant Likely /* 4765fd200f3SGrant Likely * The following routines scan a subtree and registers a device for 4775fd200f3SGrant Likely * each applicable node. 4785fd200f3SGrant Likely * 4795fd200f3SGrant Likely * Note: sparc doesn't use these routines because it has a different 4805fd200f3SGrant Likely * mechanism for creating devices from device tree nodes. 4815fd200f3SGrant Likely */ 4825fd200f3SGrant Likely 4835fd200f3SGrant Likely /** 48494c09319SGrant Likely * of_device_make_bus_id - Use the device node data to assign a unique name 48594c09319SGrant Likely * @dev: pointer to device structure that is linked to a device tree node 48694c09319SGrant Likely * 48794c09319SGrant Likely * This routine will first try using either the dcr-reg or the reg property 48894c09319SGrant Likely * value to derive a unique name. As a last resort it will use the node 48994c09319SGrant Likely * name followed by a unique number. 49094c09319SGrant Likely */ 49194c09319SGrant Likely static void of_device_make_bus_id(struct device *dev) 49294c09319SGrant Likely { 49394c09319SGrant Likely static atomic_t bus_no_reg_magic; 49494c09319SGrant Likely struct device_node *node = dev->of_node; 49594c09319SGrant Likely const u32 *reg; 49694c09319SGrant Likely u64 addr; 49794c09319SGrant Likely int magic; 49894c09319SGrant Likely 49994c09319SGrant Likely #ifdef CONFIG_PPC_DCR 50094c09319SGrant Likely /* 50194c09319SGrant Likely * If it's a DCR based device, use 'd' for native DCRs 50294c09319SGrant Likely * and 'D' for MMIO DCRs. 50394c09319SGrant Likely */ 50494c09319SGrant Likely reg = of_get_property(node, "dcr-reg", NULL); 50594c09319SGrant Likely if (reg) { 50694c09319SGrant Likely #ifdef CONFIG_PPC_DCR_NATIVE 50794c09319SGrant Likely dev_set_name(dev, "d%x.%s", *reg, node->name); 50894c09319SGrant Likely #else /* CONFIG_PPC_DCR_NATIVE */ 50994c09319SGrant Likely u64 addr = of_translate_dcr_address(node, *reg, NULL); 51094c09319SGrant Likely if (addr != OF_BAD_ADDR) { 51194c09319SGrant Likely dev_set_name(dev, "D%llx.%s", 51294c09319SGrant Likely (unsigned long long)addr, node->name); 51394c09319SGrant Likely return; 51494c09319SGrant Likely } 51594c09319SGrant Likely #endif /* !CONFIG_PPC_DCR_NATIVE */ 51694c09319SGrant Likely } 51794c09319SGrant Likely #endif /* CONFIG_PPC_DCR */ 51894c09319SGrant Likely 51994c09319SGrant Likely /* 52094c09319SGrant Likely * For MMIO, get the physical address 52194c09319SGrant Likely */ 52294c09319SGrant Likely reg = of_get_property(node, "reg", NULL); 52394c09319SGrant Likely if (reg) { 52494c09319SGrant Likely addr = of_translate_address(node, reg); 52594c09319SGrant Likely if (addr != OF_BAD_ADDR) { 52694c09319SGrant Likely dev_set_name(dev, "%llx.%s", 52794c09319SGrant Likely (unsigned long long)addr, node->name); 52894c09319SGrant Likely return; 52994c09319SGrant Likely } 53094c09319SGrant Likely } 53194c09319SGrant Likely 53294c09319SGrant Likely /* 53394c09319SGrant Likely * No BusID, use the node name and add a globally incremented 53494c09319SGrant Likely * counter (and pray...) 53594c09319SGrant Likely */ 53694c09319SGrant Likely magic = atomic_add_return(1, &bus_no_reg_magic); 53794c09319SGrant Likely dev_set_name(dev, "%s.%d", node->name, magic - 1); 53894c09319SGrant Likely } 53994c09319SGrant Likely 54094c09319SGrant Likely /** 54194c09319SGrant Likely * of_device_alloc - Allocate and initialize an of_device 54294c09319SGrant Likely * @np: device node to assign to device 54394c09319SGrant Likely * @bus_id: Name to assign to the device. May be null to use default name. 54494c09319SGrant Likely * @parent: Parent device. 54594c09319SGrant Likely */ 546*94a0cb1fSGrant Likely struct platform_device *of_device_alloc(struct device_node *np, 54794c09319SGrant Likely const char *bus_id, 54894c09319SGrant Likely struct device *parent) 54994c09319SGrant Likely { 550*94a0cb1fSGrant Likely struct platform_device *dev; 551ac80a51eSGrant Likely int rc, i, num_reg = 0, num_irq = 0; 552ac80a51eSGrant Likely struct resource *res, temp_res; 55394c09319SGrant Likely 554ac80a51eSGrant Likely /* First count how many resources are needed */ 555ac80a51eSGrant Likely while (of_address_to_resource(np, num_reg, &temp_res) == 0) 556ac80a51eSGrant Likely num_reg++; 557ac80a51eSGrant Likely while (of_irq_to_resource(np, num_irq, &temp_res) != NO_IRQ) 558ac80a51eSGrant Likely num_irq++; 559ac80a51eSGrant Likely 560ac80a51eSGrant Likely /* Allocate memory for both the struct device and the resource table */ 561ac80a51eSGrant Likely dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)), 562ac80a51eSGrant Likely GFP_KERNEL); 56394c09319SGrant Likely if (!dev) 56494c09319SGrant Likely return NULL; 565ac80a51eSGrant Likely res = (struct resource *) &dev[1]; 566ac80a51eSGrant Likely 567ac80a51eSGrant Likely /* Populate the resource table */ 568ac80a51eSGrant Likely if (num_irq || num_reg) { 569ac80a51eSGrant Likely dev->num_resources = num_reg + num_irq; 570ac80a51eSGrant Likely dev->resource = res; 571ac80a51eSGrant Likely for (i = 0; i < num_reg; i++, res++) { 572ac80a51eSGrant Likely rc = of_address_to_resource(np, i, res); 573ac80a51eSGrant Likely WARN_ON(rc); 574ac80a51eSGrant Likely } 575ac80a51eSGrant Likely for (i = 0; i < num_irq; i++, res++) { 576ac80a51eSGrant Likely rc = of_irq_to_resource(np, i, res); 577ac80a51eSGrant Likely WARN_ON(rc == NO_IRQ); 578ac80a51eSGrant Likely } 579ac80a51eSGrant Likely } 58094c09319SGrant Likely 58194c09319SGrant Likely dev->dev.of_node = of_node_get(np); 5829e3288dcSGrant Likely #if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE) 58394c09319SGrant Likely dev->dev.dma_mask = &dev->archdata.dma_mask; 5849e3288dcSGrant Likely #endif 58594c09319SGrant Likely dev->dev.parent = parent; 58694c09319SGrant Likely dev->dev.release = of_release_dev; 58794c09319SGrant Likely 58894c09319SGrant Likely if (bus_id) 58994c09319SGrant Likely dev_set_name(&dev->dev, "%s", bus_id); 59094c09319SGrant Likely else 59194c09319SGrant Likely of_device_make_bus_id(&dev->dev); 59294c09319SGrant Likely 59394c09319SGrant Likely return dev; 59494c09319SGrant Likely } 59594c09319SGrant Likely EXPORT_SYMBOL(of_device_alloc); 59694c09319SGrant Likely 59794c09319SGrant Likely /** 5985fd200f3SGrant Likely * of_platform_device_create - Alloc, initialize and register an of_device 5995fd200f3SGrant Likely * @np: pointer to node to create device for 6005fd200f3SGrant Likely * @bus_id: name to assign device 6015fd200f3SGrant Likely * @parent: Linux device model parent device. 6025fd200f3SGrant Likely */ 603*94a0cb1fSGrant Likely struct platform_device *of_platform_device_create(struct device_node *np, 6045fd200f3SGrant Likely const char *bus_id, 6055fd200f3SGrant Likely struct device *parent) 6065fd200f3SGrant Likely { 607*94a0cb1fSGrant Likely struct platform_device *dev; 6085fd200f3SGrant Likely 6095fd200f3SGrant Likely dev = of_device_alloc(np, bus_id, parent); 6105fd200f3SGrant Likely if (!dev) 6115fd200f3SGrant Likely return NULL; 6125fd200f3SGrant Likely 6139e3288dcSGrant Likely #if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE) 6145fd200f3SGrant Likely dev->archdata.dma_mask = 0xffffffffUL; 6159e3288dcSGrant Likely #endif 6165fd200f3SGrant Likely dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 617eca39301SGrant Likely dev->dev.bus = &platform_bus_type; 6185fd200f3SGrant Likely 6195fd200f3SGrant Likely /* We do not fill the DMA ops for platform devices by default. 6205fd200f3SGrant Likely * This is currently the responsibility of the platform code 6215fd200f3SGrant Likely * to do such, possibly using a device notifier 6225fd200f3SGrant Likely */ 6235fd200f3SGrant Likely 6245fd200f3SGrant Likely if (of_device_register(dev) != 0) { 6255fd200f3SGrant Likely of_device_free(dev); 6265fd200f3SGrant Likely return NULL; 6275fd200f3SGrant Likely } 6285fd200f3SGrant Likely 6295fd200f3SGrant Likely return dev; 6305fd200f3SGrant Likely } 6315fd200f3SGrant Likely EXPORT_SYMBOL(of_platform_device_create); 6325fd200f3SGrant Likely 6335fd200f3SGrant Likely /** 6345fd200f3SGrant Likely * of_platform_bus_create - Create an OF device for a bus node and all its 6355fd200f3SGrant Likely * children. Optionally recursively instantiate matching busses. 6365fd200f3SGrant Likely * @bus: device node of the bus to instantiate 6375fd200f3SGrant Likely * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to 6385fd200f3SGrant Likely * disallow recursive creation of child busses 6395fd200f3SGrant Likely */ 6405fd200f3SGrant Likely static int of_platform_bus_create(const struct device_node *bus, 6415fd200f3SGrant Likely const struct of_device_id *matches, 6425fd200f3SGrant Likely struct device *parent) 6435fd200f3SGrant Likely { 6445fd200f3SGrant Likely struct device_node *child; 645*94a0cb1fSGrant Likely struct platform_device *dev; 6465fd200f3SGrant Likely int rc = 0; 6475fd200f3SGrant Likely 6485fd200f3SGrant Likely for_each_child_of_node(bus, child) { 6495fd200f3SGrant Likely pr_debug(" create child: %s\n", child->full_name); 6505fd200f3SGrant Likely dev = of_platform_device_create(child, NULL, parent); 6515fd200f3SGrant Likely if (dev == NULL) 6525fd200f3SGrant Likely rc = -ENOMEM; 6535fd200f3SGrant Likely else if (!of_match_node(matches, child)) 6545fd200f3SGrant Likely continue; 6555fd200f3SGrant Likely if (rc == 0) { 6565fd200f3SGrant Likely pr_debug(" and sub busses\n"); 6575fd200f3SGrant Likely rc = of_platform_bus_create(child, matches, &dev->dev); 6585fd200f3SGrant Likely } 6595fd200f3SGrant Likely if (rc) { 6605fd200f3SGrant Likely of_node_put(child); 6615fd200f3SGrant Likely break; 6625fd200f3SGrant Likely } 6635fd200f3SGrant Likely } 6645fd200f3SGrant Likely return rc; 6655fd200f3SGrant Likely } 6665fd200f3SGrant Likely 6675fd200f3SGrant Likely /** 6685fd200f3SGrant Likely * of_platform_bus_probe - Probe the device-tree for platform busses 6695fd200f3SGrant Likely * @root: parent of the first level to probe or NULL for the root of the tree 6705fd200f3SGrant Likely * @matches: match table, NULL to use the default 6715fd200f3SGrant Likely * @parent: parent to hook devices from, NULL for toplevel 6725fd200f3SGrant Likely * 6735fd200f3SGrant Likely * Note that children of the provided root are not instantiated as devices 6745fd200f3SGrant Likely * unless the specified root itself matches the bus list and is not NULL. 6755fd200f3SGrant Likely */ 6765fd200f3SGrant Likely int of_platform_bus_probe(struct device_node *root, 6775fd200f3SGrant Likely const struct of_device_id *matches, 6785fd200f3SGrant Likely struct device *parent) 6795fd200f3SGrant Likely { 6805fd200f3SGrant Likely struct device_node *child; 681*94a0cb1fSGrant Likely struct platform_device *dev; 6825fd200f3SGrant Likely int rc = 0; 6835fd200f3SGrant Likely 6845fd200f3SGrant Likely if (matches == NULL) 6855fd200f3SGrant Likely matches = of_default_bus_ids; 6865fd200f3SGrant Likely if (matches == OF_NO_DEEP_PROBE) 6875fd200f3SGrant Likely return -EINVAL; 6885fd200f3SGrant Likely if (root == NULL) 6895fd200f3SGrant Likely root = of_find_node_by_path("/"); 6905fd200f3SGrant Likely else 6915fd200f3SGrant Likely of_node_get(root); 69260d59913SGrant Likely if (root == NULL) 69360d59913SGrant Likely return -EINVAL; 6945fd200f3SGrant Likely 6955fd200f3SGrant Likely pr_debug("of_platform_bus_probe()\n"); 6965fd200f3SGrant Likely pr_debug(" starting at: %s\n", root->full_name); 6975fd200f3SGrant Likely 6985fd200f3SGrant Likely /* Do a self check of bus type, if there's a match, create 6995fd200f3SGrant Likely * children 7005fd200f3SGrant Likely */ 7015fd200f3SGrant Likely if (of_match_node(matches, root)) { 7025fd200f3SGrant Likely pr_debug(" root match, create all sub devices\n"); 7035fd200f3SGrant Likely dev = of_platform_device_create(root, NULL, parent); 7045fd200f3SGrant Likely if (dev == NULL) { 7055fd200f3SGrant Likely rc = -ENOMEM; 7065fd200f3SGrant Likely goto bail; 7075fd200f3SGrant Likely } 7085fd200f3SGrant Likely pr_debug(" create all sub busses\n"); 7095fd200f3SGrant Likely rc = of_platform_bus_create(root, matches, &dev->dev); 7105fd200f3SGrant Likely goto bail; 7115fd200f3SGrant Likely } 7125fd200f3SGrant Likely for_each_child_of_node(root, child) { 7135fd200f3SGrant Likely if (!of_match_node(matches, child)) 7145fd200f3SGrant Likely continue; 7155fd200f3SGrant Likely 7165fd200f3SGrant Likely pr_debug(" match: %s\n", child->full_name); 7175fd200f3SGrant Likely dev = of_platform_device_create(child, NULL, parent); 7185fd200f3SGrant Likely if (dev == NULL) 7195fd200f3SGrant Likely rc = -ENOMEM; 7205fd200f3SGrant Likely else 7215fd200f3SGrant Likely rc = of_platform_bus_create(child, matches, &dev->dev); 7225fd200f3SGrant Likely if (rc) { 7235fd200f3SGrant Likely of_node_put(child); 7245fd200f3SGrant Likely break; 7255fd200f3SGrant Likely } 7265fd200f3SGrant Likely } 7275fd200f3SGrant Likely bail: 7285fd200f3SGrant Likely of_node_put(root); 7295fd200f3SGrant Likely return rc; 7305fd200f3SGrant Likely } 7315fd200f3SGrant Likely EXPORT_SYMBOL(of_platform_bus_probe); 7325fd200f3SGrant Likely #endif /* !CONFIG_SPARC */ 733