bus.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * arch/sh/kernel/cpu/bus.c
  3. *
  4. * Virtual bus for SuperH.
  5. *
  6. * Copyright (C) 2004 Paul Mundt
  7. *
  8. * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written
  9. * by:
  10. *
  11. * Copyright (C) 2003 - 2004 Nokia Corporation
  12. * Written by Tony Lindgren <tony@atomide.com>
  13. * Portions of code based on sa1111.c.
  14. *
  15. * This program is free software; you can redistribute it and/or modify it
  16. * under the terms of the GNU General Public License as published by the
  17. * Free Software Foundation; either version 2 of the License, or (at your
  18. * option) any later version.
  19. */
  20. #include <linux/kernel.h>
  21. #include <linux/device.h>
  22. #include <linux/init.h>
  23. #include <linux/module.h>
  24. #include <asm/bus-sh.h>
  25. static int sh_bus_match(struct device *dev, struct device_driver *drv)
  26. {
  27. struct sh_driver *shdrv = to_sh_driver(drv);
  28. struct sh_dev *shdev = to_sh_dev(dev);
  29. return shdev->dev_id == shdrv->dev_id;
  30. }
  31. static int sh_bus_suspend(struct device *dev, pm_message_t state)
  32. {
  33. struct sh_dev *shdev = to_sh_dev(dev);
  34. struct sh_driver *shdrv = to_sh_driver(dev->driver);
  35. if (shdrv && shdrv->suspend)
  36. return shdrv->suspend(shdev, state);
  37. return 0;
  38. }
  39. static int sh_bus_resume(struct device *dev)
  40. {
  41. struct sh_dev *shdev = to_sh_dev(dev);
  42. struct sh_driver *shdrv = to_sh_driver(dev->driver);
  43. if (shdrv && shdrv->resume)
  44. return shdrv->resume(shdev);
  45. return 0;
  46. }
  47. static int sh_device_probe(struct device *dev)
  48. {
  49. struct sh_dev *shdev = to_sh_dev(dev);
  50. struct sh_driver *shdrv = to_sh_driver(dev->driver);
  51. if (shdrv && shdrv->probe)
  52. return shdrv->probe(shdev);
  53. return -ENODEV;
  54. }
  55. static int sh_device_remove(struct device *dev)
  56. {
  57. struct sh_dev *shdev = to_sh_dev(dev);
  58. struct sh_driver *shdrv = to_sh_driver(dev->driver);
  59. if (shdrv && shdrv->remove)
  60. return shdrv->remove(shdev);
  61. return 0;
  62. }
  63. static struct device sh_bus_devices[SH_NR_BUSES] = {
  64. {
  65. .bus_id = SH_BUS_NAME_VIRT,
  66. },
  67. };
  68. struct bus_type sh_bus_types[SH_NR_BUSES] = {
  69. {
  70. .name = SH_BUS_NAME_VIRT,
  71. .match = sh_bus_match,
  72. .probe = sh_bus_probe,
  73. .remove = sh_bus_remove,
  74. .suspend = sh_bus_suspend,
  75. .resume = sh_bus_resume,
  76. },
  77. };
  78. int sh_device_register(struct sh_dev *dev)
  79. {
  80. if (!dev)
  81. return -EINVAL;
  82. if (dev->bus_id < 0 || dev->bus_id >= SH_NR_BUSES) {
  83. printk(KERN_ERR "%s: bus_id invalid: %s bus: %d\n",
  84. __FUNCTION__, dev->name, dev->bus_id);
  85. return -EINVAL;
  86. }
  87. dev->dev.parent = &sh_bus_devices[dev->bus_id];
  88. dev->dev.bus = &sh_bus_types[dev->bus_id];
  89. /* This is needed for USB OHCI to work */
  90. if (dev->dma_mask)
  91. dev->dev.dma_mask = dev->dma_mask;
  92. if (dev->coherent_dma_mask)
  93. dev->dev.coherent_dma_mask = dev->coherent_dma_mask;
  94. snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u",
  95. dev->name, dev->dev_id);
  96. printk(KERN_INFO "Registering SH device '%s'. Parent at %s\n",
  97. dev->dev.bus_id, dev->dev.parent->bus_id);
  98. return device_register(&dev->dev);
  99. }
  100. void sh_device_unregister(struct sh_dev *dev)
  101. {
  102. device_unregister(&dev->dev);
  103. }
  104. int sh_driver_register(struct sh_driver *drv)
  105. {
  106. if (!drv)
  107. return -EINVAL;
  108. if (drv->bus_id < 0 || drv->bus_id >= SH_NR_BUSES) {
  109. printk(KERN_ERR "%s: bus_id invalid: bus: %d device %d\n",
  110. __FUNCTION__, drv->bus_id, drv->dev_id);
  111. return -EINVAL;
  112. }
  113. drv->drv.bus = &sh_bus_types[drv->bus_id];
  114. return driver_register(&drv->drv);
  115. }
  116. void sh_driver_unregister(struct sh_driver *drv)
  117. {
  118. driver_unregister(&drv->drv);
  119. }
  120. static int __init sh_bus_init(void)
  121. {
  122. int i, ret = 0;
  123. for (i = 0; i < SH_NR_BUSES; i++) {
  124. ret = device_register(&sh_bus_devices[i]);
  125. if (ret != 0) {
  126. printk(KERN_ERR "Unable to register bus device %s\n",
  127. sh_bus_devices[i].bus_id);
  128. continue;
  129. }
  130. ret = bus_register(&sh_bus_types[i]);
  131. if (ret != 0) {
  132. printk(KERN_ERR "Unable to register bus %s\n",
  133. sh_bus_types[i].name);
  134. device_unregister(&sh_bus_devices[i]);
  135. }
  136. }
  137. printk(KERN_INFO "SH Virtual Bus initialized\n");
  138. return ret;
  139. }
  140. static void __exit sh_bus_exit(void)
  141. {
  142. int i;
  143. for (i = 0; i < SH_NR_BUSES; i++) {
  144. bus_unregister(&sh_bus_types[i]);
  145. device_unregister(&sh_bus_devices[i]);
  146. }
  147. }
  148. module_init(sh_bus_init);
  149. module_exit(sh_bus_exit);
  150. MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
  151. MODULE_DESCRIPTION("SH Virtual Bus");
  152. MODULE_LICENSE("GPL");
  153. EXPORT_SYMBOL(sh_bus_types);
  154. EXPORT_SYMBOL(sh_device_register);
  155. EXPORT_SYMBOL(sh_device_unregister);
  156. EXPORT_SYMBOL(sh_driver_register);
  157. EXPORT_SYMBOL(sh_driver_unregister);