]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/pcmcia/soc_common.c
pcmcia: soc_common: constify pcmcia_low_level ops pointer
[mirror_ubuntu-artful-kernel.git] / drivers / pcmcia / soc_common.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 Common support code for the PCMCIA control functionality of
4 integrated SOCs like the SA-11x0 and PXA2xx microprocessors.
5
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
8 except in compliance with the License. You may obtain a copy of
9 the License at http://www.mozilla.org/MPL/
10
11 Software distributed under the License is distributed on an "AS
12 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 implied. See the License for the specific language governing
14 rights and limitations under the License.
15
16 The initial developer of the original code is John G. Dorsey
17 <john+@cs.cmu.edu>. Portions created by John G. Dorsey are
18 Copyright (C) 1999 John G. Dorsey. All Rights Reserved.
19
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
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
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
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
28 the provisions above, a recipient may use your version of this
29 file under either the MPL or the GPL.
30
31======================================================================*/
32
33
17b38ebb 34#include <linux/cpufreq.h>
d9dc8787 35#include <linux/gpio.h>
45ca7536 36#include <linux/gpio/consumer.h>
1da177e4 37#include <linux/init.h>
17b38ebb
MRJ
38#include <linux/interrupt.h>
39#include <linux/io.h>
40#include <linux/irq.h>
1da177e4 41#include <linux/kernel.h>
1da177e4 42#include <linux/mm.h>
17b38ebb
MRJ
43#include <linux/module.h>
44#include <linux/moduleparam.h>
23d077e2 45#include <linux/mutex.h>
ac61b600 46#include <linux/regulator/consumer.h>
1da177e4 47#include <linux/spinlock.h>
17b38ebb 48#include <linux/timer.h>
1da177e4 49
a09e64fb 50#include <mach/hardware.h>
1da177e4
LT
51
52#include "soc_common.h"
53
d9dc8787
RK
54static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev);
55
7d16b658 56#ifdef CONFIG_PCMCIA_DEBUG
1da177e4
LT
57
58static int pc_debug;
59module_param(pc_debug, int, 0644);
60
61void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
62 int lvl, const char *fmt, ...)
63{
106665d9 64 struct va_format vaf;
1da177e4
LT
65 va_list args;
66 if (pc_debug > lvl) {
1da177e4 67 va_start(args, fmt);
106665d9
JP
68
69 vaf.fmt = fmt;
70 vaf.va = &args;
71
72 printk(KERN_DEBUG "skt%u: %s: %pV", skt->nr, func, &vaf);
73
1da177e4
LT
74 va_end(args);
75 }
76}
b9f515e3 77EXPORT_SYMBOL(soc_pcmcia_debug);
1da177e4
LT
78
79#endif
80
17b38ebb
MRJ
81#define to_soc_pcmcia_socket(x) \
82 container_of(x, struct soc_pcmcia_socket, socket)
1da177e4 83
ac61b600
RK
84int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
85 struct soc_pcmcia_regulator *r, int v)
86{
87 bool on;
88 int ret;
89
90 if (!r->reg)
91 return 0;
92
93 on = v != 0;
94 if (r->on == on)
95 return 0;
96
97 if (on) {
98 ret = regulator_set_voltage(r->reg, v * 100000, v * 100000);
99 if (ret) {
100 int vout = regulator_get_voltage(r->reg) / 100000;
101
102 dev_warn(&skt->socket.dev,
103 "CS requested %s=%u.%uV, applying %u.%uV\n",
104 r == &skt->vcc ? "Vcc" : "Vpp",
105 v / 10, v % 10, vout / 10, vout % 10);
106 }
107
108 ret = regulator_enable(r->reg);
109 } else {
110 regulator_disable(r->reg);
111 }
112 if (ret == 0)
113 r->on = on;
114
115 return ret;
116}
117EXPORT_SYMBOL_GPL(soc_pcmcia_regulator_set);
118
1da177e4
LT
119static unsigned short
120calc_speed(unsigned short *spds, int num, unsigned short dflt)
121{
122 unsigned short speed = 0;
123 int i;
124
125 for (i = 0; i < num; i++)
126 if (speed < spds[i])
127 speed = spds[i];
128 if (speed == 0)
129 speed = dflt;
130
131 return speed;
132}
133
17b38ebb
MRJ
134void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
135 struct soc_pcmcia_timing *timing)
1da177e4 136{
17b38ebb
MRJ
137 timing->io =
138 calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
139 timing->mem =
140 calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
141 timing->attr =
142 calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
1da177e4
LT
143}
144EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
145
d9dc8787
RK
146static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
147 unsigned int nr)
148{
149 unsigned int i;
150
59ecfefa 151 for (i = 0; i < nr; i++)
d9dc8787
RK
152 if (skt->stat[i].irq)
153 free_irq(skt->stat[i].irq, skt);
d9dc8787
RK
154
155 if (skt->ops->hw_shutdown)
156 skt->ops->hw_shutdown(skt);
0821c3bc
DES
157
158 clk_disable_unprepare(skt->clk);
d9dc8787
RK
159}
160
161static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
162{
163 __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
164}
165
45ca7536
RK
166int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt)
167{
168 struct device *dev = skt->socket.dev.parent;
169 struct gpio_desc *desc;
170 int i;
171
172 for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
173 if (!skt->stat[i].name)
174 continue;
175
176 desc = devm_gpiod_get(dev, skt->stat[i].name, GPIOD_IN);
177 if (IS_ERR(desc)) {
178 dev_err(dev, "Failed to get GPIO for %s: %ld\n",
179 skt->stat[i].name, PTR_ERR(desc));
180 return PTR_ERR(desc);
181 }
182
183 skt->stat[i].desc = desc;
184 }
185
186 return 0;
187}
188EXPORT_SYMBOL_GPL(soc_pcmcia_request_gpiods);
189
d9dc8787
RK
190static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
191{
192 int ret = 0, i;
193
0821c3bc
DES
194 clk_prepare_enable(skt->clk);
195
d9dc8787
RK
196 if (skt->ops->hw_init) {
197 ret = skt->ops->hw_init(skt);
198 if (ret)
199 return ret;
200 }
201
202 for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
203 if (gpio_is_valid(skt->stat[i].gpio)) {
7bfe4978
RK
204 unsigned long flags = GPIOF_IN;
205
206 /* CD is active low by default */
207 if (i == SOC_STAT_CD)
208 flags |= GPIOF_ACTIVE_LOW;
209
59ecfefa 210 ret = devm_gpio_request_one(skt->socket.dev.parent,
7bfe4978 211 skt->stat[i].gpio, flags,
59ecfefa 212 skt->stat[i].name);
d9dc8787
RK
213 if (ret) {
214 __soc_pcmcia_hw_shutdown(skt, i);
215 return ret;
216 }
217
45ca7536
RK
218 skt->stat[i].desc = gpio_to_desc(skt->stat[i].gpio);
219 }
220
221 if (skt->stat[i].desc) {
222 int irq = gpiod_to_irq(skt->stat[i].desc);
d9dc8787 223
a4941191
RK
224 if (irq > 0) {
225 if (i == SOC_STAT_RDY)
226 skt->socket.pci_irq = irq;
227 else
228 skt->stat[i].irq = irq;
229 }
d9dc8787
RK
230 }
231
232 if (skt->stat[i].irq) {
233 ret = request_irq(skt->stat[i].irq,
234 soc_common_pcmcia_interrupt,
235 IRQF_TRIGGER_NONE,
236 skt->stat[i].name, skt);
237 if (ret) {
d9dc8787
RK
238 __soc_pcmcia_hw_shutdown(skt, i);
239 return ret;
240 }
241 }
242 }
243
244 return ret;
245}
246
247static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt)
248{
249 int i;
250
251 for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
252 if (skt->stat[i].irq) {
253 irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING);
254 irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH);
255 }
256}
257
258static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
259{
260 int i;
261
262 for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
263 if (skt->stat[i].irq)
264 irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
265}
266
a1d05002
RK
267/*
268 * The CF 3.0 specification says that cards tie VS1 to ground and leave
269 * VS2 open. Many implementations do not wire up the VS signals, so we
270 * provide hard-coded values as per the CF 3.0 spec.
271 */
272void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
273 struct pcmcia_state *state)
274{
275 state->vs_3v = 1;
276}
277EXPORT_SYMBOL_GPL(soc_common_cf_socket_state);
278
1da177e4
LT
279static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
280{
281 struct pcmcia_state state;
282 unsigned int stat;
283
284 memset(&state, 0, sizeof(struct pcmcia_state));
285
d9dc8787
RK
286 /* Make battery voltage state report 'good' */
287 state.bvd1 = 1;
288 state.bvd2 = 1;
289
45ca7536 290 if (skt->stat[SOC_STAT_CD].desc)
7bfe4978 291 state.detect = !!gpiod_get_value(skt->stat[SOC_STAT_CD].desc);
45ca7536
RK
292 if (skt->stat[SOC_STAT_RDY].desc)
293 state.ready = !!gpiod_get_value(skt->stat[SOC_STAT_RDY].desc);
294 if (skt->stat[SOC_STAT_BVD1].desc)
295 state.bvd1 = !!gpiod_get_value(skt->stat[SOC_STAT_BVD1].desc);
296 if (skt->stat[SOC_STAT_BVD2].desc)
297 state.bvd2 = !!gpiod_get_value(skt->stat[SOC_STAT_BVD2].desc);
d9dc8787 298
1da177e4
LT
299 skt->ops->socket_state(skt, &state);
300
301 stat = state.detect ? SS_DETECT : 0;
302 stat |= state.ready ? SS_READY : 0;
303 stat |= state.wrprot ? SS_WRPROT : 0;
304 stat |= state.vs_3v ? SS_3VCARD : 0;
305 stat |= state.vs_Xv ? SS_XVCARD : 0;
306
307 /* The power status of individual sockets is not available
308 * explicitly from the hardware, so we just remember the state
309 * and regurgitate it upon request:
310 */
311 stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
312
313 if (skt->cs_state.flags & SS_IOCARD)
a466ebd2 314 stat |= state.bvd1 ? 0 : SS_STSCHG;
1da177e4
LT
315 else {
316 if (state.bvd1 == 0)
317 stat |= SS_BATDEAD;
318 else if (state.bvd2 == 0)
319 stat |= SS_BATWARN;
320 }
321 return stat;
322}
323
324/*
325 * soc_common_pcmcia_config_skt
326 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
327 *
328 * Convert PCMCIA socket state to our socket configure structure.
329 */
17b38ebb
MRJ
330static int soc_common_pcmcia_config_skt(
331 struct soc_pcmcia_socket *skt, socket_state_t *state)
1da177e4
LT
332{
333 int ret;
334
335 ret = skt->ops->configure_socket(skt, state);
6ac95d82
RK
336 if (ret < 0) {
337 pr_err("soc_common_pcmcia: unable to configure socket %d\n",
338 skt->nr);
339 /* restore the previous state */
340 WARN_ON(skt->ops->configure_socket(skt, &skt->cs_state));
341 return ret;
342 }
343
1da177e4 344 if (ret == 0) {
535e0abc
RK
345 struct gpio_desc *descs[2];
346 int values[2], n = 0;
347
348 if (skt->gpio_reset) {
349 descs[n] = skt->gpio_reset;
350 values[n++] = !!(state->flags & SS_RESET);
351 }
352 if (skt->gpio_bus_enable) {
353 descs[n] = skt->gpio_bus_enable;
354 values[n++] = !!(state->flags & SS_OUTPUT_ENA);
355 }
356
357 if (n)
358 gpiod_set_array_value_cansleep(n, descs, values);
359
1da177e4
LT
360 /*
361 * This really needs a better solution. The IRQ
362 * may or may not be claimed by the driver.
363 */
364 if (skt->irq_state != 1 && state->io_irq) {
365 skt->irq_state = 1;
dced35ae
TG
366 irq_set_irq_type(skt->socket.pci_irq,
367 IRQ_TYPE_EDGE_FALLING);
1da177e4
LT
368 } else if (skt->irq_state == 1 && state->io_irq == 0) {
369 skt->irq_state = 0;
dced35ae 370 irq_set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
1da177e4
LT
371 }
372
373 skt->cs_state = *state;
374 }
375
1da177e4
LT
376 return ret;
377}
378
379/* soc_common_pcmcia_sock_init()
380 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
381 *
382 * (Re-)Initialise the socket, turning on status interrupts
383 * and PCMCIA bus. This must wait for power to stabilise
384 * so that the card status signals report correctly.
385 *
386 * Returns: 0
387 */
388static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
389{
390 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
391
392 debug(skt, 2, "initializing socket\n");
a747ce83
JC
393 if (skt->ops->socket_init)
394 skt->ops->socket_init(skt);
d9dc8787 395 soc_pcmcia_hw_enable(skt);
1da177e4
LT
396 return 0;
397}
398
399
400/*
401 * soc_common_pcmcia_suspend()
402 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
403 *
404 * Remove power on the socket, disable IRQs from the card.
405 * Turn off status interrupts, and disable the PCMCIA bus.
406 *
407 * Returns: 0
408 */
409static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
410{
411 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
412
413 debug(skt, 2, "suspending socket\n");
414
d9dc8787 415 soc_pcmcia_hw_disable(skt);
a747ce83
JC
416 if (skt->ops->socket_suspend)
417 skt->ops->socket_suspend(skt);
1da177e4
LT
418
419 return 0;
420}
421
422static DEFINE_SPINLOCK(status_lock);
423
424static void soc_common_check_status(struct soc_pcmcia_socket *skt)
425{
426 unsigned int events;
427
428 debug(skt, 4, "entering PCMCIA monitoring thread\n");
429
430 do {
431 unsigned int status;
432 unsigned long flags;
433
434 status = soc_common_pcmcia_skt_state(skt);
435
436 spin_lock_irqsave(&status_lock, flags);
437 events = (status ^ skt->status) & skt->cs_state.csc_mask;
438 skt->status = status;
439 spin_unlock_irqrestore(&status_lock, flags);
440
441 debug(skt, 4, "events: %s%s%s%s%s%s\n",
442 events == 0 ? "<NONE>" : "",
443 events & SS_DETECT ? "DETECT " : "",
444 events & SS_READY ? "READY " : "",
445 events & SS_BATDEAD ? "BATDEAD " : "",
446 events & SS_BATWARN ? "BATWARN " : "",
447 events & SS_STSCHG ? "STSCHG " : "");
448
449 if (events)
450 pcmcia_parse_events(&skt->socket, events);
451 } while (events);
452}
453
454/* Let's poll for events in addition to IRQs since IRQ only is unreliable... */
455static void soc_common_pcmcia_poll_event(unsigned long dummy)
456{
457 struct soc_pcmcia_socket *skt = (struct soc_pcmcia_socket *)dummy;
458 debug(skt, 4, "polling for events\n");
459
460 mod_timer(&skt->poll_timer, jiffies + SOC_PCMCIA_POLL_PERIOD);
461
462 soc_common_check_status(skt);
463}
464
465
466/*
467 * Service routine for socket driver interrupts (requested by the
468 * low-level PCMCIA init() operation via soc_common_pcmcia_thread()).
469 * The actual interrupt-servicing work is performed by
470 * soc_common_pcmcia_thread(), largely because the Card Services event-
471 * handling code performs scheduling operations which cannot be
472 * executed from within an interrupt context.
473 */
7d12e780 474static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev)
1da177e4
LT
475{
476 struct soc_pcmcia_socket *skt = dev;
477
478 debug(skt, 3, "servicing IRQ %d\n", irq);
479
480 soc_common_check_status(skt);
481
482 return IRQ_HANDLED;
483}
484
485
486/*
487 * Implements the get_status() operation for the in-kernel PCMCIA
488 * service (formerly SS_GetStatus in Card Services). Essentially just
489 * fills in bits in `status' according to internal driver state or
490 * the value of the voltage detect chipselect register.
491 *
492 * As a debugging note, during card startup, the PCMCIA core issues
493 * three set_socket() commands in a row the first with RESET deasserted,
494 * the second with RESET asserted, and the last with RESET deasserted
495 * again. Following the third set_socket(), a get_status() command will
496 * be issued. The kernel is looking for the SS_READY flag (see
497 * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
498 *
499 * Returns: 0
500 */
501static int
502soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
503{
504 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
505
506 skt->status = soc_common_pcmcia_skt_state(skt);
507 *status = skt->status;
508
509 return 0;
510}
511
512
1da177e4
LT
513/*
514 * Implements the set_socket() operation for the in-kernel PCMCIA
515 * service (formerly SS_SetSocket in Card Services). We more or
516 * less punt all of this work and let the kernel handle the details
517 * of power configuration, reset, &c. We also record the value of
518 * `state' in order to regurgitate it to the PCMCIA core later.
1da177e4 519 */
17b38ebb
MRJ
520static int soc_common_pcmcia_set_socket(
521 struct pcmcia_socket *sock, socket_state_t *state)
1da177e4
LT
522{
523 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
524
17b38ebb
MRJ
525 debug(skt, 2, "mask: %s%s%s%s%s%s flags: %s%s%s%s%s%s Vcc %d Vpp %d irq %d\n",
526 (state->csc_mask == 0) ? "<NONE> " : "",
527 (state->csc_mask & SS_DETECT) ? "DETECT " : "",
528 (state->csc_mask & SS_READY) ? "READY " : "",
529 (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
530 (state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
531 (state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
532 (state->flags == 0) ? "<NONE> " : "",
533 (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
534 (state->flags & SS_IOCARD) ? "IOCARD " : "",
535 (state->flags & SS_RESET) ? "RESET " : "",
536 (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
537 (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
1da177e4
LT
538 state->Vcc, state->Vpp, state->io_irq);
539
540 return soc_common_pcmcia_config_skt(skt, state);
541}
542
543
544/*
545 * Implements the set_io_map() operation for the in-kernel PCMCIA
546 * service (formerly SS_SetIOMap in Card Services). We configure
547 * the map speed as requested, but override the address ranges
548 * supplied by Card Services.
549 *
550 * Returns: 0 on success, -1 on error
551 */
17b38ebb
MRJ
552static int soc_common_pcmcia_set_io_map(
553 struct pcmcia_socket *sock, struct pccard_io_map *map)
1da177e4
LT
554{
555 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
556 unsigned short speed = map->speed;
557
5f784336
WS
558 debug(skt, 2, "map %u speed %u start 0x%08llx stop 0x%08llx\n",
559 map->map, map->speed, (unsigned long long)map->start,
560 (unsigned long long)map->stop);
1da177e4 561 debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
17b38ebb
MRJ
562 (map->flags == 0) ? "<NONE>" : "",
563 (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
564 (map->flags & MAP_16BIT) ? "16BIT " : "",
565 (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
566 (map->flags & MAP_0WS) ? "0WS " : "",
567 (map->flags & MAP_WRPROT) ? "WRPROT " : "",
568 (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
569 (map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
1da177e4
LT
570
571 if (map->map >= MAX_IO_WIN) {
2e11cb4c 572 printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
1da177e4
LT
573 map->map);
574 return -1;
575 }
576
577 if (map->flags & MAP_ACTIVE) {
578 if (speed == 0)
579 speed = SOC_PCMCIA_IO_ACCESS;
580 } else {
581 speed = 0;
582 }
583
584 skt->spd_io[map->map] = speed;
585 skt->ops->set_timing(skt);
586
587 if (map->stop == 1)
588 map->stop = PAGE_SIZE-1;
589
590 map->stop -= map->start;
591 map->stop += skt->socket.io_offset;
592 map->start = skt->socket.io_offset;
593
594 return 0;
595}
596
597
598/*
599 * Implements the set_mem_map() operation for the in-kernel PCMCIA
600 * service (formerly SS_SetMemMap in Card Services). We configure
601 * the map speed as requested, but override the address ranges
602 * supplied by Card Services.
603 *
4846d017 604 * Returns: 0 on success, -ERRNO on error
1da177e4 605 */
17b38ebb
MRJ
606static int soc_common_pcmcia_set_mem_map(
607 struct pcmcia_socket *sock, struct pccard_mem_map *map)
1da177e4
LT
608{
609 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
610 struct resource *res;
611 unsigned short speed = map->speed;
612
613 debug(skt, 2, "map %u speed %u card_start %08x\n",
614 map->map, map->speed, map->card_start);
615 debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
17b38ebb
MRJ
616 (map->flags == 0) ? "<NONE>" : "",
617 (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
618 (map->flags & MAP_16BIT) ? "16BIT " : "",
619 (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
620 (map->flags & MAP_0WS) ? "0WS " : "",
621 (map->flags & MAP_WRPROT) ? "WRPROT " : "",
622 (map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
623 (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
1da177e4
LT
624
625 if (map->map >= MAX_WIN)
626 return -EINVAL;
627
628 if (map->flags & MAP_ACTIVE) {
629 if (speed == 0)
630 speed = 300;
631 } else {
632 speed = 0;
633 }
634
635 if (map->flags & MAP_ATTRIB) {
636 res = &skt->res_attr;
637 skt->spd_attr[map->map] = speed;
638 skt->spd_mem[map->map] = 0;
639 } else {
640 res = &skt->res_mem;
641 skt->spd_attr[map->map] = 0;
642 skt->spd_mem[map->map] = speed;
643 }
644
645 skt->ops->set_timing(skt);
646
647 map->static_start = res->start + map->card_start;
648
649 return 0;
650}
651
652struct bittbl {
653 unsigned int mask;
654 const char *name;
655};
656
657static struct bittbl status_bits[] = {
658 { SS_WRPROT, "SS_WRPROT" },
659 { SS_BATDEAD, "SS_BATDEAD" },
660 { SS_BATWARN, "SS_BATWARN" },
661 { SS_READY, "SS_READY" },
662 { SS_DETECT, "SS_DETECT" },
663 { SS_POWERON, "SS_POWERON" },
664 { SS_STSCHG, "SS_STSCHG" },
665 { SS_3VCARD, "SS_3VCARD" },
666 { SS_XVCARD, "SS_XVCARD" },
667};
668
669static struct bittbl conf_bits[] = {
670 { SS_PWR_AUTO, "SS_PWR_AUTO" },
671 { SS_IOCARD, "SS_IOCARD" },
672 { SS_RESET, "SS_RESET" },
673 { SS_DMA_MODE, "SS_DMA_MODE" },
674 { SS_SPKR_ENA, "SS_SPKR_ENA" },
675 { SS_OUTPUT_ENA, "SS_OUTPUT_ENA" },
676};
677
17b38ebb
MRJ
678static void dump_bits(char **p, const char *prefix,
679 unsigned int val, struct bittbl *bits, int sz)
1da177e4
LT
680{
681 char *b = *p;
682 int i;
683
684 b += sprintf(b, "%-9s:", prefix);
685 for (i = 0; i < sz; i++)
686 if (val & bits[i].mask)
687 b += sprintf(b, " %s", bits[i].name);
688 *b++ = '\n';
689 *p = b;
690}
691
692/*
693 * Implements the /sys/class/pcmcia_socket/??/status file.
694 *
695 * Returns: the number of characters added to the buffer
696 */
17b38ebb
MRJ
697static ssize_t show_status(
698 struct device *dev, struct device_attribute *attr, char *buf)
1da177e4
LT
699{
700 struct soc_pcmcia_socket *skt =
87373318 701 container_of(dev, struct soc_pcmcia_socket, socket.dev);
1da177e4
LT
702 char *p = buf;
703
17b38ebb 704 p += sprintf(p, "slot : %d\n", skt->nr);
1da177e4
LT
705
706 dump_bits(&p, "status", skt->status,
707 status_bits, ARRAY_SIZE(status_bits));
708 dump_bits(&p, "csc_mask", skt->cs_state.csc_mask,
709 status_bits, ARRAY_SIZE(status_bits));
710 dump_bits(&p, "cs_flags", skt->cs_state.flags,
711 conf_bits, ARRAY_SIZE(conf_bits));
712
17b38ebb
MRJ
713 p += sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc);
714 p += sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp);
715 p += sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq,
66024db5 716 skt->socket.pci_irq);
1da177e4 717 if (skt->ops->show_timing)
17b38ebb 718 p += skt->ops->show_timing(skt, p);
1da177e4
LT
719
720 return p-buf;
721}
e4a3c3f0 722static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1da177e4
LT
723
724
725static struct pccard_operations soc_common_pcmcia_operations = {
726 .init = soc_common_pcmcia_sock_init,
727 .suspend = soc_common_pcmcia_suspend,
728 .get_status = soc_common_pcmcia_get_status,
1da177e4
LT
729 .set_socket = soc_common_pcmcia_set_socket,
730 .set_io_map = soc_common_pcmcia_set_io_map,
731 .set_mem_map = soc_common_pcmcia_set_mem_map,
732};
733
734
1da177e4 735#ifdef CONFIG_CPU_FREQ
fb8c9959
RK
736static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
737 unsigned long val, void *data)
1da177e4 738{
fb8c9959 739 struct soc_pcmcia_socket *skt = container_of(nb, struct soc_pcmcia_socket, cpufreq_nb);
1da177e4 740 struct cpufreq_freqs *freqs = data;
1da177e4 741
fb8c9959 742 return skt->ops->frequency_change(skt, val, freqs);
1da177e4 743}
1da177e4
LT
744#endif
745
e0d21178 746void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
c8f9ce55 747 const struct pcmcia_low_level *ops, struct device *dev)
e0d21178 748{
d9dc8787
RK
749 int i;
750
e0d21178
RK
751 skt->ops = ops;
752 skt->socket.owner = ops->owner;
753 skt->socket.dev.parent = dev;
754 skt->socket.pci_irq = NO_IRQ;
d9dc8787
RK
755
756 for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
757 skt->stat[i].gpio = -EINVAL;
e0d21178
RK
758}
759EXPORT_SYMBOL(soc_pcmcia_init_one);
760
097e296d 761void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
1da177e4 762{
097e296d 763 del_timer_sync(&skt->poll_timer);
1da177e4 764
097e296d 765 pcmcia_unregister_socket(&skt->socket);
1da177e4 766
fb8c9959
RK
767#ifdef CONFIG_CPU_FREQ
768 if (skt->ops->frequency_change)
769 cpufreq_unregister_notifier(&skt->cpufreq_nb,
770 CPUFREQ_TRANSITION_NOTIFIER);
771#endif
772
d9dc8787 773 soc_pcmcia_hw_shutdown(skt);
1da177e4 774
d9dc8787 775 /* should not be required; violates some lowlevel drivers */
097e296d 776 soc_common_pcmcia_config_skt(skt, &dead_socket);
1da177e4 777
097e296d
RKAL
778 iounmap(skt->virt_io);
779 skt->virt_io = NULL;
780 release_resource(&skt->res_attr);
781 release_resource(&skt->res_mem);
782 release_resource(&skt->res_io);
783 release_resource(&skt->res_skt);
784}
785EXPORT_SYMBOL(soc_pcmcia_remove_one);
1da177e4 786
097e296d
RKAL
787int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
788{
789 int ret;
1da177e4 790
6ac95d82
RK
791 skt->cs_state = dead_socket;
792
dae6cdab
VT
793 setup_timer(&skt->poll_timer, soc_common_pcmcia_poll_event,
794 (unsigned long)skt);
097e296d 795 skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
1da177e4 796
097e296d
RKAL
797 ret = request_resource(&iomem_resource, &skt->res_skt);
798 if (ret)
799 goto out_err_1;
1da177e4 800
097e296d
RKAL
801 ret = request_resource(&skt->res_skt, &skt->res_io);
802 if (ret)
803 goto out_err_2;
1da177e4 804
097e296d
RKAL
805 ret = request_resource(&skt->res_skt, &skt->res_mem);
806 if (ret)
807 goto out_err_3;
1da177e4 808
097e296d
RKAL
809 ret = request_resource(&skt->res_skt, &skt->res_attr);
810 if (ret)
811 goto out_err_4;
1da177e4 812
097e296d
RKAL
813 skt->virt_io = ioremap(skt->res_io.start, 0x10000);
814 if (skt->virt_io == NULL) {
815 ret = -ENOMEM;
816 goto out_err_5;
817 }
1da177e4 818
097e296d
RKAL
819 /*
820 * We initialize default socket timing here, because
821 * we are not guaranteed to see a SetIOMap operation at
822 * runtime.
823 */
824 skt->ops->set_timing(skt);
1da177e4 825
d9dc8787 826 ret = soc_pcmcia_hw_init(skt);
097e296d
RKAL
827 if (ret)
828 goto out_err_6;
1da177e4 829
097e296d
RKAL
830 skt->socket.ops = &soc_common_pcmcia_operations;
831 skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
832 skt->socket.resource_ops = &pccard_static_ops;
833 skt->socket.irq_mask = 0;
834 skt->socket.map_size = PAGE_SIZE;
097e296d 835 skt->socket.io_offset = (unsigned long)skt->virt_io;
1da177e4 836
097e296d 837 skt->status = soc_common_pcmcia_skt_state(skt);
1da177e4 838
fb8c9959
RK
839#ifdef CONFIG_CPU_FREQ
840 if (skt->ops->frequency_change) {
841 skt->cpufreq_nb.notifier_call = soc_common_pcmcia_cpufreq_nb;
842
843 ret = cpufreq_register_notifier(&skt->cpufreq_nb,
844 CPUFREQ_TRANSITION_NOTIFIER);
845 if (ret < 0)
846 dev_err(skt->socket.dev.parent,
847 "unable to register CPU frequency change notifier for PCMCIA (%d)\n",
848 ret);
849 }
850#endif
851
097e296d
RKAL
852 ret = pcmcia_register_socket(&skt->socket);
853 if (ret)
854 goto out_err_7;
855
097e296d
RKAL
856 ret = device_create_file(&skt->socket.dev, &dev_attr_status);
857 if (ret)
858 goto out_err_8;
859
860 return ret;
1da177e4 861
632480ea 862 out_err_8:
097e296d
RKAL
863 del_timer_sync(&skt->poll_timer);
864 pcmcia_unregister_socket(&skt->socket);
1da177e4
LT
865
866 out_err_7:
d9dc8787 867 soc_pcmcia_hw_shutdown(skt);
1da177e4 868 out_err_6:
097e296d 869 iounmap(skt->virt_io);
1da177e4 870 out_err_5:
097e296d 871 release_resource(&skt->res_attr);
1da177e4 872 out_err_4:
097e296d 873 release_resource(&skt->res_mem);
1da177e4 874 out_err_3:
097e296d 875 release_resource(&skt->res_io);
1da177e4 876 out_err_2:
097e296d 877 release_resource(&skt->res_skt);
1da177e4 878 out_err_1:
1da177e4 879
1da177e4
LT
880 return ret;
881}
097e296d 882EXPORT_SYMBOL(soc_pcmcia_add_one);
1da177e4 883
0f767de6
RKAL
884MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
885MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
886MODULE_LICENSE("Dual MPL/GPL");