Commit 5b85e04e93f9a2963e88156cae8629ee72efd890
Committed by
Dominik Brodowski
1 parent
20fffee818
Exists in
master
and in
7 other branches
pcmcia/sa1100: don't put machine specific init functions in .init.text
These are called by sa11x0_drv_pcmcia_probe (which is marked now with __devinit) so they can go to .devinit.text now, too. This fixes: WARNING: drivers/pcmcia/sa1100_cs.o(.text+0x10): Section mismatch in reference from the function sa11x0_drv_pcmcia_probe() to the function .init.text:pcmcia_simpad_init() The function sa11x0_drv_pcmcia_probe() references the function __init pcmcia_simpad_init(). This is often because sa11x0_drv_pcmcia_probe lacks a __init annotation or the annotation of pcmcia_simpad_init is wrong. and a similar warning for pcmcia_collie_init, pcmcia_cerf_init, pcmcia_h3600_init and pcmcia_shannon_init. While at it mark pcmcia_assabet_init with __devinit, too. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> CC: Russell King <linux@arm.linux.org.uk> CC: Eric Miao <eric.y.miao@gmail.com> CC: linux-arm-kernel@lists.infradead.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Showing 7 changed files with 7 additions and 7 deletions Inline Diff
drivers/pcmcia/pxa2xx_sharpsl.c
1 | /* | 1 | /* |
2 | * Sharp SL-C7xx Series PCMCIA routines | 2 | * Sharp SL-C7xx Series PCMCIA routines |
3 | * | 3 | * |
4 | * Copyright (c) 2004-2005 Richard Purdie | 4 | * Copyright (c) 2004-2005 Richard Purdie |
5 | * | 5 | * |
6 | * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c | 6 | * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | 20 | ||
21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
24 | #include <asm/hardware/scoop.h> | 24 | #include <asm/hardware/scoop.h> |
25 | 25 | ||
26 | #include "soc_common.h" | 26 | #include "soc_common.h" |
27 | 27 | ||
28 | #define NO_KEEP_VS 0x0001 | 28 | #define NO_KEEP_VS 0x0001 |
29 | #define SCOOP_DEV platform_scoop_config->devs | 29 | #define SCOOP_DEV platform_scoop_config->devs |
30 | 30 | ||
31 | static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) | 31 | static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) |
32 | { | 32 | { |
33 | struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr]; | 33 | struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr]; |
34 | 34 | ||
35 | reset_scoop(scoopdev->dev); | 35 | reset_scoop(scoopdev->dev); |
36 | 36 | ||
37 | /* Shared power controls need to be handled carefully */ | 37 | /* Shared power controls need to be handled carefully */ |
38 | if (platform_scoop_config->power_ctrl) | 38 | if (platform_scoop_config->power_ctrl) |
39 | platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr); | 39 | platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr); |
40 | else | 40 | else |
41 | write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000); | 41 | write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000); |
42 | 42 | ||
43 | scoopdev->keep_vs = NO_KEEP_VS; | 43 | scoopdev->keep_vs = NO_KEEP_VS; |
44 | scoopdev->keep_rd = 0; | 44 | scoopdev->keep_rd = 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 47 | static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | if (platform_scoop_config->pcmcia_init) | 51 | if (platform_scoop_config->pcmcia_init) |
52 | platform_scoop_config->pcmcia_init(); | 52 | platform_scoop_config->pcmcia_init(); |
53 | 53 | ||
54 | /* Register interrupts */ | 54 | /* Register interrupts */ |
55 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { | 55 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { |
56 | struct pcmcia_irqs cd_irq; | 56 | struct pcmcia_irqs cd_irq; |
57 | 57 | ||
58 | cd_irq.sock = skt->nr; | 58 | cd_irq.sock = skt->nr; |
59 | cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; | 59 | cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; |
60 | cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; | 60 | cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; |
61 | ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); | 61 | ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); |
62 | 62 | ||
63 | if (ret) { | 63 | if (ret) { |
64 | printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); | 64 | printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); |
65 | return ret; | 65 | return ret; |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; | 69 | skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; |
70 | 70 | ||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 74 | static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
75 | { | 75 | { |
76 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { | 76 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { |
77 | struct pcmcia_irqs cd_irq; | 77 | struct pcmcia_irqs cd_irq; |
78 | 78 | ||
79 | cd_irq.sock = skt->nr; | 79 | cd_irq.sock = skt->nr; |
80 | cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; | 80 | cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; |
81 | cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; | 81 | cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; |
82 | soc_pcmcia_free_irqs(skt, &cd_irq, 1); | 82 | soc_pcmcia_free_irqs(skt, &cd_irq, 1); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | 86 | ||
87 | static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 87 | static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
88 | struct pcmcia_state *state) | 88 | struct pcmcia_state *state) |
89 | { | 89 | { |
90 | unsigned short cpr, csr; | 90 | unsigned short cpr, csr; |
91 | struct device *scoop = SCOOP_DEV[skt->nr].dev; | 91 | struct device *scoop = SCOOP_DEV[skt->nr].dev; |
92 | 92 | ||
93 | cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR); | 93 | cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR); |
94 | 94 | ||
95 | write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); | 95 | write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); |
96 | write_scoop_reg(scoop, SCOOP_ISR, 0x0000); | 96 | write_scoop_reg(scoop, SCOOP_ISR, 0x0000); |
97 | write_scoop_reg(scoop, SCOOP_IRM, 0x0000); | 97 | write_scoop_reg(scoop, SCOOP_IRM, 0x0000); |
98 | csr = read_scoop_reg(scoop, SCOOP_CSR); | 98 | csr = read_scoop_reg(scoop, SCOOP_CSR); |
99 | if (csr & 0x0004) { | 99 | if (csr & 0x0004) { |
100 | /* card eject */ | 100 | /* card eject */ |
101 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 101 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); |
102 | SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; | 102 | SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; |
103 | } | 103 | } |
104 | else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) { | 104 | else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) { |
105 | /* keep vs1,vs2 */ | 105 | /* keep vs1,vs2 */ |
106 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 106 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); |
107 | csr |= SCOOP_DEV[skt->nr].keep_vs; | 107 | csr |= SCOOP_DEV[skt->nr].keep_vs; |
108 | } | 108 | } |
109 | else if (cpr & 0x0003) { | 109 | else if (cpr & 0x0003) { |
110 | /* power on */ | 110 | /* power on */ |
111 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 111 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); |
112 | SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0); | 112 | SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0); |
113 | } | 113 | } |
114 | else { | 114 | else { |
115 | /* card detect */ | 115 | /* card detect */ |
116 | if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) { | 116 | if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) { |
117 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 117 | write_scoop_reg(scoop, SCOOP_CDR, 0x0000); |
118 | } else { | 118 | } else { |
119 | write_scoop_reg(scoop, SCOOP_CDR, 0x0002); | 119 | write_scoop_reg(scoop, SCOOP_CDR, 0x0002); |
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | state->detect = (csr & 0x0004) ? 0 : 1; | 123 | state->detect = (csr & 0x0004) ? 0 : 1; |
124 | state->ready = (csr & 0x0002) ? 1 : 0; | 124 | state->ready = (csr & 0x0002) ? 1 : 0; |
125 | state->bvd1 = (csr & 0x0010) ? 1 : 0; | 125 | state->bvd1 = (csr & 0x0010) ? 1 : 0; |
126 | state->bvd2 = (csr & 0x0020) ? 1 : 0; | 126 | state->bvd2 = (csr & 0x0020) ? 1 : 0; |
127 | state->wrprot = (csr & 0x0008) ? 1 : 0; | 127 | state->wrprot = (csr & 0x0008) ? 1 : 0; |
128 | state->vs_3v = (csr & 0x0040) ? 0 : 1; | 128 | state->vs_3v = (csr & 0x0040) ? 0 : 1; |
129 | state->vs_Xv = (csr & 0x0080) ? 0 : 1; | 129 | state->vs_Xv = (csr & 0x0080) ? 0 : 1; |
130 | 130 | ||
131 | if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { | 131 | if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { |
132 | printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); | 132 | printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); |
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | 136 | ||
137 | static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 137 | static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
138 | const socket_state_t *state) | 138 | const socket_state_t *state) |
139 | { | 139 | { |
140 | unsigned long flags; | 140 | unsigned long flags; |
141 | struct device *scoop = SCOOP_DEV[skt->nr].dev; | 141 | struct device *scoop = SCOOP_DEV[skt->nr].dev; |
142 | 142 | ||
143 | unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; | 143 | unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; |
144 | 144 | ||
145 | switch (state->Vcc) { | 145 | switch (state->Vcc) { |
146 | case 0: break; | 146 | case 0: break; |
147 | case 33: break; | 147 | case 33: break; |
148 | case 50: break; | 148 | case 50: break; |
149 | default: | 149 | default: |
150 | printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc); | 150 | printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc); |
151 | return -1; | 151 | return -1; |
152 | } | 152 | } |
153 | 153 | ||
154 | if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) { | 154 | if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) { |
155 | printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp); | 155 | printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp); |
156 | return -1; | 156 | return -1; |
157 | } | 157 | } |
158 | 158 | ||
159 | local_irq_save(flags); | 159 | local_irq_save(flags); |
160 | 160 | ||
161 | nmcr = (mcr = read_scoop_reg(scoop, SCOOP_MCR)) & ~0x0010; | 161 | nmcr = (mcr = read_scoop_reg(scoop, SCOOP_MCR)) & ~0x0010; |
162 | ncpr = (cpr = read_scoop_reg(scoop, SCOOP_CPR)) & ~0x0083; | 162 | ncpr = (cpr = read_scoop_reg(scoop, SCOOP_CPR)) & ~0x0083; |
163 | nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; | 163 | nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; |
164 | nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; | 164 | nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; |
165 | 165 | ||
166 | if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) { | 166 | if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) { |
167 | ncpr |= (state->Vcc == 33) ? 0x0002 : | 167 | ncpr |= (state->Vcc == 33) ? 0x0002 : |
168 | (state->Vcc == 50) ? 0x0002 : 0; | 168 | (state->Vcc == 50) ? 0x0002 : 0; |
169 | } else { | 169 | } else { |
170 | ncpr |= (state->Vcc == 33) ? 0x0001 : | 170 | ncpr |= (state->Vcc == 33) ? 0x0001 : |
171 | (state->Vcc == 50) ? 0x0002 : 0; | 171 | (state->Vcc == 50) ? 0x0002 : 0; |
172 | } | 172 | } |
173 | nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; | 173 | nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; |
174 | ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; | 174 | ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; |
175 | nccr |= (state->flags&SS_RESET)? 0x0080: 0; | 175 | nccr |= (state->flags&SS_RESET)? 0x0080: 0; |
176 | nimr |= ((skt->status&SS_DETECT) ? 0x0004 : 0)| | 176 | nimr |= ((skt->status&SS_DETECT) ? 0x0004 : 0)| |
177 | ((skt->status&SS_READY) ? 0x0002 : 0)| | 177 | ((skt->status&SS_READY) ? 0x0002 : 0)| |
178 | ((skt->status&SS_BATDEAD)? 0x0010 : 0)| | 178 | ((skt->status&SS_BATDEAD)? 0x0010 : 0)| |
179 | ((skt->status&SS_BATWARN)? 0x0020 : 0)| | 179 | ((skt->status&SS_BATWARN)? 0x0020 : 0)| |
180 | ((skt->status&SS_STSCHG) ? 0x0010 : 0)| | 180 | ((skt->status&SS_STSCHG) ? 0x0010 : 0)| |
181 | ((skt->status&SS_WRPROT) ? 0x0008 : 0); | 181 | ((skt->status&SS_WRPROT) ? 0x0008 : 0); |
182 | 182 | ||
183 | if (!(ncpr & 0x0003)) { | 183 | if (!(ncpr & 0x0003)) { |
184 | SCOOP_DEV[skt->nr].keep_rd = 0; | 184 | SCOOP_DEV[skt->nr].keep_rd = 0; |
185 | } else if (!SCOOP_DEV[skt->nr].keep_rd) { | 185 | } else if (!SCOOP_DEV[skt->nr].keep_rd) { |
186 | if (nccr & 0x0080) | 186 | if (nccr & 0x0080) |
187 | SCOOP_DEV[skt->nr].keep_rd = 1; | 187 | SCOOP_DEV[skt->nr].keep_rd = 1; |
188 | else | 188 | else |
189 | nccr |= 0x0080; | 189 | nccr |= 0x0080; |
190 | } | 190 | } |
191 | 191 | ||
192 | if (mcr != nmcr) | 192 | if (mcr != nmcr) |
193 | write_scoop_reg(scoop, SCOOP_MCR, nmcr); | 193 | write_scoop_reg(scoop, SCOOP_MCR, nmcr); |
194 | if (cpr != ncpr) { | 194 | if (cpr != ncpr) { |
195 | if (platform_scoop_config->power_ctrl) | 195 | if (platform_scoop_config->power_ctrl) |
196 | platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr); | 196 | platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr); |
197 | else | 197 | else |
198 | write_scoop_reg(scoop, SCOOP_CPR, ncpr); | 198 | write_scoop_reg(scoop, SCOOP_CPR, ncpr); |
199 | } | 199 | } |
200 | if (ccr != nccr) | 200 | if (ccr != nccr) |
201 | write_scoop_reg(scoop, SCOOP_CCR, nccr); | 201 | write_scoop_reg(scoop, SCOOP_CCR, nccr); |
202 | if (imr != nimr) | 202 | if (imr != nimr) |
203 | write_scoop_reg(scoop, SCOOP_IMR, nimr); | 203 | write_scoop_reg(scoop, SCOOP_IMR, nimr); |
204 | 204 | ||
205 | local_irq_restore(flags); | 205 | local_irq_restore(flags); |
206 | 206 | ||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 210 | static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
211 | { | 211 | { |
212 | sharpsl_pcmcia_init_reset(skt); | 212 | sharpsl_pcmcia_init_reset(skt); |
213 | 213 | ||
214 | /* Enable interrupt */ | 214 | /* Enable interrupt */ |
215 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); | 215 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); |
216 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); | 216 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); |
217 | SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; | 217 | SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; |
218 | } | 218 | } |
219 | 219 | ||
220 | static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 220 | static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
221 | { | 221 | { |
222 | sharpsl_pcmcia_init_reset(skt); | 222 | sharpsl_pcmcia_init_reset(skt); |
223 | } | 223 | } |
224 | 224 | ||
225 | static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { | 225 | static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { |
226 | .owner = THIS_MODULE, | 226 | .owner = THIS_MODULE, |
227 | .hw_init = sharpsl_pcmcia_hw_init, | 227 | .hw_init = sharpsl_pcmcia_hw_init, |
228 | .hw_shutdown = sharpsl_pcmcia_hw_shutdown, | 228 | .hw_shutdown = sharpsl_pcmcia_hw_shutdown, |
229 | .socket_state = sharpsl_pcmcia_socket_state, | 229 | .socket_state = sharpsl_pcmcia_socket_state, |
230 | .configure_socket = sharpsl_pcmcia_configure_socket, | 230 | .configure_socket = sharpsl_pcmcia_configure_socket, |
231 | .socket_init = sharpsl_pcmcia_socket_init, | 231 | .socket_init = sharpsl_pcmcia_socket_init, |
232 | .socket_suspend = sharpsl_pcmcia_socket_suspend, | 232 | .socket_suspend = sharpsl_pcmcia_socket_suspend, |
233 | .first = 0, | 233 | .first = 0, |
234 | .nr = 0, | 234 | .nr = 0, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | #ifdef CONFIG_SA1100_COLLIE | 237 | #ifdef CONFIG_SA1100_COLLIE |
238 | #include "sa11xx_base.h" | 238 | #include "sa11xx_base.h" |
239 | 239 | ||
240 | int __init pcmcia_collie_init(struct device *dev) | 240 | int __devinit pcmcia_collie_init(struct device *dev) |
241 | { | 241 | { |
242 | int ret = -ENODEV; | 242 | int ret = -ENODEV; |
243 | 243 | ||
244 | if (machine_is_collie()) | 244 | if (machine_is_collie()) |
245 | ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1); | 245 | ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1); |
246 | 246 | ||
247 | return ret; | 247 | return ret; |
248 | } | 248 | } |
249 | 249 | ||
250 | #else | 250 | #else |
251 | 251 | ||
252 | static struct platform_device *sharpsl_pcmcia_device; | 252 | static struct platform_device *sharpsl_pcmcia_device; |
253 | 253 | ||
254 | static int __init sharpsl_pcmcia_init(void) | 254 | static int __init sharpsl_pcmcia_init(void) |
255 | { | 255 | { |
256 | int ret; | 256 | int ret; |
257 | 257 | ||
258 | if (!platform_scoop_config) | 258 | if (!platform_scoop_config) |
259 | return -ENODEV; | 259 | return -ENODEV; |
260 | 260 | ||
261 | sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs; | 261 | sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs; |
262 | sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 262 | sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); |
263 | 263 | ||
264 | if (!sharpsl_pcmcia_device) | 264 | if (!sharpsl_pcmcia_device) |
265 | return -ENOMEM; | 265 | return -ENOMEM; |
266 | 266 | ||
267 | ret = platform_device_add_data(sharpsl_pcmcia_device, | 267 | ret = platform_device_add_data(sharpsl_pcmcia_device, |
268 | &sharpsl_pcmcia_ops, sizeof(sharpsl_pcmcia_ops)); | 268 | &sharpsl_pcmcia_ops, sizeof(sharpsl_pcmcia_ops)); |
269 | if (ret == 0) { | 269 | if (ret == 0) { |
270 | sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; | 270 | sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; |
271 | ret = platform_device_add(sharpsl_pcmcia_device); | 271 | ret = platform_device_add(sharpsl_pcmcia_device); |
272 | } | 272 | } |
273 | 273 | ||
274 | if (ret) | 274 | if (ret) |
275 | platform_device_put(sharpsl_pcmcia_device); | 275 | platform_device_put(sharpsl_pcmcia_device); |
276 | 276 | ||
277 | return ret; | 277 | return ret; |
278 | } | 278 | } |
279 | 279 | ||
280 | static void __exit sharpsl_pcmcia_exit(void) | 280 | static void __exit sharpsl_pcmcia_exit(void) |
281 | { | 281 | { |
282 | platform_device_unregister(sharpsl_pcmcia_device); | 282 | platform_device_unregister(sharpsl_pcmcia_device); |
283 | } | 283 | } |
284 | 284 | ||
285 | fs_initcall(sharpsl_pcmcia_init); | 285 | fs_initcall(sharpsl_pcmcia_init); |
286 | module_exit(sharpsl_pcmcia_exit); | 286 | module_exit(sharpsl_pcmcia_exit); |
287 | #endif | 287 | #endif |
288 | 288 | ||
289 | MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); | 289 | MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); |
290 | MODULE_LICENSE("GPL"); | 290 | MODULE_LICENSE("GPL"); |
291 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); | 291 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); |
292 | 292 |
drivers/pcmcia/sa1100_assabet.c
1 | /* | 1 | /* |
2 | * drivers/pcmcia/sa1100_assabet.c | 2 | * drivers/pcmcia/sa1100_assabet.c |
3 | * | 3 | * |
4 | * PCMCIA implementation routines for Assabet | 4 | * PCMCIA implementation routines for Assabet |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | 13 | ||
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
16 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
17 | #include <asm/signal.h> | 17 | #include <asm/signal.h> |
18 | #include <mach/assabet.h> | 18 | #include <mach/assabet.h> |
19 | 19 | ||
20 | #include "sa1100_generic.h" | 20 | #include "sa1100_generic.h" |
21 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | 22 | static struct pcmcia_irqs irqs[] = { |
23 | { 1, ASSABET_IRQ_GPIO_CF_CD, "CF CD" }, | 23 | { 1, ASSABET_IRQ_GPIO_CF_CD, "CF CD" }, |
24 | { 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" }, | 24 | { 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" }, |
25 | { 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" }, | 25 | { 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" }, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
29 | { | 29 | { |
30 | skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; | 30 | skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; |
31 | 31 | ||
32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
33 | } | 33 | } |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Release all resources. | 36 | * Release all resources. |
37 | */ | 37 | */ |
38 | static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 38 | static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
39 | { | 39 | { |
40 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 40 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
41 | } | 41 | } |
42 | 42 | ||
43 | static void | 43 | static void |
44 | assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 44 | assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
45 | { | 45 | { |
46 | unsigned long levels = GPLR; | 46 | unsigned long levels = GPLR; |
47 | 47 | ||
48 | state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1; | 48 | state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1; |
49 | state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0; | 49 | state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0; |
50 | state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0; | 50 | state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0; |
51 | state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0; | 51 | state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0; |
52 | state->wrprot = 0; /* Not available on Assabet. */ | 52 | state->wrprot = 0; /* Not available on Assabet. */ |
53 | state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ | 53 | state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ |
54 | state->vs_Xv = 0; | 54 | state->vs_Xv = 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | static int | 57 | static int |
58 | assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | 58 | assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) |
59 | { | 59 | { |
60 | unsigned int mask; | 60 | unsigned int mask; |
61 | 61 | ||
62 | switch (state->Vcc) { | 62 | switch (state->Vcc) { |
63 | case 0: | 63 | case 0: |
64 | mask = 0; | 64 | mask = 0; |
65 | break; | 65 | break; |
66 | 66 | ||
67 | case 50: | 67 | case 50: |
68 | printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n", | 68 | printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n", |
69 | __func__); | 69 | __func__); |
70 | 70 | ||
71 | case 33: /* Can only apply 3.3V to the CF slot. */ | 71 | case 33: /* Can only apply 3.3V to the CF slot. */ |
72 | mask = ASSABET_BCR_CF_PWR; | 72 | mask = ASSABET_BCR_CF_PWR; |
73 | break; | 73 | break; |
74 | 74 | ||
75 | default: | 75 | default: |
76 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__, | 76 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__, |
77 | state->Vcc); | 77 | state->Vcc); |
78 | return -1; | 78 | return -1; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Silently ignore Vpp, output enable, speaker enable. */ | 81 | /* Silently ignore Vpp, output enable, speaker enable. */ |
82 | 82 | ||
83 | if (state->flags & SS_RESET) | 83 | if (state->flags & SS_RESET) |
84 | mask |= ASSABET_BCR_CF_RST; | 84 | mask |= ASSABET_BCR_CF_RST; |
85 | 85 | ||
86 | ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask); | 86 | ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask); |
87 | 87 | ||
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | 90 | ||
91 | /* | 91 | /* |
92 | * Enable card status IRQs on (re-)initialisation. This can | 92 | * Enable card status IRQs on (re-)initialisation. This can |
93 | * be called at initialisation, power management event, or | 93 | * be called at initialisation, power management event, or |
94 | * pcmcia event. | 94 | * pcmcia event. |
95 | */ | 95 | */ |
96 | static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 96 | static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
97 | { | 97 | { |
98 | /* | 98 | /* |
99 | * Enable CF bus | 99 | * Enable CF bus |
100 | */ | 100 | */ |
101 | ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF); | 101 | ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF); |
102 | 102 | ||
103 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 103 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
104 | } | 104 | } |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * Disable card status IRQs on suspend. | 107 | * Disable card status IRQs on suspend. |
108 | */ | 108 | */ |
109 | static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 109 | static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
110 | { | 110 | { |
111 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 111 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
112 | 112 | ||
113 | /* | 113 | /* |
114 | * Tristate the CF bus signals. Also assert CF | 114 | * Tristate the CF bus signals. Also assert CF |
115 | * reset as per user guide page 4-11. | 115 | * reset as per user guide page 4-11. |
116 | */ | 116 | */ |
117 | ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); | 117 | ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); |
118 | } | 118 | } |
119 | 119 | ||
120 | static struct pcmcia_low_level assabet_pcmcia_ops = { | 120 | static struct pcmcia_low_level assabet_pcmcia_ops = { |
121 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | 122 | ||
123 | .hw_init = assabet_pcmcia_hw_init, | 123 | .hw_init = assabet_pcmcia_hw_init, |
124 | .hw_shutdown = assabet_pcmcia_hw_shutdown, | 124 | .hw_shutdown = assabet_pcmcia_hw_shutdown, |
125 | 125 | ||
126 | .socket_state = assabet_pcmcia_socket_state, | 126 | .socket_state = assabet_pcmcia_socket_state, |
127 | .configure_socket = assabet_pcmcia_configure_socket, | 127 | .configure_socket = assabet_pcmcia_configure_socket, |
128 | 128 | ||
129 | .socket_init = assabet_pcmcia_socket_init, | 129 | .socket_init = assabet_pcmcia_socket_init, |
130 | .socket_suspend = assabet_pcmcia_socket_suspend, | 130 | .socket_suspend = assabet_pcmcia_socket_suspend, |
131 | }; | 131 | }; |
132 | 132 | ||
133 | int pcmcia_assabet_init(struct device *dev) | 133 | int __devinit pcmcia_assabet_init(struct device *dev) |
134 | { | 134 | { |
135 | int ret = -ENODEV; | 135 | int ret = -ENODEV; |
136 | 136 | ||
137 | if (machine_is_assabet() && !machine_has_neponset()) | 137 | if (machine_is_assabet() && !machine_has_neponset()) |
138 | ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1); | 138 | ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1); |
139 | 139 | ||
140 | return ret; | 140 | return ret; |
141 | } | 141 | } |
142 | 142 |
drivers/pcmcia/sa1100_cerf.c
1 | /* | 1 | /* |
2 | * drivers/pcmcia/sa1100_cerf.c | 2 | * drivers/pcmcia/sa1100_cerf.c |
3 | * | 3 | * |
4 | * PCMCIA implementation routines for CerfBoard | 4 | * PCMCIA implementation routines for CerfBoard |
5 | * Based off the Assabet. | 5 | * Based off the Assabet. |
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | 13 | ||
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
16 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
17 | #include <mach/cerf.h> | 17 | #include <mach/cerf.h> |
18 | #include "sa1100_generic.h" | 18 | #include "sa1100_generic.h" |
19 | 19 | ||
20 | #define CERF_SOCKET 1 | 20 | #define CERF_SOCKET 1 |
21 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | 22 | static struct pcmcia_irqs irqs[] = { |
23 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" }, | 23 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" }, |
24 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" }, | 24 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" }, |
25 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" } | 25 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" } |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
29 | { | 29 | { |
30 | skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; | 30 | skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; |
31 | 31 | ||
32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
33 | } | 33 | } |
34 | 34 | ||
35 | static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 35 | static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
36 | { | 36 | { |
37 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 37 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
38 | } | 38 | } |
39 | 39 | ||
40 | static void | 40 | static void |
41 | cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 41 | cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
42 | { | 42 | { |
43 | unsigned long levels = GPLR; | 43 | unsigned long levels = GPLR; |
44 | 44 | ||
45 | state->detect = (levels & CERF_GPIO_CF_CD) ?0:1; | 45 | state->detect = (levels & CERF_GPIO_CF_CD) ?0:1; |
46 | state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0; | 46 | state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0; |
47 | state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0; | 47 | state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0; |
48 | state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0; | 48 | state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0; |
49 | state->wrprot = 0; | 49 | state->wrprot = 0; |
50 | state->vs_3v = 1; | 50 | state->vs_3v = 1; |
51 | state->vs_Xv = 0; | 51 | state->vs_Xv = 0; |
52 | } | 52 | } |
53 | 53 | ||
54 | static int | 54 | static int |
55 | cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 55 | cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
56 | const socket_state_t *state) | 56 | const socket_state_t *state) |
57 | { | 57 | { |
58 | switch (state->Vcc) { | 58 | switch (state->Vcc) { |
59 | case 0: | 59 | case 0: |
60 | case 50: | 60 | case 50: |
61 | case 33: | 61 | case 33: |
62 | break; | 62 | break; |
63 | 63 | ||
64 | default: | 64 | default: |
65 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | 65 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", |
66 | __func__, state->Vcc); | 66 | __func__, state->Vcc); |
67 | return -1; | 67 | return -1; |
68 | } | 68 | } |
69 | 69 | ||
70 | if (state->flags & SS_RESET) { | 70 | if (state->flags & SS_RESET) { |
71 | GPSR = CERF_GPIO_CF_RESET; | 71 | GPSR = CERF_GPIO_CF_RESET; |
72 | } else { | 72 | } else { |
73 | GPCR = CERF_GPIO_CF_RESET; | 73 | GPCR = CERF_GPIO_CF_RESET; |
74 | } | 74 | } |
75 | 75 | ||
76 | return 0; | 76 | return 0; |
77 | } | 77 | } |
78 | 78 | ||
79 | static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 79 | static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
80 | { | 80 | { |
81 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 81 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 84 | static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
85 | { | 85 | { |
86 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 86 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
87 | } | 87 | } |
88 | 88 | ||
89 | static struct pcmcia_low_level cerf_pcmcia_ops = { | 89 | static struct pcmcia_low_level cerf_pcmcia_ops = { |
90 | .owner = THIS_MODULE, | 90 | .owner = THIS_MODULE, |
91 | .hw_init = cerf_pcmcia_hw_init, | 91 | .hw_init = cerf_pcmcia_hw_init, |
92 | .hw_shutdown = cerf_pcmcia_hw_shutdown, | 92 | .hw_shutdown = cerf_pcmcia_hw_shutdown, |
93 | .socket_state = cerf_pcmcia_socket_state, | 93 | .socket_state = cerf_pcmcia_socket_state, |
94 | .configure_socket = cerf_pcmcia_configure_socket, | 94 | .configure_socket = cerf_pcmcia_configure_socket, |
95 | 95 | ||
96 | .socket_init = cerf_pcmcia_socket_init, | 96 | .socket_init = cerf_pcmcia_socket_init, |
97 | .socket_suspend = cerf_pcmcia_socket_suspend, | 97 | .socket_suspend = cerf_pcmcia_socket_suspend, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | int __init pcmcia_cerf_init(struct device *dev) | 100 | int __devinit pcmcia_cerf_init(struct device *dev) |
101 | { | 101 | { |
102 | int ret = -ENODEV; | 102 | int ret = -ENODEV; |
103 | 103 | ||
104 | if (machine_is_cerf()) | 104 | if (machine_is_cerf()) |
105 | ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1); | 105 | ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1); |
106 | 106 | ||
107 | return ret; | 107 | return ret; |
108 | } | 108 | } |
109 | 109 |
drivers/pcmcia/sa1100_generic.c
1 | /*====================================================================== | 1 | /*====================================================================== |
2 | 2 | ||
3 | Device driver for the PCMCIA control functionality of StrongARM | 3 | Device driver for the PCMCIA control functionality of StrongARM |
4 | SA-1100 microprocessors. | 4 | SA-1100 microprocessors. |
5 | 5 | ||
6 | The contents of this file are subject to the Mozilla Public | 6 | The contents of this file are subject to the Mozilla Public |
7 | License Version 1.1 (the "License"); you may not use this file | 7 | License Version 1.1 (the "License"); you may not use this file |
8 | except in compliance with the License. You may obtain a copy of | 8 | except in compliance with the License. You may obtain a copy of |
9 | the License at http://www.mozilla.org/MPL/ | 9 | the License at http://www.mozilla.org/MPL/ |
10 | 10 | ||
11 | Software distributed under the License is distributed on an "AS | 11 | Software distributed under the License is distributed on an "AS |
12 | IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | 12 | IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
13 | implied. See the License for the specific language governing | 13 | implied. See the License for the specific language governing |
14 | rights and limitations under the License. | 14 | rights and limitations under the License. |
15 | 15 | ||
16 | The initial developer of the original code is John G. Dorsey | 16 | The initial developer of the original code is John G. Dorsey |
17 | <john+@cs.cmu.edu>. Portions created by John G. Dorsey are | 17 | <john+@cs.cmu.edu>. Portions created by John G. Dorsey are |
18 | Copyright (C) 1999 John G. Dorsey. All Rights Reserved. | 18 | Copyright (C) 1999 John G. Dorsey. All Rights Reserved. |
19 | 19 | ||
20 | Alternatively, the contents of this file may be used under the | 20 | Alternatively, the contents of this file may be used under the |
21 | terms of the GNU Public License version 2 (the "GPL"), in which | 21 | terms of the GNU Public License version 2 (the "GPL"), in which |
22 | case the provisions of the GPL are applicable instead of the | 22 | case the provisions of the GPL are applicable instead of the |
23 | above. If you wish to allow the use of your version of this file | 23 | above. If you wish to allow the use of your version of this file |
24 | only under the terms of the GPL and not to allow others to use | 24 | only under the terms of the GPL and not to allow others to use |
25 | your version of this file under the MPL, indicate your decision | 25 | your version of this file under the MPL, indicate your decision |
26 | by deleting the provisions above and replace them with the notice | 26 | by deleting the provisions above and replace them with the notice |
27 | and other provisions required by the GPL. If you do not delete | 27 | and other provisions required by the GPL. If you do not delete |
28 | the provisions above, a recipient may use your version of this | 28 | the provisions above, a recipient may use your version of this |
29 | file under either the MPL or the GPL. | 29 | file under either the MPL or the GPL. |
30 | 30 | ||
31 | ======================================================================*/ | 31 | ======================================================================*/ |
32 | 32 | ||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | 37 | ||
38 | #include <pcmcia/ss.h> | 38 | #include <pcmcia/ss.h> |
39 | 39 | ||
40 | #include <asm/hardware/scoop.h> | 40 | #include <asm/hardware/scoop.h> |
41 | 41 | ||
42 | #include "sa1100_generic.h" | 42 | #include "sa1100_generic.h" |
43 | 43 | ||
44 | int __init pcmcia_collie_init(struct device *dev); | 44 | int __init pcmcia_collie_init(struct device *dev); |
45 | 45 | ||
46 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | 46 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { |
47 | #ifdef CONFIG_SA1100_ASSABET | 47 | #ifdef CONFIG_SA1100_ASSABET |
48 | pcmcia_assabet_init, | 48 | pcmcia_assabet_init, |
49 | #endif | 49 | #endif |
50 | #ifdef CONFIG_SA1100_CERF | 50 | #ifdef CONFIG_SA1100_CERF |
51 | pcmcia_cerf_init, | 51 | pcmcia_cerf_init, |
52 | #endif | 52 | #endif |
53 | #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) | 53 | #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) |
54 | pcmcia_h3600_init, | 54 | pcmcia_h3600_init, |
55 | #endif | 55 | #endif |
56 | #ifdef CONFIG_SA1100_SHANNON | 56 | #ifdef CONFIG_SA1100_SHANNON |
57 | pcmcia_shannon_init, | 57 | pcmcia_shannon_init, |
58 | #endif | 58 | #endif |
59 | #ifdef CONFIG_SA1100_SIMPAD | 59 | #ifdef CONFIG_SA1100_SIMPAD |
60 | pcmcia_simpad_init, | 60 | pcmcia_simpad_init, |
61 | #endif | 61 | #endif |
62 | #ifdef CONFIG_SA1100_COLLIE | 62 | #ifdef CONFIG_SA1100_COLLIE |
63 | pcmcia_collie_init, | 63 | pcmcia_collie_init, |
64 | #endif | 64 | #endif |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) | 67 | static int __devinit sa11x0_drv_pcmcia_probe(struct platform_device *dev) |
68 | { | 68 | { |
69 | int i, ret = -ENODEV; | 69 | int i, ret = -ENODEV; |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Initialise any "on-board" PCMCIA sockets. | 72 | * Initialise any "on-board" PCMCIA sockets. |
73 | */ | 73 | */ |
74 | for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) { | 74 | for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) { |
75 | ret = sa11x0_pcmcia_hw_init[i](&dev->dev); | 75 | ret = sa11x0_pcmcia_hw_init[i](&dev->dev); |
76 | if (ret == 0) | 76 | if (ret == 0) |
77 | break; | 77 | break; |
78 | } | 78 | } |
79 | 79 | ||
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) | 83 | static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) |
84 | { | 84 | { |
85 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); | 85 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); |
86 | int i; | 86 | int i; |
87 | 87 | ||
88 | platform_set_drvdata(dev, NULL); | 88 | platform_set_drvdata(dev, NULL); |
89 | 89 | ||
90 | for (i = 0; i < sinfo->nskt; i++) | 90 | for (i = 0; i < sinfo->nskt; i++) |
91 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 91 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
92 | 92 | ||
93 | kfree(sinfo); | 93 | kfree(sinfo); |
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct platform_driver sa11x0_pcmcia_driver = { | 97 | static struct platform_driver sa11x0_pcmcia_driver = { |
98 | .driver = { | 98 | .driver = { |
99 | .name = "sa11x0-pcmcia", | 99 | .name = "sa11x0-pcmcia", |
100 | .owner = THIS_MODULE, | 100 | .owner = THIS_MODULE, |
101 | }, | 101 | }, |
102 | .probe = sa11x0_drv_pcmcia_probe, | 102 | .probe = sa11x0_drv_pcmcia_probe, |
103 | .remove = sa11x0_drv_pcmcia_remove, | 103 | .remove = sa11x0_drv_pcmcia_remove, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | /* sa11x0_pcmcia_init() | 106 | /* sa11x0_pcmcia_init() |
107 | * ^^^^^^^^^^^^^^^^^^^^ | 107 | * ^^^^^^^^^^^^^^^^^^^^ |
108 | * | 108 | * |
109 | * This routine performs low-level PCMCIA initialization and then | 109 | * This routine performs low-level PCMCIA initialization and then |
110 | * registers this socket driver with Card Services. | 110 | * registers this socket driver with Card Services. |
111 | * | 111 | * |
112 | * Returns: 0 on success, -ve error code on failure | 112 | * Returns: 0 on success, -ve error code on failure |
113 | */ | 113 | */ |
114 | static int __init sa11x0_pcmcia_init(void) | 114 | static int __init sa11x0_pcmcia_init(void) |
115 | { | 115 | { |
116 | return platform_driver_register(&sa11x0_pcmcia_driver); | 116 | return platform_driver_register(&sa11x0_pcmcia_driver); |
117 | } | 117 | } |
118 | 118 | ||
119 | /* sa11x0_pcmcia_exit() | 119 | /* sa11x0_pcmcia_exit() |
120 | * ^^^^^^^^^^^^^^^^^^^^ | 120 | * ^^^^^^^^^^^^^^^^^^^^ |
121 | * Invokes the low-level kernel service to free IRQs associated with this | 121 | * Invokes the low-level kernel service to free IRQs associated with this |
122 | * socket controller and reset GPIO edge detection. | 122 | * socket controller and reset GPIO edge detection. |
123 | */ | 123 | */ |
124 | static void __exit sa11x0_pcmcia_exit(void) | 124 | static void __exit sa11x0_pcmcia_exit(void) |
125 | { | 125 | { |
126 | platform_driver_unregister(&sa11x0_pcmcia_driver); | 126 | platform_driver_unregister(&sa11x0_pcmcia_driver); |
127 | } | 127 | } |
128 | 128 | ||
129 | MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>"); | 129 | MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>"); |
130 | MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11x0 Socket Controller"); | 130 | MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11x0 Socket Controller"); |
131 | MODULE_LICENSE("Dual MPL/GPL"); | 131 | MODULE_LICENSE("Dual MPL/GPL"); |
132 | 132 | ||
133 | fs_initcall(sa11x0_pcmcia_init); | 133 | fs_initcall(sa11x0_pcmcia_init); |
134 | module_exit(sa11x0_pcmcia_exit); | 134 | module_exit(sa11x0_pcmcia_exit); |
135 | 135 |
drivers/pcmcia/sa1100_h3600.c
1 | /* | 1 | /* |
2 | * drivers/pcmcia/sa1100_h3600.c | 2 | * drivers/pcmcia/sa1100_h3600.c |
3 | * | 3 | * |
4 | * PCMCIA implementation routines for H3600 | 4 | * PCMCIA implementation routines for H3600 |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | 14 | ||
15 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
16 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
17 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
18 | #include <mach/h3xxx.h> | 18 | #include <mach/h3xxx.h> |
19 | 19 | ||
20 | #include "sa1100_generic.h" | 20 | #include "sa1100_generic.h" |
21 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | 22 | static struct pcmcia_irqs irqs[] = { |
23 | { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */ | 23 | { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */ |
24 | { .sock = 1, .str = "PCMCIA CD1" } | 24 | { .sock = 1, .str = "PCMCIA CD1" } |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 27 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
28 | { | 28 | { |
29 | int err; | 29 | int err; |
30 | 30 | ||
31 | switch (skt->nr) { | 31 | switch (skt->nr) { |
32 | case 0: | 32 | case 0: |
33 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); | 33 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); |
34 | if (err) | 34 | if (err) |
35 | goto err00; | 35 | goto err00; |
36 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0); | 36 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0); |
37 | if (err) | 37 | if (err) |
38 | goto err01; | 38 | goto err01; |
39 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0); | 39 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0); |
40 | 40 | ||
41 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0"); | 41 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0"); |
42 | if (err) | 42 | if (err) |
43 | goto err01; | 43 | goto err01; |
44 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0); | 44 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0); |
45 | if (err) | 45 | if (err) |
46 | goto err02; | 46 | goto err02; |
47 | irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0); | 47 | irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0); |
48 | 48 | ||
49 | err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); | 49 | err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); |
50 | if (err) | 50 | if (err) |
51 | goto err02; | 51 | goto err02; |
52 | err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0); | 52 | err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0); |
53 | if (err) | 53 | if (err) |
54 | goto err03; | 54 | goto err03; |
55 | err = gpio_request(H3XXX_EGPIO_OPT_ON, "OPT ON"); | 55 | err = gpio_request(H3XXX_EGPIO_OPT_ON, "OPT ON"); |
56 | if (err) | 56 | if (err) |
57 | goto err03; | 57 | goto err03; |
58 | err = gpio_direction_output(H3XXX_EGPIO_OPT_ON, 0); | 58 | err = gpio_direction_output(H3XXX_EGPIO_OPT_ON, 0); |
59 | if (err) | 59 | if (err) |
60 | goto err04; | 60 | goto err04; |
61 | err = gpio_request(H3XXX_EGPIO_OPT_RESET, "OPT RESET"); | 61 | err = gpio_request(H3XXX_EGPIO_OPT_RESET, "OPT RESET"); |
62 | if (err) | 62 | if (err) |
63 | goto err04; | 63 | goto err04; |
64 | err = gpio_direction_output(H3XXX_EGPIO_OPT_RESET, 0); | 64 | err = gpio_direction_output(H3XXX_EGPIO_OPT_RESET, 0); |
65 | if (err) | 65 | if (err) |
66 | goto err05; | 66 | goto err05; |
67 | err = gpio_request(H3XXX_EGPIO_CARD_RESET, "PCMCIA CARD RESET"); | 67 | err = gpio_request(H3XXX_EGPIO_CARD_RESET, "PCMCIA CARD RESET"); |
68 | if (err) | 68 | if (err) |
69 | goto err05; | 69 | goto err05; |
70 | err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0); | 70 | err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0); |
71 | if (err) | 71 | if (err) |
72 | goto err06; | 72 | goto err06; |
73 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 73 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
74 | if (err) | 74 | if (err) |
75 | goto err06; | 75 | goto err06; |
76 | break; | 76 | break; |
77 | case 1: | 77 | case 1: |
78 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); | 78 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); |
79 | if (err) | 79 | if (err) |
80 | goto err10; | 80 | goto err10; |
81 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1); | 81 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1); |
82 | if (err) | 82 | if (err) |
83 | goto err11; | 83 | goto err11; |
84 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1); | 84 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1); |
85 | 85 | ||
86 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1"); | 86 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1"); |
87 | if (err) | 87 | if (err) |
88 | goto err11; | 88 | goto err11; |
89 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1); | 89 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1); |
90 | if (err) | 90 | if (err) |
91 | goto err12; | 91 | goto err12; |
92 | irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1); | 92 | irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1); |
93 | 93 | ||
94 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 94 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
95 | if (err) | 95 | if (err) |
96 | goto err12; | 96 | goto err12; |
97 | break; | 97 | break; |
98 | } | 98 | } |
99 | return 0; | 99 | return 0; |
100 | 100 | ||
101 | err06: gpio_free(H3XXX_EGPIO_CARD_RESET); | 101 | err06: gpio_free(H3XXX_EGPIO_CARD_RESET); |
102 | err05: gpio_free(H3XXX_EGPIO_OPT_RESET); | 102 | err05: gpio_free(H3XXX_EGPIO_OPT_RESET); |
103 | err04: gpio_free(H3XXX_EGPIO_OPT_ON); | 103 | err04: gpio_free(H3XXX_EGPIO_OPT_ON); |
104 | err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); | 104 | err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); |
105 | err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | 105 | err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0); |
106 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | 106 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); |
107 | err00: return err; | 107 | err00: return err; |
108 | 108 | ||
109 | err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | 109 | err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0); |
110 | err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | 110 | err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); |
111 | err10: return err; | 111 | err10: return err; |
112 | } | 112 | } |
113 | 113 | ||
114 | static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 114 | static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
115 | { | 115 | { |
116 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 116 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
117 | 117 | ||
118 | switch (skt->nr) { | 118 | switch (skt->nr) { |
119 | case 0: | 119 | case 0: |
120 | /* Disable CF bus: */ | 120 | /* Disable CF bus: */ |
121 | gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0); | 121 | gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0); |
122 | gpio_set_value(H3XXX_EGPIO_OPT_ON, 0); | 122 | gpio_set_value(H3XXX_EGPIO_OPT_ON, 0); |
123 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1); | 123 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1); |
124 | 124 | ||
125 | gpio_free(H3XXX_EGPIO_CARD_RESET); | 125 | gpio_free(H3XXX_EGPIO_CARD_RESET); |
126 | gpio_free(H3XXX_EGPIO_OPT_RESET); | 126 | gpio_free(H3XXX_EGPIO_OPT_RESET); |
127 | gpio_free(H3XXX_EGPIO_OPT_ON); | 127 | gpio_free(H3XXX_EGPIO_OPT_ON); |
128 | gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); | 128 | gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); |
129 | gpio_free(H3XXX_GPIO_PCMCIA_CD0); | 129 | gpio_free(H3XXX_GPIO_PCMCIA_CD0); |
130 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | 130 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); |
131 | break; | 131 | break; |
132 | case 1: | 132 | case 1: |
133 | gpio_free(H3XXX_GPIO_PCMCIA_CD1); | 133 | gpio_free(H3XXX_GPIO_PCMCIA_CD1); |
134 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ1); | 134 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ1); |
135 | break; | 135 | break; |
136 | } | 136 | } |
137 | } | 137 | } |
138 | 138 | ||
139 | static void | 139 | static void |
140 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 140 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
141 | { | 141 | { |
142 | switch (skt->nr) { | 142 | switch (skt->nr) { |
143 | case 0: | 143 | case 0: |
144 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); | 144 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); |
145 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); | 145 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); |
146 | state->bvd1 = 0; | 146 | state->bvd1 = 0; |
147 | state->bvd2 = 0; | 147 | state->bvd2 = 0; |
148 | state->wrprot = 0; /* Not available on H3600. */ | 148 | state->wrprot = 0; /* Not available on H3600. */ |
149 | state->vs_3v = 0; | 149 | state->vs_3v = 0; |
150 | state->vs_Xv = 0; | 150 | state->vs_Xv = 0; |
151 | break; | 151 | break; |
152 | 152 | ||
153 | case 1: | 153 | case 1: |
154 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1); | 154 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1); |
155 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1); | 155 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1); |
156 | state->bvd1 = 0; | 156 | state->bvd1 = 0; |
157 | state->bvd2 = 0; | 157 | state->bvd2 = 0; |
158 | state->wrprot = 0; /* Not available on H3600. */ | 158 | state->wrprot = 0; /* Not available on H3600. */ |
159 | state->vs_3v = 0; | 159 | state->vs_3v = 0; |
160 | state->vs_Xv = 0; | 160 | state->vs_Xv = 0; |
161 | break; | 161 | break; |
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | static int | 165 | static int |
166 | h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | 166 | h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) |
167 | { | 167 | { |
168 | if (state->Vcc != 0 && state->Vcc != 33 && state->Vcc != 50) { | 168 | if (state->Vcc != 0 && state->Vcc != 33 && state->Vcc != 50) { |
169 | printk(KERN_ERR "h3600_pcmcia: unrecognized Vcc %u.%uV\n", | 169 | printk(KERN_ERR "h3600_pcmcia: unrecognized Vcc %u.%uV\n", |
170 | state->Vcc / 10, state->Vcc % 10); | 170 | state->Vcc / 10, state->Vcc % 10); |
171 | return -1; | 171 | return -1; |
172 | } | 172 | } |
173 | 173 | ||
174 | gpio_set_value(H3XXX_EGPIO_CARD_RESET, !!(state->flags & SS_RESET)); | 174 | gpio_set_value(H3XXX_EGPIO_CARD_RESET, !!(state->flags & SS_RESET)); |
175 | 175 | ||
176 | /* Silently ignore Vpp, output enable, speaker enable. */ | 176 | /* Silently ignore Vpp, output enable, speaker enable. */ |
177 | 177 | ||
178 | return 0; | 178 | return 0; |
179 | } | 179 | } |
180 | 180 | ||
181 | static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 181 | static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
182 | { | 182 | { |
183 | /* Enable CF bus: */ | 183 | /* Enable CF bus: */ |
184 | gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 1); | 184 | gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 1); |
185 | gpio_set_value(H3XXX_EGPIO_OPT_ON, 1); | 185 | gpio_set_value(H3XXX_EGPIO_OPT_ON, 1); |
186 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0); | 186 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0); |
187 | 187 | ||
188 | msleep(10); | 188 | msleep(10); |
189 | 189 | ||
190 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 190 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
191 | } | 191 | } |
192 | 192 | ||
193 | static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 193 | static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
194 | { | 194 | { |
195 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 195 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
196 | 196 | ||
197 | /* | 197 | /* |
198 | * FIXME: This doesn't fit well. We don't have the mechanism in | 198 | * FIXME: This doesn't fit well. We don't have the mechanism in |
199 | * the generic PCMCIA layer to deal with the idea of two sockets | 199 | * the generic PCMCIA layer to deal with the idea of two sockets |
200 | * on one bus. We rely on the cs.c behaviour shutting down | 200 | * on one bus. We rely on the cs.c behaviour shutting down |
201 | * socket 0 then socket 1. | 201 | * socket 0 then socket 1. |
202 | */ | 202 | */ |
203 | if (skt->nr == 1) { | 203 | if (skt->nr == 1) { |
204 | gpio_set_value(H3XXX_EGPIO_OPT_ON, 0); | 204 | gpio_set_value(H3XXX_EGPIO_OPT_ON, 0); |
205 | gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0); | 205 | gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0); |
206 | /* hmm, does this suck power? */ | 206 | /* hmm, does this suck power? */ |
207 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1); | 207 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1); |
208 | } | 208 | } |
209 | } | 209 | } |
210 | 210 | ||
211 | struct pcmcia_low_level h3600_pcmcia_ops = { | 211 | struct pcmcia_low_level h3600_pcmcia_ops = { |
212 | .owner = THIS_MODULE, | 212 | .owner = THIS_MODULE, |
213 | .hw_init = h3600_pcmcia_hw_init, | 213 | .hw_init = h3600_pcmcia_hw_init, |
214 | .hw_shutdown = h3600_pcmcia_hw_shutdown, | 214 | .hw_shutdown = h3600_pcmcia_hw_shutdown, |
215 | .socket_state = h3600_pcmcia_socket_state, | 215 | .socket_state = h3600_pcmcia_socket_state, |
216 | .configure_socket = h3600_pcmcia_configure_socket, | 216 | .configure_socket = h3600_pcmcia_configure_socket, |
217 | 217 | ||
218 | .socket_init = h3600_pcmcia_socket_init, | 218 | .socket_init = h3600_pcmcia_socket_init, |
219 | .socket_suspend = h3600_pcmcia_socket_suspend, | 219 | .socket_suspend = h3600_pcmcia_socket_suspend, |
220 | }; | 220 | }; |
221 | 221 | ||
222 | int __init pcmcia_h3600_init(struct device *dev) | 222 | int __devinit pcmcia_h3600_init(struct device *dev) |
223 | { | 223 | { |
224 | int ret = -ENODEV; | 224 | int ret = -ENODEV; |
225 | 225 | ||
226 | if (machine_is_h3600() || machine_is_h3100()) | 226 | if (machine_is_h3600() || machine_is_h3100()) |
227 | ret = sa11xx_drv_pcmcia_probe(dev, &h3600_pcmcia_ops, 0, 2); | 227 | ret = sa11xx_drv_pcmcia_probe(dev, &h3600_pcmcia_ops, 0, 2); |
228 | 228 | ||
229 | return ret; | 229 | return ret; |
230 | } | 230 | } |
231 | 231 |
drivers/pcmcia/sa1100_shannon.c
1 | /* | 1 | /* |
2 | * drivers/pcmcia/sa1100_shannon.c | 2 | * drivers/pcmcia/sa1100_shannon.c |
3 | * | 3 | * |
4 | * PCMCIA implementation routines for Shannon | 4 | * PCMCIA implementation routines for Shannon |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | 11 | ||
12 | #include <mach/hardware.h> | 12 | #include <mach/hardware.h> |
13 | #include <asm/mach-types.h> | 13 | #include <asm/mach-types.h> |
14 | #include <mach/shannon.h> | 14 | #include <mach/shannon.h> |
15 | #include <asm/irq.h> | 15 | #include <asm/irq.h> |
16 | #include "sa1100_generic.h" | 16 | #include "sa1100_generic.h" |
17 | 17 | ||
18 | static struct pcmcia_irqs irqs[] = { | 18 | static struct pcmcia_irqs irqs[] = { |
19 | { 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" }, | 19 | { 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" }, |
20 | { 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" }, | 20 | { 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" }, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 23 | static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
24 | { | 24 | { |
25 | /* All those are inputs */ | 25 | /* All those are inputs */ |
26 | GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | | 26 | GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | |
27 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); | 27 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); |
28 | GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | | 28 | GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | |
29 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); | 29 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); |
30 | 30 | ||
31 | skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; | 31 | skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; |
32 | 32 | ||
33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 36 | static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
37 | { | 37 | { |
38 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 38 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
39 | } | 39 | } |
40 | 40 | ||
41 | static void | 41 | static void |
42 | shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 42 | shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
43 | struct pcmcia_state *state) | 43 | struct pcmcia_state *state) |
44 | { | 44 | { |
45 | unsigned long levels = GPLR; | 45 | unsigned long levels = GPLR; |
46 | 46 | ||
47 | switch (skt->nr) { | 47 | switch (skt->nr) { |
48 | case 0: | 48 | case 0: |
49 | state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1; | 49 | state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1; |
50 | state->ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0; | 50 | state->ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0; |
51 | state->wrprot = 0; /* Not available on Shannon. */ | 51 | state->wrprot = 0; /* Not available on Shannon. */ |
52 | state->bvd1 = 1; | 52 | state->bvd1 = 1; |
53 | state->bvd2 = 1; | 53 | state->bvd2 = 1; |
54 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ | 54 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ |
55 | state->vs_Xv = 0; | 55 | state->vs_Xv = 0; |
56 | break; | 56 | break; |
57 | 57 | ||
58 | case 1: | 58 | case 1: |
59 | state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1; | 59 | state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1; |
60 | state->ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0; | 60 | state->ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0; |
61 | state->wrprot = 0; /* Not available on Shannon. */ | 61 | state->wrprot = 0; /* Not available on Shannon. */ |
62 | state->bvd1 = 1; | 62 | state->bvd1 = 1; |
63 | state->bvd2 = 1; | 63 | state->bvd2 = 1; |
64 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ | 64 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ |
65 | state->vs_Xv = 0; | 65 | state->vs_Xv = 0; |
66 | break; | 66 | break; |
67 | } | 67 | } |
68 | } | 68 | } |
69 | 69 | ||
70 | static int | 70 | static int |
71 | shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 71 | shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
72 | const socket_state_t *state) | 72 | const socket_state_t *state) |
73 | { | 73 | { |
74 | switch (state->Vcc) { | 74 | switch (state->Vcc) { |
75 | case 0: /* power off */ | 75 | case 0: /* power off */ |
76 | printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __func__); | 76 | printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __func__); |
77 | break; | 77 | break; |
78 | case 50: | 78 | case 50: |
79 | printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __func__); | 79 | printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __func__); |
80 | case 33: | 80 | case 33: |
81 | break; | 81 | break; |
82 | default: | 82 | default: |
83 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | 83 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", |
84 | __func__, state->Vcc); | 84 | __func__, state->Vcc); |
85 | return -1; | 85 | return -1; |
86 | } | 86 | } |
87 | 87 | ||
88 | printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __func__); | 88 | printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __func__); |
89 | 89 | ||
90 | /* Silently ignore Vpp, output enable, speaker enable. */ | 90 | /* Silently ignore Vpp, output enable, speaker enable. */ |
91 | 91 | ||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 95 | static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
96 | { | 96 | { |
97 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 97 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 100 | static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
101 | { | 101 | { |
102 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 102 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
103 | } | 103 | } |
104 | 104 | ||
105 | static struct pcmcia_low_level shannon_pcmcia_ops = { | 105 | static struct pcmcia_low_level shannon_pcmcia_ops = { |
106 | .owner = THIS_MODULE, | 106 | .owner = THIS_MODULE, |
107 | .hw_init = shannon_pcmcia_hw_init, | 107 | .hw_init = shannon_pcmcia_hw_init, |
108 | .hw_shutdown = shannon_pcmcia_hw_shutdown, | 108 | .hw_shutdown = shannon_pcmcia_hw_shutdown, |
109 | .socket_state = shannon_pcmcia_socket_state, | 109 | .socket_state = shannon_pcmcia_socket_state, |
110 | .configure_socket = shannon_pcmcia_configure_socket, | 110 | .configure_socket = shannon_pcmcia_configure_socket, |
111 | 111 | ||
112 | .socket_init = shannon_pcmcia_socket_init, | 112 | .socket_init = shannon_pcmcia_socket_init, |
113 | .socket_suspend = shannon_pcmcia_socket_suspend, | 113 | .socket_suspend = shannon_pcmcia_socket_suspend, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | int __init pcmcia_shannon_init(struct device *dev) | 116 | int __devinit pcmcia_shannon_init(struct device *dev) |
117 | { | 117 | { |
118 | int ret = -ENODEV; | 118 | int ret = -ENODEV; |
119 | 119 | ||
120 | if (machine_is_shannon()) | 120 | if (machine_is_shannon()) |
121 | ret = sa11xx_drv_pcmcia_probe(dev, &shannon_pcmcia_ops, 0, 2); | 121 | ret = sa11xx_drv_pcmcia_probe(dev, &shannon_pcmcia_ops, 0, 2); |
122 | 122 | ||
123 | return ret; | 123 | return ret; |
124 | } | 124 | } |
125 | 125 |
drivers/pcmcia/sa1100_simpad.c
1 | /* | 1 | /* |
2 | * drivers/pcmcia/sa1100_simpad.c | 2 | * drivers/pcmcia/sa1100_simpad.c |
3 | * | 3 | * |
4 | * PCMCIA implementation routines for simpad | 4 | * PCMCIA implementation routines for simpad |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | 11 | ||
12 | #include <mach/hardware.h> | 12 | #include <mach/hardware.h> |
13 | #include <asm/mach-types.h> | 13 | #include <asm/mach-types.h> |
14 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
15 | #include <mach/simpad.h> | 15 | #include <mach/simpad.h> |
16 | #include "sa1100_generic.h" | 16 | #include "sa1100_generic.h" |
17 | 17 | ||
18 | extern long get_cs3_shadow(void); | 18 | extern long get_cs3_shadow(void); |
19 | extern void set_cs3_bit(int value); | 19 | extern void set_cs3_bit(int value); |
20 | extern void clear_cs3_bit(int value); | 20 | extern void clear_cs3_bit(int value); |
21 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | 22 | static struct pcmcia_irqs irqs[] = { |
23 | { 1, IRQ_GPIO_CF_CD, "CF_CD" }, | 23 | { 1, IRQ_GPIO_CF_CD, "CF_CD" }, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 26 | static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
27 | { | 27 | { |
28 | 28 | ||
29 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 29 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
30 | 30 | ||
31 | skt->socket.pci_irq = IRQ_GPIO_CF_IRQ; | 31 | skt->socket.pci_irq = IRQ_GPIO_CF_IRQ; |
32 | 32 | ||
33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 36 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
37 | { | 37 | { |
38 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 38 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
39 | 39 | ||
40 | /* Disable CF bus: */ | 40 | /* Disable CF bus: */ |
41 | //set_cs3_bit(PCMCIA_BUFF_DIS); | 41 | //set_cs3_bit(PCMCIA_BUFF_DIS); |
42 | clear_cs3_bit(PCMCIA_RESET); | 42 | clear_cs3_bit(PCMCIA_RESET); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void | 45 | static void |
46 | simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
47 | struct pcmcia_state *state) | 47 | struct pcmcia_state *state) |
48 | { | 48 | { |
49 | unsigned long levels = GPLR; | 49 | unsigned long levels = GPLR; |
50 | long cs3reg = get_cs3_shadow(); | 50 | long cs3reg = get_cs3_shadow(); |
51 | 51 | ||
52 | state->detect=((levels & GPIO_CF_CD)==0)?1:0; | 52 | state->detect=((levels & GPIO_CF_CD)==0)?1:0; |
53 | state->ready=(levels & GPIO_CF_IRQ)?1:0; | 53 | state->ready=(levels & GPIO_CF_IRQ)?1:0; |
54 | state->bvd1=1; /* Not available on Simpad. */ | 54 | state->bvd1=1; /* Not available on Simpad. */ |
55 | state->bvd2=1; /* Not available on Simpad. */ | 55 | state->bvd2=1; /* Not available on Simpad. */ |
56 | state->wrprot=0; /* Not available on Simpad. */ | 56 | state->wrprot=0; /* Not available on Simpad. */ |
57 | 57 | ||
58 | if((cs3reg & 0x0c) == 0x0c) { | 58 | if((cs3reg & 0x0c) == 0x0c) { |
59 | state->vs_3v=0; | 59 | state->vs_3v=0; |
60 | state->vs_Xv=0; | 60 | state->vs_Xv=0; |
61 | } else { | 61 | } else { |
62 | state->vs_3v=1; | 62 | state->vs_3v=1; |
63 | state->vs_Xv=0; | 63 | state->vs_Xv=0; |
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | static int | 67 | static int |
68 | simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 68 | simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
69 | const socket_state_t *state) | 69 | const socket_state_t *state) |
70 | { | 70 | { |
71 | unsigned long flags; | 71 | unsigned long flags; |
72 | 72 | ||
73 | local_irq_save(flags); | 73 | local_irq_save(flags); |
74 | 74 | ||
75 | /* Murphy: see table of MIC2562a-1 */ | 75 | /* Murphy: see table of MIC2562a-1 */ |
76 | switch (state->Vcc) { | 76 | switch (state->Vcc) { |
77 | case 0: | 77 | case 0: |
78 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 78 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
79 | break; | 79 | break; |
80 | 80 | ||
81 | case 33: | 81 | case 33: |
82 | clear_cs3_bit(VCC_3V_EN|EN1); | 82 | clear_cs3_bit(VCC_3V_EN|EN1); |
83 | set_cs3_bit(VCC_5V_EN|EN0); | 83 | set_cs3_bit(VCC_5V_EN|EN0); |
84 | break; | 84 | break; |
85 | 85 | ||
86 | case 50: | 86 | case 50: |
87 | clear_cs3_bit(VCC_5V_EN|EN1); | 87 | clear_cs3_bit(VCC_5V_EN|EN1); |
88 | set_cs3_bit(VCC_3V_EN|EN0); | 88 | set_cs3_bit(VCC_3V_EN|EN0); |
89 | break; | 89 | break; |
90 | 90 | ||
91 | default: | 91 | default: |
92 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | 92 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", |
93 | __func__, state->Vcc); | 93 | __func__, state->Vcc); |
94 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 94 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
95 | local_irq_restore(flags); | 95 | local_irq_restore(flags); |
96 | return -1; | 96 | return -1; |
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
100 | local_irq_restore(flags); | 100 | local_irq_restore(flags); |
101 | 101 | ||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 105 | static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
106 | { | 106 | { |
107 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 107 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
108 | } | 108 | } |
109 | 109 | ||
110 | static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 110 | static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
111 | { | 111 | { |
112 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 112 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
113 | set_cs3_bit(PCMCIA_RESET); | 113 | set_cs3_bit(PCMCIA_RESET); |
114 | } | 114 | } |
115 | 115 | ||
116 | static struct pcmcia_low_level simpad_pcmcia_ops = { | 116 | static struct pcmcia_low_level simpad_pcmcia_ops = { |
117 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
118 | .hw_init = simpad_pcmcia_hw_init, | 118 | .hw_init = simpad_pcmcia_hw_init, |
119 | .hw_shutdown = simpad_pcmcia_hw_shutdown, | 119 | .hw_shutdown = simpad_pcmcia_hw_shutdown, |
120 | .socket_state = simpad_pcmcia_socket_state, | 120 | .socket_state = simpad_pcmcia_socket_state, |
121 | .configure_socket = simpad_pcmcia_configure_socket, | 121 | .configure_socket = simpad_pcmcia_configure_socket, |
122 | .socket_init = simpad_pcmcia_socket_init, | 122 | .socket_init = simpad_pcmcia_socket_init, |
123 | .socket_suspend = simpad_pcmcia_socket_suspend, | 123 | .socket_suspend = simpad_pcmcia_socket_suspend, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | int __init pcmcia_simpad_init(struct device *dev) | 126 | int __devinit pcmcia_simpad_init(struct device *dev) |
127 | { | 127 | { |
128 | int ret = -ENODEV; | 128 | int ret = -ENODEV; |
129 | 129 | ||
130 | if (machine_is_simpad()) | 130 | if (machine_is_simpad()) |
131 | ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1); | 131 | ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1); |
132 | 132 | ||
133 | return ret; | 133 | return ret; |
134 | } | 134 | } |
135 | 135 |