dev-pcmcia.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
  7. */
  8. #include <linux/init.h>
  9. #include <linux/kernel.h>
  10. #include <asm/bootinfo.h>
  11. #include <linux/platform_device.h>
  12. #include <bcm63xx_cs.h>
  13. #include <bcm63xx_cpu.h>
  14. #include <bcm63xx_dev_pcmcia.h>
  15. #include <bcm63xx_io.h>
  16. #include <bcm63xx_regs.h>
  17. static struct resource pcmcia_resources[] = {
  18. /* pcmcia registers */
  19. {
  20. /* start & end filled at runtime */
  21. .flags = IORESOURCE_MEM,
  22. },
  23. /* pcmcia memory zone resources */
  24. {
  25. .start = BCM_PCMCIA_COMMON_BASE_PA,
  26. .end = BCM_PCMCIA_COMMON_END_PA,
  27. .flags = IORESOURCE_MEM,
  28. },
  29. {
  30. .start = BCM_PCMCIA_ATTR_BASE_PA,
  31. .end = BCM_PCMCIA_ATTR_END_PA,
  32. .flags = IORESOURCE_MEM,
  33. },
  34. {
  35. .start = BCM_PCMCIA_IO_BASE_PA,
  36. .end = BCM_PCMCIA_IO_END_PA,
  37. .flags = IORESOURCE_MEM,
  38. },
  39. /* PCMCIA irq */
  40. {
  41. /* start filled at runtime */
  42. .flags = IORESOURCE_IRQ,
  43. },
  44. /* declare PCMCIA IO resource also */
  45. {
  46. .start = BCM_PCMCIA_IO_BASE_PA,
  47. .end = BCM_PCMCIA_IO_END_PA,
  48. .flags = IORESOURCE_IO,
  49. },
  50. };
  51. static struct bcm63xx_pcmcia_platform_data pd;
  52. static struct platform_device bcm63xx_pcmcia_device = {
  53. .name = "bcm63xx_pcmcia",
  54. .id = 0,
  55. .num_resources = ARRAY_SIZE(pcmcia_resources),
  56. .resource = pcmcia_resources,
  57. .dev = {
  58. .platform_data = &pd,
  59. },
  60. };
  61. static int __init config_pcmcia_cs(unsigned int cs,
  62. u32 base, unsigned int size)
  63. {
  64. int ret;
  65. ret = bcm63xx_set_cs_status(cs, 0);
  66. if (!ret)
  67. ret = bcm63xx_set_cs_base(cs, base, size);
  68. if (!ret)
  69. ret = bcm63xx_set_cs_status(cs, 1);
  70. return ret;
  71. }
  72. static const struct {
  73. unsigned int cs;
  74. unsigned int base;
  75. unsigned int size;
  76. } pcmcia_cs[3] __initconst = {
  77. {
  78. .cs = MPI_CS_PCMCIA_COMMON,
  79. .base = BCM_PCMCIA_COMMON_BASE_PA,
  80. .size = BCM_PCMCIA_COMMON_SIZE
  81. },
  82. {
  83. .cs = MPI_CS_PCMCIA_ATTR,
  84. .base = BCM_PCMCIA_ATTR_BASE_PA,
  85. .size = BCM_PCMCIA_ATTR_SIZE
  86. },
  87. {
  88. .cs = MPI_CS_PCMCIA_IO,
  89. .base = BCM_PCMCIA_IO_BASE_PA,
  90. .size = BCM_PCMCIA_IO_SIZE
  91. },
  92. };
  93. int __init bcm63xx_pcmcia_register(void)
  94. {
  95. int ret, i;
  96. if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
  97. return 0;
  98. /* use correct pcmcia ready gpio depending on processor */
  99. switch (bcm63xx_get_cpu_id()) {
  100. case BCM6348_CPU_ID:
  101. pd.ready_gpio = 22;
  102. break;
  103. case BCM6358_CPU_ID:
  104. pd.ready_gpio = 18;
  105. break;
  106. default:
  107. return -ENODEV;
  108. }
  109. pcmcia_resources[0].start = bcm63xx_regset_address(RSET_PCMCIA);
  110. pcmcia_resources[0].end = pcmcia_resources[0].start +
  111. RSET_PCMCIA_SIZE - 1;
  112. pcmcia_resources[4].start = bcm63xx_get_irq_number(IRQ_PCMCIA);
  113. /* configure pcmcia chip selects */
  114. for (i = 0; i < 3; i++) {
  115. ret = config_pcmcia_cs(pcmcia_cs[i].cs,
  116. pcmcia_cs[i].base,
  117. pcmcia_cs[i].size);
  118. if (ret)
  119. goto out_err;
  120. }
  121. return platform_device_register(&bcm63xx_pcmcia_device);
  122. out_err:
  123. pr_err("unable to set pcmcia chip select\n");
  124. return ret;
  125. }