bridge.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 2001 Red Hat, Inc. All rights reserved.
  3.  *
  4.  * This software may be freely redistributed under the terms
  5.  *  of the GNU public license.
  6.  * 
  7.  * You should have received a copy of the GNU General Public License
  8.  * along with this program; if not, write to the Free Software
  9.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10.  *
  11.  *  Author: Arjan van de Ven <arjanv@redhat.com>
  12.  *
  13.  */
  14. /*
  15.  * Generic PCI driver for PCI bridges for powermanagement purposes
  16.  *
  17.  */
  18. #include <linux/config.h> 
  19. #include <linux/module.h>
  20. #include <linux/kernel.h>
  21. #include <linux/pci.h>
  22. #include <linux/init.h>
  23. static struct pci_device_id bridge_pci_table[] __devinitdata = {
  24.         {/* handle all PCI bridges */
  25. class:          ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
  26. class_mask:     ~0,
  27. vendor:         PCI_ANY_ID,
  28. device:         PCI_ANY_ID,
  29. subvendor:      PCI_ANY_ID,
  30. subdevice:      PCI_ANY_ID,
  31. },
  32.         {0,},
  33. };
  34. static int bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id);
  35. static int pci_bridge_save_state_bus(struct pci_bus *bus, int force);
  36. int pci_generic_resume_compare(struct pci_dev *pdev);
  37. int pci_bridge_force_restore = 0;
  38. static int __init bridge_setup(char *str)
  39. {
  40. if (!strcmp(str,"force"))
  41. pci_bridge_force_restore = 1;
  42. else if (!strcmp(str,"noforce"))
  43. pci_bridge_force_restore = 0;
  44. return 0;
  45. }
  46. __setup("resume=",bridge_setup);
  47. static int pci_bridge_save_state_bus(struct pci_bus *bus, int force)
  48. {
  49. struct list_head *list;
  50. int error = 0;
  51. list_for_each(list, &bus->children) {
  52. error = pci_bridge_save_state_bus(pci_bus_b(list),force);
  53. if (error) return error;
  54. }
  55. list_for_each(list, &bus->devices) {
  56. pci_generic_suspend_save(pci_dev_b(list),0);
  57. }
  58. return 0;
  59. }
  60. static int pci_bridge_restore_state_bus(struct pci_bus *bus, int force)
  61. {
  62. struct list_head *list;
  63. int error = 0;
  64. static int printed_warning=0;
  65. list_for_each(list, &bus->children) {
  66. error = pci_bridge_restore_state_bus(pci_bus_b(list),force);
  67. if (error) return error;
  68. }
  69. list_for_each(list, &bus->devices) {
  70. if (force)
  71. pci_generic_resume_restore(pci_dev_b(list));
  72. else {
  73. error = pci_generic_resume_compare(pci_dev_b(list));
  74. if (error && !printed_warning++) { 
  75. printk(KERN_WARNING "resume warning: bios doesn't restore PCI state properlyn");
  76. printk(KERN_WARNING "resume warning: if resume failed, try booting with resume=forcen");
  77. }
  78. if (error)
  79. return error;
  80. }
  81. }
  82. return 0;
  83. }
  84. static int bridge_suspend(struct pci_dev *dev, u32 force)
  85. {
  86. pci_generic_suspend_save(dev,force);
  87. if (dev->subordinate)
  88. pci_bridge_save_state_bus(dev->subordinate,force);
  89. return 0;
  90. }
  91. static int bridge_resume(struct pci_dev *dev)
  92. {
  93. pci_generic_resume_restore(dev);
  94. if (dev->subordinate)
  95. pci_bridge_restore_state_bus(dev->subordinate,pci_bridge_force_restore);
  96. return 0;
  97. }
  98. MODULE_DEVICE_TABLE(pci, bridge_pci_table);
  99. static struct pci_driver bridge_ops = {
  100.         name:           "PCI Bridge",   
  101.         id_table:       bridge_pci_table,
  102.         probe:          bridge_probe,    
  103.         suspend:  bridge_suspend,
  104.         resume:  bridge_resume
  105. };
  106. static int __devinit bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  107. {
  108. return 0;
  109. }
  110. static int __init bridge_init(void) 
  111. {
  112.         pci_register_driver(&bridge_ops);
  113.         return 0;
  114. }
  115. static void __exit bridge_exit(void)
  116. {
  117.         pci_unregister_driver(&bridge_ops);
  118. module_init(bridge_init)
  119. module_exit(bridge_exit)