aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:58:08 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:58:08 -0400
commit489de30259e667d7bc47da9da44a0270b050cd97 (patch)
tree6807814f443fe2c5d041c3bc3fe3ca8d22a955ca /drivers/pcmcia
parent1f1c2881f673671539b25686df463518d69c4649 (diff)
parentbf22f6fe2d72b4d7e9035be8ceb340414cf490e3 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (209 commits) [POWERPC] Create add_rtc() function to enable the RTC CMOS driver [POWERPC] Add H_ILLAN_ATTRIBUTES hcall number [POWERPC] xilinxfb: Parameterize xilinxfb platform device registration [POWERPC] Oprofile support for Power 5++ [POWERPC] Enable arbitary speed tty ioctls and split input/output speed [POWERPC] Make drivers/char/hvc_console.c:khvcd() static [POWERPC] Remove dead code for preventing pread() and pwrite() calls [POWERPC] Remove unnecessary #undef printk from prom.c [POWERPC] Fix typo in Ebony default DTS [POWERPC] Check for NULL ppc_md.init_IRQ() before calling [POWERPC] Remove extra return statement [POWERPC] pasemi: Don't auto-select CONFIG_EMBEDDED [POWERPC] pasemi: Rename platform [POWERPC] arch/powerpc/kernel/sysfs.c: Move NUMA exports [POWERPC] Add __read_mostly support for powerpc [POWERPC] Modify sched_clock() to make CONFIG_PRINTK_TIME more sane [POWERPC] Create a dummy zImage if no valid platform has been selected [POWERPC] PS3: Bootwrapper support. [POWERPC] powermac i2c: Use mutex [POWERPC] Schedule removal of arch/ppc ... Fixed up conflicts manually in: Documentation/feature-removal-schedule.txt arch/powerpc/kernel/pci_32.c arch/powerpc/kernel/pci_64.c include/asm-powerpc/pci.h and asked the powerpc people to double-check the result..
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig17
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c351
2 files changed, 176 insertions, 192 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 35f88649d3b7..c0c77f82d051 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -180,14 +180,15 @@ config TCIC
180 PCMCIA cards are plugged into. If unsure, say N. 180 PCMCIA cards are plugged into. If unsure, say N.
181 181
182config PCMCIA_M8XX 182config PCMCIA_M8XX
183 tristate "MPC8xx PCMCIA support" 183 tristate "MPC8xx PCMCIA support"
184 depends on PCMCIA && PPC && 8xx 184 depends on PCMCIA && PPC && 8xx
185 select PCCARD_IODYN 185 select PCCARD_IODYN
186 help 186 select PCCARD_NONSTATIC
187 Say Y here to include support for PowerPC 8xx series PCMCIA 187 help
188 controller. 188 Say Y here to include support for PowerPC 8xx series PCMCIA
189 189 controller.
190 This driver is also available as a module called m8xx_pcmcia. 190
191 This driver is also available as a module called m8xx_pcmcia.
191 192
192config HD64465_PCMCIA 193config HD64465_PCMCIA
193 tristate "HD64465 host bridge support" 194 tristate "HD64465 host bridge support"
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 9721ed7bf502..3b40f9623cc9 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -10,7 +10,7 @@
10 * Further fixes, v2.6 kernel port 10 * Further fixes, v2.6 kernel port
11 * <marcelo.tosatti@cyclades.com> 11 * <marcelo.tosatti@cyclades.com>
12 * 12 *
13 * Some fixes, additions (C) 2005 Montavista Software, Inc. 13 * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
14 * <vbordug@ru.mvista.com> 14 * <vbordug@ru.mvista.com>
15 * 15 *
16 * "The ExCA standard specifies that socket controllers should provide 16 * "The ExCA standard specifies that socket controllers should provide
@@ -40,10 +40,6 @@
40#include <linux/fcntl.h> 40#include <linux/fcntl.h>
41#include <linux/string.h> 41#include <linux/string.h>
42 42
43#include <asm/io.h>
44#include <asm/bitops.h>
45#include <asm/system.h>
46
47#include <linux/kernel.h> 43#include <linux/kernel.h>
48#include <linux/errno.h> 44#include <linux/errno.h>
49#include <linux/slab.h> 45#include <linux/slab.h>
@@ -51,11 +47,18 @@
51#include <linux/ioport.h> 47#include <linux/ioport.h>
52#include <linux/delay.h> 48#include <linux/delay.h>
53#include <linux/interrupt.h> 49#include <linux/interrupt.h>
54#include <linux/platform_device.h> 50#include <linux/fsl_devices.h>
55 51
52#include <asm/io.h>
53#include <asm/bitops.h>
54#include <asm/system.h>
55#include <asm/time.h>
56#include <asm/mpc8xx.h> 56#include <asm/mpc8xx.h>
57#include <asm/8xx_immap.h> 57#include <asm/8xx_immap.h>
58#include <asm/irq.h> 58#include <asm/irq.h>
59#include <asm/fs_pd.h>
60#include <asm/of_device.h>
61#include <asm/of_platform.h>
59 62
60#include <pcmcia/version.h> 63#include <pcmcia/version.h>
61#include <pcmcia/cs_types.h> 64#include <pcmcia/cs_types.h>
@@ -146,27 +149,17 @@ MODULE_LICENSE("Dual MPL/GPL");
146#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */ 149#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
147#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */ 150#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
148#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */ 151#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
149
150#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level */
151
152/* ------------------------------------------------------------------------- */ 152/* ------------------------------------------------------------------------- */
153 153
154/* 2.4.x and newer has this always in HZ */ 154static int pcmcia_schlvl;
155#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
156
157static int pcmcia_schlvl = PCMCIA_SCHLVL;
158 155
159static DEFINE_SPINLOCK(events_lock); 156static DEFINE_SPINLOCK(events_lock);
160 157
161
162#define PCMCIA_SOCKET_KEY_5V 1 158#define PCMCIA_SOCKET_KEY_5V 1
163#define PCMCIA_SOCKET_KEY_LV 2 159#define PCMCIA_SOCKET_KEY_LV 2
164 160
165/* look up table for pgcrx registers */ 161/* look up table for pgcrx registers */
166static u32 *m8xx_pgcrx[2] = { 162static u32 *m8xx_pgcrx[2];
167 &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
168 &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
169};
170 163
171/* 164/*
172 * This structure is used to address each window in the PCMCIA controller. 165 * This structure is used to address each window in the PCMCIA controller.
@@ -228,11 +221,16 @@ struct event_table {
228 u32 eventbit; 221 u32 eventbit;
229}; 222};
230 223
224static const char driver_name[] = "m8xx-pcmcia";
225
231struct socket_info { 226struct socket_info {
232 void (*handler)(void *info, u32 events); 227 void (*handler)(void *info, u32 events);
233 void *info; 228 void *info;
234 229
235 u32 slot; 230 u32 slot;
231 pcmconf8xx_t *pcmcia;
232 u32 bus_freq;
233 int hwirq;
236 234
237 socket_state_t state; 235 socket_state_t state;
238 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO]; 236 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
@@ -408,78 +406,21 @@ static void hardware_disable(int slot)
408#if defined(CONFIG_MPC885ADS) 406#if defined(CONFIG_MPC885ADS)
409 407
410#define PCMCIA_BOARD_MSG "MPC885ADS" 408#define PCMCIA_BOARD_MSG "MPC885ADS"
409#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
411 410
412static int voltage_set(int slot, int vcc, int vpp) 411static inline void hardware_enable(int slot)
413{ 412{
414 u32 reg = 0; 413 m8xx_pcmcia_ops.hw_ctrl(slot, 1);
415 unsigned *bcsr_io;
416
417 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
418
419 switch(vcc) {
420 case 0:
421 break;
422 case 33:
423 reg |= BCSR1_PCCVCC0;
424 break;
425 case 50:
426 reg |= BCSR1_PCCVCC1;
427 break;
428 default:
429 goto out_unmap;
430 }
431
432 switch(vpp) {
433 case 0:
434 break;
435 case 33:
436 case 50:
437 if(vcc == vpp)
438 reg |= BCSR1_PCCVPP1;
439 else
440 goto out_unmap;
441 break;
442 case 120:
443 if ((vcc == 33) || (vcc == 50))
444 reg |= BCSR1_PCCVPP0;
445 else
446 goto out_unmap;
447 default:
448 goto out_unmap;
449 }
450
451 /* first, turn off all power */
452 out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
453
454 /* enable new powersettings */
455 out_be32(bcsr_io, in_be32(bcsr_io) | reg);
456
457 iounmap(bcsr_io);
458 return 0;
459
460out_unmap:
461 iounmap(bcsr_io);
462 return 1;
463} 414}
464 415
465#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V 416static inline void hardware_disable(int slot)
466
467static void hardware_enable(int slot)
468{ 417{
469 unsigned *bcsr_io; 418 m8xx_pcmcia_ops.hw_ctrl(slot, 0);
470
471 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
472 out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
473 iounmap(bcsr_io);
474} 419}
475 420
476static void hardware_disable(int slot) 421static inline int voltage_set(int slot, int vcc, int vpp)
477{ 422{
478 unsigned *bcsr_io; 423 return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
479
480 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
481 out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN);
482 iounmap(bcsr_io);
483} 424}
484 425
485#endif 426#endif
@@ -604,48 +545,6 @@ static int voltage_set(int slot, int vcc, int vpp)
604 545
605#endif /* CONFIG_PRxK */ 546#endif /* CONFIG_PRxK */
606 547
607static void m8xx_shutdown(void)
608{
609 u32 m, i;
610 struct pcmcia_win *w;
611
612 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
613 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
614
615 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i));
616 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
617
618 /* turn off interrupt and disable CxOE */
619 out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
620
621 /* turn off memory windows */
622 for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
623 out_be32(&w->or, 0); /* set to not valid */
624 w++;
625 }
626
627 /* turn off voltage */
628 voltage_set(i, 0, 0);
629
630 /* disable external hardware */
631 hardware_disable(i);
632 }
633
634 free_irq(pcmcia_schlvl, NULL);
635}
636
637static struct device_driver m8xx_driver = {
638 .name = "m8xx-pcmcia",
639 .bus = &platform_bus_type,
640 .suspend = pcmcia_socket_dev_suspend,
641 .resume = pcmcia_socket_dev_resume,
642};
643
644static struct platform_device m8xx_device = {
645 .name = "m8xx-pcmcia",
646 .id = 0,
647};
648
649static u32 pending_events[PCMCIA_SOCKETS_NO]; 548static u32 pending_events[PCMCIA_SOCKETS_NO];
650static DEFINE_SPINLOCK(pending_event_lock); 549static DEFINE_SPINLOCK(pending_event_lock);
651 550
@@ -654,13 +553,14 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
654 struct socket_info *s; 553 struct socket_info *s;
655 struct event_table *e; 554 struct event_table *e;
656 unsigned int i, events, pscr, pipr, per; 555 unsigned int i, events, pscr, pipr, per;
556 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
657 557
658 dprintk("Interrupt!\n"); 558 dprintk("Interrupt!\n");
659 /* get interrupt sources */ 559 /* get interrupt sources */
660 560
661 pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr); 561 pscr = in_be32(&pcmcia->pcmc_pscr);
662 pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr); 562 pipr = in_be32(&pcmcia->pcmc_pipr);
663 per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per); 563 per = in_be32(&pcmcia->pcmc_per);
664 564
665 for(i = 0; i < PCMCIA_SOCKETS_NO; i++) { 565 for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
666 s = &socket[i]; 566 s = &socket[i];
@@ -724,7 +624,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
724 per &= ~M8XX_PCMCIA_RDY_L(0); 624 per &= ~M8XX_PCMCIA_RDY_L(0);
725 per &= ~M8XX_PCMCIA_RDY_L(1); 625 per &= ~M8XX_PCMCIA_RDY_L(1);
726 626
727 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per); 627 out_be32(&pcmcia->pcmc_per, per);
728 628
729 if (events) 629 if (events)
730 pcmcia_parse_events(&socket[i].socket, events); 630 pcmcia_parse_events(&socket[i].socket, events);
@@ -732,7 +632,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
732 } 632 }
733 633
734 /* clear the interrupt sources */ 634 /* clear the interrupt sources */
735 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr); 635 out_be32(&pcmcia->pcmc_pscr, pscr);
736 636
737 dprintk("Interrupt done.\n"); 637 dprintk("Interrupt done.\n");
738 638
@@ -753,7 +653,7 @@ static u32 m8xx_get_graycode(u32 size)
753 return k; 653 return k;
754} 654}
755 655
756static u32 m8xx_get_speed(u32 ns, u32 is_io) 656static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
757{ 657{
758 u32 reg, clocks, psst, psl, psht; 658 u32 reg, clocks, psst, psl, psht;
759 659
@@ -781,7 +681,7 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io)
781 681
782#define ADJ 180 /* 80 % longer accesstime - to be sure */ 682#define ADJ 180 /* 80 % longer accesstime - to be sure */
783 683
784 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000; 684 clocks = ((bus_freq / 1000) * ns) / 1000;
785 clocks = (clocks * ADJ) / (100*1000); 685 clocks = (clocks * ADJ) / (100*1000);
786 if(clocks >= PCMCIA_BMT_LIMIT) { 686 if(clocks >= PCMCIA_BMT_LIMIT) {
787 printk( "Max access time limit reached\n"); 687 printk( "Max access time limit reached\n");
@@ -806,8 +706,9 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
806 int lsock = container_of(sock, struct socket_info, socket)->slot; 706 int lsock = container_of(sock, struct socket_info, socket)->slot;
807 struct socket_info *s = &socket[lsock]; 707 struct socket_info *s = &socket[lsock];
808 unsigned int pipr, reg; 708 unsigned int pipr, reg;
709 pcmconf8xx_t *pcmcia = s->pcmcia;
809 710
810 pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr); 711 pipr = in_be32(&pcmcia->pcmc_pipr);
811 712
812 *value = ((pipr & (M8XX_PCMCIA_CD1(lsock) 713 *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
813 | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0; 714 | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
@@ -918,6 +819,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
918 struct event_table *e; 819 struct event_table *e;
919 unsigned int reg; 820 unsigned int reg;
920 unsigned long flags; 821 unsigned long flags;
822 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
921 823
922 dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " 824 dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
923 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags, 825 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
@@ -927,6 +829,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
927 if(voltage_set(lsock, state->Vcc, state->Vpp)) 829 if(voltage_set(lsock, state->Vcc, state->Vpp))
928 return -EINVAL; 830 return -EINVAL;
929 831
832
930 /* Take care of reset... */ 833 /* Take care of reset... */
931 if(state->flags & SS_RESET) 834 if(state->flags & SS_RESET)
932 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */ 835 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
@@ -982,7 +885,8 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
982 * If io_irq is non-zero we should enable irq. 885 * If io_irq is non-zero we should enable irq.
983 */ 886 */
984 if(state->io_irq) { 887 if(state->io_irq) {
985 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24); 888 out_be32(M8XX_PGCRX(lsock),
889 in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(s->hwirq) << 24);
986 /* 890 /*
987 * Strange thing here: 891 * Strange thing here:
988 * The manual does not tell us which interrupt 892 * The manual does not tell us which interrupt
@@ -1027,7 +931,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
1027 * Writing ones will clear the bits. 931 * Writing ones will clear the bits.
1028 */ 932 */
1029 933
1030 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg); 934 out_be32(&pcmcia->pcmc_pscr, reg);
1031 935
1032 /* 936 /*
1033 * Write the mask. 937 * Write the mask.
@@ -1036,15 +940,8 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
1036 * Ones will enable the interrupt. 940 * Ones will enable the interrupt.
1037 */ 941 */
1038 942
1039 /* 943 reg |= in_be32(&pcmcia->pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1040 reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 944 out_be32(&pcmcia->pcmc_per, reg);
1041 & M8XX_PCMCIA_MASK(lsock);
1042 */
1043
1044 reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
1045 (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1046
1047 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
1048 945
1049 spin_unlock_irqrestore(&events_lock, flags); 946 spin_unlock_irqrestore(&events_lock, flags);
1050 947
@@ -1062,6 +959,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1062 struct socket_info *s = &socket[lsock]; 959 struct socket_info *s = &socket[lsock];
1063 struct pcmcia_win *w; 960 struct pcmcia_win *w;
1064 unsigned int reg, winnr; 961 unsigned int reg, winnr;
962 pcmconf8xx_t *pcmcia = s->pcmcia;
963
1065 964
1066#define M8XX_SIZE (io->stop - io->start + 1) 965#define M8XX_SIZE (io->stop - io->start + 1)
1067#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start) 966#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
@@ -1086,7 +985,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1086 985
1087 /* setup registers */ 986 /* setup registers */
1088 987
1089 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 988 w = (void *) &pcmcia->pcmc_pbr0;
1090 w += winnr; 989 w += winnr;
1091 990
1092 out_be32(&w->or, 0); /* turn off window first */ 991 out_be32(&w->or, 0); /* turn off window first */
@@ -1095,12 +994,13 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1095 reg <<= 27; 994 reg <<= 27;
1096 reg |= M8XX_PCMCIA_POR_IO |(lsock << 2); 995 reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
1097 996
1098 reg |= m8xx_get_speed(io->speed, 1); 997 reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
1099 998
1100 if(io->flags & MAP_WRPROT) 999 if(io->flags & MAP_WRPROT)
1101 reg |= M8XX_PCMCIA_POR_WRPROT; 1000 reg |= M8XX_PCMCIA_POR_WRPROT;
1102 1001
1103 if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) 1002 /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
1003 if(io->flags & MAP_16BIT)
1104 reg |= M8XX_PCMCIA_POR_16BIT; 1004 reg |= M8XX_PCMCIA_POR_16BIT;
1105 1005
1106 if(io->flags & MAP_ACTIVE) 1006 if(io->flags & MAP_ACTIVE)
@@ -1117,7 +1017,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1117 1017
1118 /* setup registers */ 1018 /* setup registers */
1119 1019
1120 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 1020 w = (void *) &pcmcia->pcmc_pbr0;
1121 w += winnr; 1021 w += winnr;
1122 1022
1123 out_be32(&w->or, 0); /* turn off window */ 1023 out_be32(&w->or, 0); /* turn off window */
@@ -1144,6 +1044,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
1144 struct pcmcia_win *w; 1044 struct pcmcia_win *w;
1145 struct pccard_mem_map *old; 1045 struct pccard_mem_map *old;
1146 unsigned int reg, winnr; 1046 unsigned int reg, winnr;
1047 pcmconf8xx_t *pcmcia = s->pcmcia;
1147 1048
1148 dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, " 1049 dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
1149 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, 1050 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
@@ -1166,12 +1067,12 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
1166 1067
1167 /* Setup the window in the pcmcia controller */ 1068 /* Setup the window in the pcmcia controller */
1168 1069
1169 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 1070 w = (void *) &pcmcia->pcmc_pbr0;
1170 w += winnr; 1071 w += winnr;
1171 1072
1172 reg |= lsock << 2; 1073 reg |= lsock << 2;
1173 1074
1174 reg |= m8xx_get_speed(mem->speed, 0); 1075 reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
1175 1076
1176 if(mem->flags & MAP_ATTRIB) 1077 if(mem->flags & MAP_ATTRIB)
1177 reg |= M8XX_PCMCIA_POR_ATTRMEM; 1078 reg |= M8XX_PCMCIA_POR_ATTRMEM;
@@ -1236,60 +1137,69 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
1236 1137
1237} 1138}
1238 1139
1239static int m8xx_suspend(struct pcmcia_socket *sock) 1140static int m8xx_sock_suspend(struct pcmcia_socket *sock)
1240{ 1141{
1241 return m8xx_set_socket(sock, &dead_socket); 1142 return m8xx_set_socket(sock, &dead_socket);
1242} 1143}
1243 1144
1244static struct pccard_operations m8xx_services = { 1145static struct pccard_operations m8xx_services = {
1245 .init = m8xx_sock_init, 1146 .init = m8xx_sock_init,
1246 .suspend = m8xx_suspend, 1147 .suspend = m8xx_sock_suspend,
1247 .get_status = m8xx_get_status, 1148 .get_status = m8xx_get_status,
1248 .set_socket = m8xx_set_socket, 1149 .set_socket = m8xx_set_socket,
1249 .set_io_map = m8xx_set_io_map, 1150 .set_io_map = m8xx_set_io_map,
1250 .set_mem_map = m8xx_set_mem_map, 1151 .set_mem_map = m8xx_set_mem_map,
1251}; 1152};
1252 1153
1253static int __init m8xx_init(void) 1154static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id *match)
1254{ 1155{
1255 struct pcmcia_win *w; 1156 struct pcmcia_win *w;
1256 unsigned int i,m; 1157 unsigned int i, m, hwirq;
1158 pcmconf8xx_t *pcmcia;
1159 int status;
1160 struct device_node *np = ofdev->node;
1257 1161
1258 pcmcia_info("%s\n", version); 1162 pcmcia_info("%s\n", version);
1259 1163
1260 if (driver_register(&m8xx_driver)) 1164 pcmcia = of_iomap(np, 0);
1261 return -1; 1165 if(pcmcia == NULL)
1166 return -EINVAL;
1167
1168 pcmcia_schlvl = irq_of_parse_and_map(np, 0);
1169 hwirq = irq_map[pcmcia_schlvl].hwirq;
1170 if (pcmcia_schlvl < 0)
1171 return -EINVAL;
1172
1173 m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
1174 m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
1175
1262 1176
1263 pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG 1177 pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
1264 " with IRQ %u.\n", pcmcia_schlvl); 1178 " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
1265 1179
1266 /* Configure Status change interrupt */ 1180 /* Configure Status change interrupt */
1267 1181
1268 if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0, 1182 if(request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
1269 "m8xx_pcmcia", NULL)) { 1183 driver_name, socket)) {
1270 pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n", 1184 pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
1271 pcmcia_schlvl); 1185 pcmcia_schlvl);
1272 return -1; 1186 return -1;
1273 } 1187 }
1274 1188
1275 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 1189 w = (void *) &pcmcia->pcmc_pbr0;
1276
1277 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
1278 M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
1279 1190
1280 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, 1191 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
1281 in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & 1192 clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1282 ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
1283 1193
1284/* connect interrupt and disable CxOE */ 1194 /* connect interrupt and disable CxOE */
1285 1195
1286 out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16)); 1196 out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1287 out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16)); 1197 out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1288 1198
1289/* intialize the fixed memory windows */ 1199 /* intialize the fixed memory windows */
1290 1200
1291 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){ 1201 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
1292 for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) { 1202 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1293 out_be32(&w->br, PCMCIA_MEM_WIN_BASE + 1203 out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
1294 (PCMCIA_MEM_WIN_SIZE 1204 (PCMCIA_MEM_WIN_SIZE
1295 * (m + i * PCMCIA_MEM_WIN_NO))); 1205 * (m + i * PCMCIA_MEM_WIN_NO)));
@@ -1300,16 +1210,14 @@ static int __init m8xx_init(void)
1300 } 1210 }
1301 } 1211 }
1302 1212
1303/* turn off voltage */ 1213 /* turn off voltage */
1304 voltage_set(0, 0, 0); 1214 voltage_set(0, 0, 0);
1305 voltage_set(1, 0, 0); 1215 voltage_set(1, 0, 0);
1306 1216
1307/* Enable external hardware */ 1217 /* Enable external hardware */
1308 hardware_enable(0); 1218 hardware_enable(0);
1309 hardware_enable(1); 1219 hardware_enable(1);
1310 1220
1311 platform_device_register(&m8xx_device);
1312
1313 for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) { 1221 for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
1314 socket[i].slot = i; 1222 socket[i].slot = i;
1315 socket[i].socket.owner = THIS_MODULE; 1223 socket[i].socket.owner = THIS_MODULE;
@@ -1317,30 +1225,105 @@ static int __init m8xx_init(void)
1317 socket[i].socket.irq_mask = 0x000; 1225 socket[i].socket.irq_mask = 0x000;
1318 socket[i].socket.map_size = 0x1000; 1226 socket[i].socket.map_size = 0x1000;
1319 socket[i].socket.io_offset = 0; 1227 socket[i].socket.io_offset = 0;
1320 socket[i].socket.pci_irq = i ? 7 : 9; 1228 socket[i].socket.pci_irq = pcmcia_schlvl;
1321 socket[i].socket.ops = &m8xx_services; 1229 socket[i].socket.ops = &m8xx_services;
1322 socket[i].socket.resource_ops = &pccard_iodyn_ops; 1230 socket[i].socket.resource_ops = &pccard_nonstatic_ops;
1323 socket[i].socket.cb_dev = NULL; 1231 socket[i].socket.cb_dev = NULL;
1324 socket[i].socket.dev.parent = &m8xx_device.dev; 1232 socket[i].socket.dev.parent = &ofdev->dev;
1233 socket[i].pcmcia = pcmcia;
1234 socket[i].bus_freq = ppc_proc_freq;
1235 socket[i].hwirq = hwirq;
1236
1237
1325 } 1238 }
1326 1239
1327 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) 1240 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1328 pcmcia_register_socket(&socket[i].socket); 1241 status = pcmcia_register_socket(&socket[i].socket);
1242 if (status < 0)
1243 pcmcia_error("Socket register failed\n");
1244 }
1329 1245
1330 return 0; 1246 return 0;
1331} 1247}
1332 1248
1333static void __exit m8xx_exit(void) 1249static int m8xx_remove(struct of_device* ofdev)
1334{ 1250{
1335 int i; 1251 u32 m, i;
1252 struct pcmcia_win *w;
1253 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
1254
1255 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1256 w = (void *) &pcmcia->pcmc_pbr0;
1257
1258 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
1259 out_be32(&pcmcia->pcmc_per,
1260 in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
1336 1261
1262 /* turn off interrupt and disable CxOE */
1263 out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
1264
1265 /* turn off memory windows */
1266 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1267 out_be32(&w->or, 0); /* set to not valid */
1268 w++;
1269 }
1270
1271 /* turn off voltage */
1272 voltage_set(i, 0, 0);
1273
1274 /* disable external hardware */
1275 hardware_disable(i);
1276 }
1337 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) 1277 for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
1338 pcmcia_unregister_socket(&socket[i].socket); 1278 pcmcia_unregister_socket(&socket[i].socket);
1339 1279
1340 m8xx_shutdown(); 1280 free_irq(pcmcia_schlvl, NULL);
1341 1281
1342 platform_device_unregister(&m8xx_device); 1282 return 0;
1343 driver_unregister(&m8xx_driver); 1283}
1284
1285#ifdef CONFIG_PM
1286static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
1287{
1288 return pcmcia_socket_dev_suspend(&pdev->dev, state);
1289}
1290
1291static int m8xx_resume(struct platform_device *pdev)
1292{
1293 return pcmcia_socket_dev_resume(&pdev->dev);
1294}
1295#else
1296#define m8xx_suspend NULL
1297#define m8xx_resume NULL
1298#endif
1299
1300static struct of_device_id m8xx_pcmcia_match[] = {
1301 {
1302 .type = "pcmcia",
1303 .compatible = "fsl,pq-pcmcia",
1304 },
1305 {},
1306};
1307
1308MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
1309
1310static struct of_platform_driver m8xx_pcmcia_driver = {
1311 .name = (char *) driver_name,
1312 .match_table = m8xx_pcmcia_match,
1313 .probe = m8xx_probe,
1314 .remove = m8xx_remove,
1315 .suspend = m8xx_suspend,
1316 .resume = m8xx_resume,
1317};
1318
1319static int __init m8xx_init(void)
1320{
1321 return of_register_platform_driver(&m8xx_pcmcia_driver);
1322}
1323
1324static void __exit m8xx_exit(void)
1325{
1326 of_unregister_platform_driver(&m8xx_pcmcia_driver);
1344} 1327}
1345 1328
1346module_init(m8xx_init); 1329module_init(m8xx_init);