Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dev-pcmcia.c
Go to the documentation of this file.
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 <[email protected]>
7  */
8 
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <asm/bootinfo.h>
12 #include <linux/platform_device.h>
13 #include <bcm63xx_cs.h>
14 #include <bcm63xx_cpu.h>
15 #include <bcm63xx_dev_pcmcia.h>
16 #include <bcm63xx_io.h>
17 #include <bcm63xx_regs.h>
18 
19 static struct resource pcmcia_resources[] = {
20  /* pcmcia registers */
21  {
22  /* start & end filled at runtime */
23  .flags = IORESOURCE_MEM,
24  },
25 
26  /* pcmcia memory zone resources */
27  {
30  .flags = IORESOURCE_MEM,
31  },
32  {
33  .start = BCM_PCMCIA_ATTR_BASE_PA,
35  .flags = IORESOURCE_MEM,
36  },
37  {
38  .start = BCM_PCMCIA_IO_BASE_PA,
39  .end = BCM_PCMCIA_IO_END_PA,
40  .flags = IORESOURCE_MEM,
41  },
42 
43  /* PCMCIA irq */
44  {
45  /* start filled at runtime */
46  .flags = IORESOURCE_IRQ,
47  },
48 
49  /* declare PCMCIA IO resource also */
50  {
51  .start = BCM_PCMCIA_IO_BASE_PA,
52  .end = BCM_PCMCIA_IO_END_PA,
53  .flags = IORESOURCE_IO,
54  },
55 };
56 
57 static struct bcm63xx_pcmcia_platform_data pd;
58 
59 static struct platform_device bcm63xx_pcmcia_device = {
60  .name = "bcm63xx_pcmcia",
61  .id = 0,
62  .num_resources = ARRAY_SIZE(pcmcia_resources),
63  .resource = pcmcia_resources,
64  .dev = {
65  .platform_data = &pd,
66  },
67 };
68 
69 static int __init config_pcmcia_cs(unsigned int cs,
70  u32 base, unsigned int size)
71 {
72  int ret;
73 
74  ret = bcm63xx_set_cs_status(cs, 0);
75  if (!ret)
76  ret = bcm63xx_set_cs_base(cs, base, size);
77  if (!ret)
78  ret = bcm63xx_set_cs_status(cs, 1);
79  return ret;
80 }
81 
82 static const struct {
83  unsigned int cs;
84  unsigned int base;
85  unsigned int size;
86 } pcmcia_cs[3] __initconst = {
87  {
91  },
92  {
93  .cs = MPI_CS_PCMCIA_ATTR,
95  .size = BCM_PCMCIA_ATTR_SIZE
96  },
97  {
98  .cs = MPI_CS_PCMCIA_IO,
99  .base = BCM_PCMCIA_IO_BASE_PA,
100  .size = BCM_PCMCIA_IO_SIZE
101  },
102 };
103 
105 {
106  int ret, i;
107 
108  if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
109  return 0;
110 
111  /* use correct pcmcia ready gpio depending on processor */
112  switch (bcm63xx_get_cpu_id()) {
113  case BCM6348_CPU_ID:
114  pd.ready_gpio = 22;
115  break;
116 
117  case BCM6358_CPU_ID:
118  pd.ready_gpio = 18;
119  break;
120 
121  default:
122  return -ENODEV;
123  }
124 
125  pcmcia_resources[0].start = bcm63xx_regset_address(RSET_PCMCIA);
126  pcmcia_resources[0].end = pcmcia_resources[0].start +
127  RSET_PCMCIA_SIZE - 1;
128  pcmcia_resources[4].start = bcm63xx_get_irq_number(IRQ_PCMCIA);
129 
130  /* configure pcmcia chip selects */
131  for (i = 0; i < 3; i++) {
132  ret = config_pcmcia_cs(pcmcia_cs[i].cs,
133  pcmcia_cs[i].base,
134  pcmcia_cs[i].size);
135  if (ret)
136  goto out_err;
137  }
138 
139  return platform_device_register(&bcm63xx_pcmcia_device);
140 
141 out_err:
142  printk(KERN_ERR "unable to set pcmcia chip select\n");
143  return ret;
144 }