ppc_sys.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * arch/ppc/syslib/ppc_sys.c
  3. *
  4. * PPC System library functions
  5. *
  6. * Maintainer: Kumar Gala <kumar.gala@freescale.com>
  7. *
  8. * Copyright 2005 Freescale Semiconductor Inc.
  9. * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify it
  12. * under the terms of the GNU General Public License as published by the
  13. * Free Software Foundation; either version 2 of the License, or (at your
  14. * option) any later version.
  15. */
  16. #include <asm/ppc_sys.h>
  17. int (*ppc_sys_device_fixup) (struct platform_device * pdev);
  18. static int ppc_sys_inited;
  19. void __init identify_ppc_sys_by_id(u32 id)
  20. {
  21. unsigned int i = 0;
  22. while (1) {
  23. if ((ppc_sys_specs[i].mask & id) == ppc_sys_specs[i].value)
  24. break;
  25. i++;
  26. }
  27. cur_ppc_sys_spec = &ppc_sys_specs[i];
  28. return;
  29. }
  30. void __init identify_ppc_sys_by_name(char *name)
  31. {
  32. unsigned int i = 0;
  33. while (ppc_sys_specs[i].ppc_sys_name[0])
  34. {
  35. if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
  36. break;
  37. i++;
  38. }
  39. cur_ppc_sys_spec = &ppc_sys_specs[i];
  40. return;
  41. }
  42. static int __init count_sys_specs(void)
  43. {
  44. int i = 0;
  45. while (ppc_sys_specs[i].ppc_sys_name[0])
  46. i++;
  47. return i;
  48. }
  49. static int __init find_chip_by_name_and_id(char *name, u32 id)
  50. {
  51. int ret = -1;
  52. unsigned int i = 0;
  53. unsigned int j = 0;
  54. unsigned int dups = 0;
  55. unsigned char matched[count_sys_specs()];
  56. while (ppc_sys_specs[i].ppc_sys_name[0]) {
  57. if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
  58. matched[j++] = i;
  59. i++;
  60. }
  61. if (j != 0) {
  62. for (i = 0; i < j; i++) {
  63. if ((ppc_sys_specs[matched[i]].mask & id) ==
  64. ppc_sys_specs[matched[i]].value) {
  65. ret = matched[i];
  66. dups++;
  67. }
  68. }
  69. ret = (dups == 1) ? ret : (-1 * dups);
  70. }
  71. return ret;
  72. }
  73. void __init identify_ppc_sys_by_name_and_id(char *name, u32 id)
  74. {
  75. int i = find_chip_by_name_and_id(name, id);
  76. BUG_ON(i < 0);
  77. cur_ppc_sys_spec = &ppc_sys_specs[i];
  78. }
  79. /* Update all memory resources by paddr, call before platform_device_register */
  80. void __init
  81. ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
  82. {
  83. int i;
  84. for (i = 0; i < pdev->num_resources; i++) {
  85. struct resource *r = &pdev->resource[i];
  86. if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) {
  87. r->start += paddr;
  88. r->end += paddr;
  89. }
  90. }
  91. }
  92. /* Get platform_data pointer out of platform device, call before platform_device_register */
  93. void *__init ppc_sys_get_pdata(enum ppc_sys_devices dev)
  94. {
  95. return ppc_sys_platform_devices[dev].dev.platform_data;
  96. }
  97. void ppc_sys_device_remove(enum ppc_sys_devices dev)
  98. {
  99. unsigned int i;
  100. if (ppc_sys_inited) {
  101. platform_device_unregister(&ppc_sys_platform_devices[dev]);
  102. } else {
  103. if (cur_ppc_sys_spec == NULL)
  104. return;
  105. for (i = 0; i < cur_ppc_sys_spec->num_devices; i++)
  106. if (cur_ppc_sys_spec->device_list[i] == dev)
  107. cur_ppc_sys_spec->device_list[i] = -1;
  108. }
  109. }
  110. static int __init ppc_sys_init(void)
  111. {
  112. unsigned int i, dev_id, ret = 0;
  113. BUG_ON(cur_ppc_sys_spec == NULL);
  114. for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
  115. dev_id = cur_ppc_sys_spec->device_list[i];
  116. if (dev_id != -1) {
  117. if (ppc_sys_device_fixup != NULL)
  118. ppc_sys_device_fixup(&ppc_sys_platform_devices
  119. [dev_id]);
  120. if (platform_device_register
  121. (&ppc_sys_platform_devices[dev_id])) {
  122. ret = 1;
  123. printk(KERN_ERR
  124. "unable to register device %d\n",
  125. dev_id);
  126. }
  127. }
  128. }
  129. ppc_sys_inited = 1;
  130. return ret;
  131. }
  132. subsys_initcall(ppc_sys_init);