ppc_sys.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * arch/ppc/syslib/ppc_sys.c
  3. *
  4. * PPC System library functions
  5. *
  6. * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  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 <linux/string.h>
  17. #include <asm/ppc_sys.h>
  18. int (*ppc_sys_device_fixup) (struct platform_device * pdev);
  19. static int ppc_sys_inited;
  20. void __init identify_ppc_sys_by_id(u32 id)
  21. {
  22. unsigned int i = 0;
  23. while (1) {
  24. if ((ppc_sys_specs[i].mask & id) == ppc_sys_specs[i].value)
  25. break;
  26. i++;
  27. }
  28. cur_ppc_sys_spec = &ppc_sys_specs[i];
  29. return;
  30. }
  31. void __init identify_ppc_sys_by_name(char *name)
  32. {
  33. unsigned int i = 0;
  34. while (ppc_sys_specs[i].ppc_sys_name[0])
  35. {
  36. if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
  37. break;
  38. i++;
  39. }
  40. cur_ppc_sys_spec = &ppc_sys_specs[i];
  41. return;
  42. }
  43. static int __init count_sys_specs(void)
  44. {
  45. int i = 0;
  46. while (ppc_sys_specs[i].ppc_sys_name[0])
  47. i++;
  48. return i;
  49. }
  50. static int __init find_chip_by_name_and_id(char *name, u32 id)
  51. {
  52. int ret = -1;
  53. unsigned int i = 0;
  54. unsigned int j = 0;
  55. unsigned int dups = 0;
  56. unsigned char matched[count_sys_specs()];
  57. while (ppc_sys_specs[i].ppc_sys_name[0]) {
  58. if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
  59. matched[j++] = i;
  60. i++;
  61. }
  62. ret = i;
  63. if (j != 0) {
  64. for (i = 0; i < j; i++) {
  65. if ((ppc_sys_specs[matched[i]].mask & id) ==
  66. ppc_sys_specs[matched[i]].value) {
  67. ret = matched[i];
  68. dups++;
  69. }
  70. }
  71. ret = (dups == 1) ? ret : (-1 * dups);
  72. }
  73. return ret;
  74. }
  75. void __init identify_ppc_sys_by_name_and_id(char *name, u32 id)
  76. {
  77. int i = find_chip_by_name_and_id(name, id);
  78. BUG_ON(i < 0);
  79. cur_ppc_sys_spec = &ppc_sys_specs[i];
  80. }
  81. /* Update all memory resources by paddr, call before platform_device_register */
  82. void __init
  83. ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
  84. {
  85. int i;
  86. for (i = 0; i < pdev->num_resources; i++) {
  87. struct resource *r = &pdev->resource[i];
  88. if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) {
  89. r->start += paddr;
  90. r->end += paddr;
  91. }
  92. }
  93. }
  94. /* Get platform_data pointer out of platform device, call before platform_device_register */
  95. void *__init ppc_sys_get_pdata(enum ppc_sys_devices dev)
  96. {
  97. return ppc_sys_platform_devices[dev].dev.platform_data;
  98. }
  99. void ppc_sys_device_remove(enum ppc_sys_devices dev)
  100. {
  101. unsigned int i;
  102. if (ppc_sys_inited) {
  103. platform_device_unregister(&ppc_sys_platform_devices[dev]);
  104. } else {
  105. if (cur_ppc_sys_spec == NULL)
  106. return;
  107. for (i = 0; i < cur_ppc_sys_spec->num_devices; i++)
  108. if (cur_ppc_sys_spec->device_list[i] == dev)
  109. cur_ppc_sys_spec->device_list[i] = -1;
  110. }
  111. }
  112. static int __init ppc_sys_init(void)
  113. {
  114. unsigned int i, dev_id, ret = 0;
  115. BUG_ON(cur_ppc_sys_spec == NULL);
  116. for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
  117. dev_id = cur_ppc_sys_spec->device_list[i];
  118. if (dev_id != -1) {
  119. if (ppc_sys_device_fixup != NULL)
  120. ppc_sys_device_fixup(&ppc_sys_platform_devices
  121. [dev_id]);
  122. if (platform_device_register
  123. (&ppc_sys_platform_devices[dev_id])) {
  124. ret = 1;
  125. printk(KERN_ERR
  126. "unable to register device %d\n",
  127. dev_id);
  128. }
  129. }
  130. }
  131. ppc_sys_inited = 1;
  132. return ret;
  133. }
  134. subsys_initcall(ppc_sys_init);