diff options
author | Russell King - ARM Linux <linux@arm.linux.org.uk> | 2009-03-29 14:42:44 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2009-11-09 02:30:11 -0500 |
commit | 701a5dc05ad99a06958b3f97cb69d99b47cebee3 (patch) | |
tree | f91ab0cb2179fa771dfb3c9929bc09c7580ec3f8 /drivers | |
parent | da4f007375197d6683461b995d404b01a7fdf2f5 (diff) |
PCMCIA: sa1111: wrap soc_pcmcia_socket to contain sa1111 specific data
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/pxa2xx_base.c | 19 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_base.h | 3 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_lubbock.c | 10 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_badge4.c | 7 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_jornada720.c | 20 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_neponset.c | 9 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_generic.c | 58 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_generic.h | 14 | ||||
-rw-r--r-- | drivers/pcmcia/sa11xx_base.c | 21 | ||||
-rw-r--r-- | drivers/pcmcia/sa11xx_base.h | 2 |
10 files changed, 123 insertions, 40 deletions
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 3cb4fd21cc2f..c9c104b57c59 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -228,7 +228,7 @@ static const char *skt_names[] = { | |||
228 | #define SKT_DEV_INFO_SIZE(n) \ | 228 | #define SKT_DEV_INFO_SIZE(n) \ |
229 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) | 229 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) |
230 | 230 | ||
231 | static int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) | 231 | int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) |
232 | { | 232 | { |
233 | skt->res_skt.start = _PCMCIA(skt->nr); | 233 | skt->res_skt.start = _PCMCIA(skt->nr); |
234 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; | 234 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; |
@@ -253,9 +253,18 @@ static int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
253 | return soc_pcmcia_add_one(skt); | 253 | return soc_pcmcia_add_one(skt); |
254 | } | 254 | } |
255 | 255 | ||
256 | void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops) | ||
257 | { | ||
258 | /* Provide our PXA2xx specific timing routines. */ | ||
259 | ops->set_timing = pxa2xx_pcmcia_set_timing; | ||
260 | #ifdef CONFIG_CPU_FREQ | ||
261 | ops->frequency_change = pxa2xx_pcmcia_frequency_change; | ||
262 | #endif | ||
263 | } | ||
264 | |||
256 | int __pxa2xx_drv_pcmcia_probe(struct device *dev) | 265 | int __pxa2xx_drv_pcmcia_probe(struct device *dev) |
257 | { | 266 | { |
258 | int i, ret; | 267 | int i, ret = 0; |
259 | struct pcmcia_low_level *ops; | 268 | struct pcmcia_low_level *ops; |
260 | struct skt_dev_info *sinfo; | 269 | struct skt_dev_info *sinfo; |
261 | struct soc_pcmcia_socket *skt; | 270 | struct soc_pcmcia_socket *skt; |
@@ -265,11 +274,7 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev) | |||
265 | 274 | ||
266 | ops = (struct pcmcia_low_level *)dev->platform_data; | 275 | ops = (struct pcmcia_low_level *)dev->platform_data; |
267 | 276 | ||
268 | /* Provide our PXA2xx specific timing routines. */ | 277 | pxa2xx_drv_pcmcia_ops(ops); |
269 | ops->set_timing = pxa2xx_pcmcia_set_timing; | ||
270 | #ifdef CONFIG_CPU_FREQ | ||
271 | ops->frequency_change = pxa2xx_pcmcia_frequency_change; | ||
272 | #endif | ||
273 | 278 | ||
274 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); | 279 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); |
275 | if (!sinfo) | 280 | if (!sinfo) |
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index 235d681652c3..cb5efaec886f 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h | |||
@@ -1,3 +1,6 @@ | |||
1 | /* temporary measure */ | 1 | /* temporary measure */ |
2 | extern int __pxa2xx_drv_pcmcia_probe(struct device *); | 2 | extern int __pxa2xx_drv_pcmcia_probe(struct device *); |
3 | 3 | ||
4 | int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); | ||
5 | void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); | ||
6 | |||
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index 6cbb1b1f7cfd..35d52809a8cd 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c | |||
@@ -32,6 +32,7 @@ static int | |||
32 | lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 32 | lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
33 | const socket_state_t *state) | 33 | const socket_state_t *state) |
34 | { | 34 | { |
35 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
35 | unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set; | 36 | unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set; |
36 | int ret = 0; | 37 | int ret = 0; |
37 | 38 | ||
@@ -149,7 +150,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
149 | 150 | ||
150 | if (ret == 0) { | 151 | if (ret == 0) { |
151 | lubbock_set_misc_wr(misc_mask, misc_set); | 152 | lubbock_set_misc_wr(misc_mask, misc_set); |
152 | sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); | 153 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); |
153 | } | 154 | } |
154 | 155 | ||
155 | #if 1 | 156 | #if 1 |
@@ -175,7 +176,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
175 | * Switch to 5V, Configure socket with 5V voltage | 176 | * Switch to 5V, Configure socket with 5V voltage |
176 | */ | 177 | */ |
177 | lubbock_set_misc_wr(misc_mask, 0); | 178 | lubbock_set_misc_wr(misc_mask, 0); |
178 | sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0); | 179 | sa1111_set_io(s->dev, pa_dwr_mask, 0); |
179 | 180 | ||
180 | /* | 181 | /* |
181 | * It takes about 100ms to turn off Vcc. | 182 | * It takes about 100ms to turn off Vcc. |
@@ -228,8 +229,9 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev) | |||
228 | /* Set CF Socket 1 power to standby mode. */ | 229 | /* Set CF Socket 1 power to standby mode. */ |
229 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); | 230 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); |
230 | 231 | ||
231 | sadev->dev.platform_data = &lubbock_pcmcia_ops; | 232 | pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); |
232 | ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); | 233 | ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, |
234 | pxa2xx_drv_pcmcia_add_one); | ||
233 | } | 235 | } |
234 | 236 | ||
235 | return ret; | 237 | return ret; |
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c index 1ca9737ea79e..6399314e244d 100644 --- a/drivers/pcmcia/sa1100_badge4.c +++ b/drivers/pcmcia/sa1100_badge4.c | |||
@@ -134,6 +134,9 @@ static struct pcmcia_low_level badge4_pcmcia_ops = { | |||
134 | 134 | ||
135 | .socket_init = sa1111_pcmcia_socket_init, | 135 | .socket_init = sa1111_pcmcia_socket_init, |
136 | .socket_suspend = sa1111_pcmcia_socket_suspend, | 136 | .socket_suspend = sa1111_pcmcia_socket_suspend, |
137 | |||
138 | .first = 0, | ||
139 | .nr = 2, | ||
137 | }; | 140 | }; |
138 | 141 | ||
139 | int pcmcia_badge4_init(struct device *dev) | 142 | int pcmcia_badge4_init(struct device *dev) |
@@ -146,7 +149,9 @@ int pcmcia_badge4_init(struct device *dev) | |||
146 | __func__, | 149 | __func__, |
147 | badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); | 150 | badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); |
148 | 151 | ||
149 | ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2); | 152 | sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); |
153 | ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, | ||
154 | sa11xx_drv_pcmcia_add_one); | ||
150 | } | 155 | } |
151 | 156 | ||
152 | return ret; | 157 | return ret; |
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c index 7eedb42f800c..4a32f4f1a717 100644 --- a/drivers/pcmcia/sa1100_jornada720.c +++ b/drivers/pcmcia/sa1100_jornada720.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 25 | static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
26 | { | 26 | { |
27 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
27 | unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; | 28 | unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; |
28 | 29 | ||
29 | /* | 30 | /* |
@@ -31,9 +32,9 @@ static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
31 | */ | 32 | */ |
32 | GRER |= 0x00000002; | 33 | GRER |= 0x00000002; |
33 | /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ | 34 | /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ |
34 | sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0); | 35 | sa1111_set_io_dir(s->dev, pin, 0, 0); |
35 | sa1111_set_io(SA1111_DEV(skt->dev), pin, 0); | 36 | sa1111_set_io(s->dev, pin, 0); |
36 | sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0); | 37 | sa1111_set_sleep_io(s->dev, pin, 0); |
37 | 38 | ||
38 | return sa1111_pcmcia_hw_init(skt); | 39 | return sa1111_pcmcia_hw_init(skt); |
39 | } | 40 | } |
@@ -41,6 +42,7 @@ static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
41 | static int | 42 | static int |
42 | jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | 43 | jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) |
43 | { | 44 | { |
45 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
44 | unsigned int pa_dwr_mask, pa_dwr_set; | 46 | unsigned int pa_dwr_mask, pa_dwr_set; |
45 | int ret; | 47 | int ret; |
46 | 48 | ||
@@ -97,7 +99,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s | |||
97 | unsigned long flags; | 99 | unsigned long flags; |
98 | 100 | ||
99 | local_irq_save(flags); | 101 | local_irq_save(flags); |
100 | sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); | 102 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); |
101 | local_irq_restore(flags); | 103 | local_irq_restore(flags); |
102 | } | 104 | } |
103 | 105 | ||
@@ -113,14 +115,20 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = { | |||
113 | 115 | ||
114 | .socket_init = sa1111_pcmcia_socket_init, | 116 | .socket_init = sa1111_pcmcia_socket_init, |
115 | .socket_suspend = sa1111_pcmcia_socket_suspend, | 117 | .socket_suspend = sa1111_pcmcia_socket_suspend, |
118 | |||
119 | .first = 0, | ||
120 | .nr = 2, | ||
116 | }; | 121 | }; |
117 | 122 | ||
118 | int __devinit pcmcia_jornada720_init(struct device *dev) | 123 | int __devinit pcmcia_jornada720_init(struct device *dev) |
119 | { | 124 | { |
120 | int ret = -ENODEV; | 125 | int ret = -ENODEV; |
121 | 126 | ||
122 | if (machine_is_jornada720()) | 127 | if (machine_is_jornada720()) { |
123 | ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2); | 128 | sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); |
129 | ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops, | ||
130 | sa11xx_drv_pcmcia_add_one); | ||
131 | } | ||
124 | 132 | ||
125 | return ret; | 133 | return ret; |
126 | } | 134 | } |
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c index 0c76d337815b..e39c65a06fee 100644 --- a/drivers/pcmcia/sa1100_neponset.c +++ b/drivers/pcmcia/sa1100_neponset.c | |||
@@ -43,6 +43,7 @@ | |||
43 | static int | 43 | static int |
44 | neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | 44 | neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) |
45 | { | 45 | { |
46 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
46 | unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set; | 47 | unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set; |
47 | int ret; | 48 | int ret; |
48 | 49 | ||
@@ -99,7 +100,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta | |||
99 | NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; | 100 | NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; |
100 | 101 | ||
101 | local_irq_restore(flags); | 102 | local_irq_restore(flags); |
102 | sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); | 103 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); |
103 | } | 104 | } |
104 | 105 | ||
105 | return 0; | 106 | return 0; |
@@ -121,6 +122,8 @@ static struct pcmcia_low_level neponset_pcmcia_ops = { | |||
121 | .configure_socket = neponset_pcmcia_configure_socket, | 122 | .configure_socket = neponset_pcmcia_configure_socket, |
122 | .socket_init = neponset_pcmcia_socket_init, | 123 | .socket_init = neponset_pcmcia_socket_init, |
123 | .socket_suspend = sa1111_pcmcia_socket_suspend, | 124 | .socket_suspend = sa1111_pcmcia_socket_suspend, |
125 | .first = 0, | ||
126 | .nr = 2, | ||
124 | }; | 127 | }; |
125 | 128 | ||
126 | int pcmcia_neponset_init(struct sa1111_dev *sadev) | 129 | int pcmcia_neponset_init(struct sa1111_dev *sadev) |
@@ -135,7 +138,9 @@ int pcmcia_neponset_init(struct sa1111_dev *sadev) | |||
135 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); | 138 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); |
136 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | 139 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); |
137 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | 140 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); |
138 | ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2); | 141 | sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); |
142 | ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, | ||
143 | sa11xx_drv_pcmcia_add_one); | ||
139 | } | 144 | } |
140 | 145 | ||
141 | return ret; | 146 | return ret; |
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index a6793e30cf71..98c791537cac 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c | |||
@@ -30,9 +30,6 @@ static struct pcmcia_irqs irqs[] = { | |||
30 | 30 | ||
31 | int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 31 | int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
32 | { | 32 | { |
33 | if (skt->irq == NO_IRQ) | ||
34 | skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT; | ||
35 | |||
36 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
37 | } | 34 | } |
38 | 35 | ||
@@ -43,8 +40,8 @@ void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
43 | 40 | ||
44 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 41 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
45 | { | 42 | { |
46 | struct sa1111_dev *sadev = SA1111_DEV(skt->dev); | 43 | struct sa1111_pcmcia_socket *s = to_skt(skt); |
47 | unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR); | 44 | unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); |
48 | 45 | ||
49 | switch (skt->nr) { | 46 | switch (skt->nr) { |
50 | case 0: | 47 | case 0: |
@@ -71,7 +68,7 @@ void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_sta | |||
71 | 68 | ||
72 | int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | 69 | int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) |
73 | { | 70 | { |
74 | struct sa1111_dev *sadev = SA1111_DEV(skt->dev); | 71 | struct sa1111_pcmcia_socket *s = to_skt(skt); |
75 | unsigned int pccr_skt_mask, pccr_set_mask, val; | 72 | unsigned int pccr_skt_mask, pccr_set_mask, val; |
76 | unsigned long flags; | 73 | unsigned long flags; |
77 | 74 | ||
@@ -100,10 +97,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s | |||
100 | pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; | 97 | pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; |
101 | 98 | ||
102 | local_irq_save(flags); | 99 | local_irq_save(flags); |
103 | val = sa1111_readl(sadev->mapbase + SA1111_PCCR); | 100 | val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); |
104 | val &= ~pccr_skt_mask; | 101 | val &= ~pccr_skt_mask; |
105 | val |= pccr_set_mask & pccr_skt_mask; | 102 | val |= pccr_set_mask & pccr_skt_mask; |
106 | sa1111_writel(val, sadev->mapbase + SA1111_PCCR); | 103 | sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); |
107 | local_irq_restore(flags); | 104 | local_irq_restore(flags); |
108 | 105 | ||
109 | return 0; | 106 | return 0; |
@@ -119,10 +116,45 @@ void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | |||
119 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 116 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
120 | } | 117 | } |
121 | 118 | ||
119 | int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | ||
120 | int (*add)(struct soc_pcmcia_socket *)) | ||
121 | { | ||
122 | struct sa1111_pcmcia_socket *s; | ||
123 | int i, ret = 0; | ||
124 | |||
125 | s = kzalloc(sizeof(*s) * ops->nr, GFP_KERNEL); | ||
126 | if (!s) | ||
127 | return -ENODEV; | ||
128 | |||
129 | for (i = 0; i < ops->nr; i++) { | ||
130 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
131 | if (!s) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | s->soc.nr = ops->first + i; | ||
135 | s->soc.irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT; | ||
136 | s->soc.ops = ops; | ||
137 | s->soc.socket.owner = ops->owner; | ||
138 | s->soc.socket.dev.parent = &dev->dev; | ||
139 | s->dev = dev; | ||
140 | |||
141 | ret = add(&s->soc); | ||
142 | if (ret == 0) { | ||
143 | s->next = dev_get_drvdata(&dev->dev); | ||
144 | dev_set_drvdata(&dev->dev, s); | ||
145 | } else | ||
146 | kfree(s); | ||
147 | } | ||
148 | |||
149 | return ret; | ||
150 | } | ||
151 | |||
122 | static int pcmcia_probe(struct sa1111_dev *dev) | 152 | static int pcmcia_probe(struct sa1111_dev *dev) |
123 | { | 153 | { |
124 | void __iomem *base; | 154 | void __iomem *base; |
125 | 155 | ||
156 | dev_set_drvdata(&dev->dev, NULL); | ||
157 | |||
126 | if (!request_mem_region(dev->res.start, 512, | 158 | if (!request_mem_region(dev->res.start, 512, |
127 | SA1111_DRIVER_NAME(dev))) | 159 | SA1111_DRIVER_NAME(dev))) |
128 | return -EBUSY; | 160 | return -EBUSY; |
@@ -152,15 +184,15 @@ static int pcmcia_probe(struct sa1111_dev *dev) | |||
152 | 184 | ||
153 | static int __devexit pcmcia_remove(struct sa1111_dev *dev) | 185 | static int __devexit pcmcia_remove(struct sa1111_dev *dev) |
154 | { | 186 | { |
155 | struct skt_dev_info *sinfo = dev_get_drvdata(&dev->dev); | 187 | struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev); |
156 | int i; | ||
157 | 188 | ||
158 | dev_set_drvdata(&dev->dev, NULL); | 189 | dev_set_drvdata(&dev->dev, NULL); |
159 | 190 | ||
160 | for (i = 0; i < sinfo->nskt; i++) | 191 | for (; next = s->next, s; s = next) { |
161 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 192 | soc_pcmcia_remove_one(&s->soc); |
193 | kfree(s); | ||
194 | } | ||
162 | 195 | ||
163 | kfree(sinfo); | ||
164 | release_mem_region(dev->res.start, 512); | 196 | release_mem_region(dev->res.start, 512); |
165 | return 0; | 197 | return 0; |
166 | } | 198 | } |
diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h index 10ced4a210d7..536fe15818be 100644 --- a/drivers/pcmcia/sa1111_generic.h +++ b/drivers/pcmcia/sa1111_generic.h | |||
@@ -1,6 +1,20 @@ | |||
1 | #include "soc_common.h" | 1 | #include "soc_common.h" |
2 | #include "sa11xx_base.h" | 2 | #include "sa11xx_base.h" |
3 | 3 | ||
4 | struct sa1111_pcmcia_socket { | ||
5 | struct soc_pcmcia_socket soc; | ||
6 | struct sa1111_dev *dev; | ||
7 | struct sa1111_pcmcia_socket *next; | ||
8 | }; | ||
9 | |||
10 | static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s) | ||
11 | { | ||
12 | return container_of(s, struct sa1111_pcmcia_socket, soc); | ||
13 | } | ||
14 | |||
15 | int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | ||
16 | int (*add)(struct soc_pcmcia_socket *)); | ||
17 | |||
4 | extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *); | 18 | extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *); |
5 | extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *); | 19 | extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *); |
6 | extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); | 20 | extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); |
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 92a43486adc6..4db81490e5c9 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c | |||
@@ -171,7 +171,7 @@ static const char *skt_names[] = { | |||
171 | #define SKT_DEV_INFO_SIZE(n) \ | 171 | #define SKT_DEV_INFO_SIZE(n) \ |
172 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) | 172 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) |
173 | 173 | ||
174 | static int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) | 174 | int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) |
175 | { | 175 | { |
176 | skt->res_skt.start = _PCMCIA(skt->nr); | 176 | skt->res_skt.start = _PCMCIA(skt->nr); |
177 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; | 177 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; |
@@ -195,14 +195,10 @@ static int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
195 | 195 | ||
196 | return soc_pcmcia_add_one(skt); | 196 | return soc_pcmcia_add_one(skt); |
197 | } | 197 | } |
198 | EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one); | ||
198 | 199 | ||
199 | int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | 200 | void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops) |
200 | int first, int nr) | ||
201 | { | 201 | { |
202 | struct skt_dev_info *sinfo; | ||
203 | struct soc_pcmcia_socket *skt; | ||
204 | int i; | ||
205 | |||
206 | /* | 202 | /* |
207 | * set default MECR calculation if the board specific | 203 | * set default MECR calculation if the board specific |
208 | * code did not specify one... | 204 | * code did not specify one... |
@@ -216,6 +212,17 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
216 | #ifdef CONFIG_CPU_FREQ | 212 | #ifdef CONFIG_CPU_FREQ |
217 | ops->frequency_change = sa1100_pcmcia_frequency_change; | 213 | ops->frequency_change = sa1100_pcmcia_frequency_change; |
218 | #endif | 214 | #endif |
215 | } | ||
216 | EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops); | ||
217 | |||
218 | int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | ||
219 | int first, int nr) | ||
220 | { | ||
221 | struct skt_dev_info *sinfo; | ||
222 | struct soc_pcmcia_socket *skt; | ||
223 | int i, ret = 0; | ||
224 | |||
225 | sa11xx_drv_pcmcia_ops(ops); | ||
219 | 226 | ||
220 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); | 227 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); |
221 | if (!sinfo) | 228 | if (!sinfo) |
diff --git a/drivers/pcmcia/sa11xx_base.h b/drivers/pcmcia/sa11xx_base.h index 7bc208280527..3d76d720f463 100644 --- a/drivers/pcmcia/sa11xx_base.h +++ b/drivers/pcmcia/sa11xx_base.h | |||
@@ -118,6 +118,8 @@ static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz, | |||
118 | } | 118 | } |
119 | 119 | ||
120 | 120 | ||
121 | int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); | ||
122 | void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); | ||
121 | extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr); | 123 | extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr); |
122 | 124 | ||
123 | #endif /* !defined(_PCMCIA_SA1100_H) */ | 125 | #endif /* !defined(_PCMCIA_SA1100_H) */ |