| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Sharp SL-C7xx Series PCMCIA routines | 
 | 3 |  * | 
 | 4 |  * Copyright (c) 2004-2005 Richard Purdie | 
 | 5 |  * | 
 | 6 |  * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c | 
 | 7 |  * | 
 | 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 | 
 | 10 |  * published by the Free Software Foundation. | 
 | 11 |  * | 
 | 12 |  */ | 
 | 13 |  | 
 | 14 | #include <linux/module.h> | 
 | 15 | #include <linux/init.h> | 
 | 16 | #include <linux/kernel.h> | 
 | 17 | #include <linux/errno.h> | 
 | 18 | #include <linux/interrupt.h> | 
| Russell King | d052d1b | 2005-10-29 19:07:23 +0100 | [diff] [blame] | 19 | #include <linux/platform_device.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 |  | 
| Pavel Machek | 77bb86a | 2005-10-30 23:39:02 +0000 | [diff] [blame] | 21 | #include <asm/mach-types.h> | 
| Russell King | a09e64f | 2008-08-05 16:14:15 +0100 | [diff] [blame] | 22 | #include <mach/hardware.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 | #include <asm/irq.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 24 | #include <asm/hardware/scoop.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 25 |  | 
 | 26 | #include "soc_common.h" | 
 | 27 |  | 
 | 28 | #define	NO_KEEP_VS 0x0001 | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 29 | #define SCOOP_DEV platform_scoop_config->devs | 
 | 30 |  | 
| Richard Purdie | 945b957 | 2006-01-05 20:44:57 +0000 | [diff] [blame] | 31 | static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 32 | { | 
| Richard Purdie | 945b957 | 2006-01-05 20:44:57 +0000 | [diff] [blame] | 33 | 	struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr]; | 
 | 34 |  | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 35 | 	reset_scoop(scoopdev->dev); | 
| Richard Purdie | 945b957 | 2006-01-05 20:44:57 +0000 | [diff] [blame] | 36 |  | 
 | 37 | 	/* Shared power controls need to be handled carefully */ | 
 | 38 | 	if (platform_scoop_config->power_ctrl) | 
 | 39 | 		platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr); | 
 | 40 | 	else | 
 | 41 | 		write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000); | 
 | 42 |  | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 43 | 	scoopdev->keep_vs = NO_KEEP_VS; | 
 | 44 | 	scoopdev->keep_rd = 0; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 45 | } | 
 | 46 |  | 
 | 47 | static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 
 | 48 | { | 
 | 49 | 	int ret; | 
 | 50 |  | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 51 | 	if (platform_scoop_config->pcmcia_init) | 
 | 52 | 		platform_scoop_config->pcmcia_init(); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 53 |  | 
 | 54 | 	/* Register interrupts */ | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 55 | 	if (SCOOP_DEV[skt->nr].cd_irq >= 0) { | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 56 | 		struct pcmcia_irqs cd_irq; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 |  | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 58 | 		cd_irq.sock = skt->nr; | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 59 | 		cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq; | 
 | 60 | 		cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str; | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 61 | 		ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); | 
 | 62 |  | 
 | 63 | 		if (ret) { | 
 | 64 | 			printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); | 
 | 65 | 			return ret; | 
 | 66 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | 	} | 
 | 68 |  | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 69 | 	skt->irq = SCOOP_DEV[skt->nr].irq; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 70 |  | 
 | 71 | 	return 0; | 
 | 72 | } | 
 | 73 |  | 
 | 74 | static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 
 | 75 | { | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 76 | 	if (SCOOP_DEV[skt->nr].cd_irq >= 0) { | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 77 | 		struct pcmcia_irqs cd_irq; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 78 |  | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 79 | 		cd_irq.sock = skt->nr; | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 80 | 		cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq; | 
 | 81 | 		cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str; | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 82 | 		soc_pcmcia_free_irqs(skt, &cd_irq, 1); | 
 | 83 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 84 | } | 
 | 85 |  | 
 | 86 |  | 
 | 87 | static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 
 | 88 | 				    struct pcmcia_state *state) | 
 | 89 | { | 
 | 90 | 	unsigned short cpr, csr; | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 91 | 	struct device *scoop = SCOOP_DEV[skt->nr].dev; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 92 |  | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 93 | 	cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 94 |  | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 95 | 	write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); | 
 | 96 | 	write_scoop_reg(scoop, SCOOP_ISR, 0x0000); | 
 | 97 | 	write_scoop_reg(scoop, SCOOP_IRM, 0x0000); | 
 | 98 | 	csr = read_scoop_reg(scoop, SCOOP_CSR); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 99 | 	if (csr & 0x0004) { | 
 | 100 | 		/* card eject */ | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 101 | 		write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 102 | 		SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 103 | 	} | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 104 | 	else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 105 | 		/* keep vs1,vs2 */ | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 106 | 		write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 107 | 		csr |= SCOOP_DEV[skt->nr].keep_vs; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 108 | 	} | 
 | 109 | 	else if (cpr & 0x0003) { | 
 | 110 | 		/* power on */ | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 111 | 		write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 112 | 		SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 113 | 	} | 
 | 114 | 	else { | 
 | 115 | 		/* card detect */ | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 116 | 	        if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) { | 
 | 117 | 	                write_scoop_reg(scoop, SCOOP_CDR, 0x0000); | 
 | 118 | 	        } else { | 
 | 119 | 		        write_scoop_reg(scoop, SCOOP_CDR, 0x0002); | 
 | 120 | 	        } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 | 	} | 
 | 122 |  | 
 | 123 | 	state->detect = (csr & 0x0004) ? 0 : 1; | 
 | 124 | 	state->ready  = (csr & 0x0002) ? 1 : 0; | 
 | 125 | 	state->bvd1   = (csr & 0x0010) ? 1 : 0; | 
 | 126 | 	state->bvd2   = (csr & 0x0020) ? 1 : 0; | 
 | 127 | 	state->wrprot = (csr & 0x0008) ? 1 : 0; | 
 | 128 | 	state->vs_3v  = (csr & 0x0040) ? 0 : 1; | 
 | 129 | 	state->vs_Xv  = (csr & 0x0080) ? 0 : 1; | 
 | 130 |  | 
 | 131 | 	if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { | 
 | 132 | 		printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); | 
 | 133 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 134 | } | 
 | 135 |  | 
 | 136 |  | 
 | 137 | static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 
 | 138 | 				       const socket_state_t *state) | 
 | 139 | { | 
 | 140 | 	unsigned long flags; | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 141 | 	struct device *scoop = SCOOP_DEV[skt->nr].dev; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 142 |  | 
 | 143 | 	unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; | 
 | 144 |  | 
 | 145 | 	switch (state->Vcc) { | 
 | 146 | 	case	0:  	break; | 
 | 147 | 	case 	33: 	break; | 
 | 148 | 	case	50: 	break; | 
 | 149 | 	default: | 
 | 150 | 		 printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc); | 
 | 151 | 		 return -1; | 
 | 152 | 	} | 
 | 153 |  | 
 | 154 | 	if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) { | 
 | 155 | 		printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp); | 
 | 156 | 		return -1; | 
 | 157 | 	} | 
 | 158 |  | 
 | 159 | 	local_irq_save(flags); | 
 | 160 |  | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 161 | 	nmcr = (mcr = read_scoop_reg(scoop, SCOOP_MCR)) & ~0x0010; | 
 | 162 | 	ncpr = (cpr = read_scoop_reg(scoop, SCOOP_CPR)) & ~0x0083; | 
 | 163 | 	nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; | 
 | 164 | 	nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 165 |  | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 166 | 	if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) { | 
 | 167 | 	        ncpr |= (state->Vcc == 33) ? 0x0002 : | 
 | 168 | 		        (state->Vcc == 50) ? 0x0002 : 0; | 
 | 169 | 	} else { | 
 | 170 | 	        ncpr |= (state->Vcc == 33) ? 0x0001 : | 
 | 171 | 		        (state->Vcc == 50) ? 0x0002 : 0; | 
 | 172 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 173 | 	nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; | 
 | 174 | 	ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; | 
 | 175 | 	nccr |= (state->flags&SS_RESET)? 0x0080: 0; | 
 | 176 | 	nimr |=	((skt->status&SS_DETECT) ? 0x0004 : 0)| | 
 | 177 | 			((skt->status&SS_READY)  ? 0x0002 : 0)| | 
 | 178 | 			((skt->status&SS_BATDEAD)? 0x0010 : 0)| | 
 | 179 | 			((skt->status&SS_BATWARN)? 0x0020 : 0)| | 
 | 180 | 			((skt->status&SS_STSCHG) ? 0x0010 : 0)| | 
 | 181 | 			((skt->status&SS_WRPROT) ? 0x0008 : 0); | 
 | 182 |  | 
 | 183 | 	if (!(ncpr & 0x0003)) { | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 184 | 		SCOOP_DEV[skt->nr].keep_rd = 0; | 
 | 185 | 	} else if (!SCOOP_DEV[skt->nr].keep_rd) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 186 | 		if (nccr & 0x0080) | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 187 | 			SCOOP_DEV[skt->nr].keep_rd = 1; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 | 		else | 
 | 189 | 			nccr |= 0x0080; | 
 | 190 | 	} | 
 | 191 |  | 
 | 192 | 	if (mcr != nmcr) | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 193 | 		write_scoop_reg(scoop, SCOOP_MCR, nmcr); | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 194 | 	if (cpr != ncpr) { | 
 | 195 | 		if (platform_scoop_config->power_ctrl) | 
 | 196 | 			platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr); | 
 | 197 | 		else | 
 | 198 | 		        write_scoop_reg(scoop, SCOOP_CPR, ncpr); | 
 | 199 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 200 | 	if (ccr != nccr) | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 201 | 		write_scoop_reg(scoop, SCOOP_CCR, nccr); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 202 | 	if (imr != nimr) | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 203 | 		write_scoop_reg(scoop, SCOOP_IMR, nimr); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 204 |  | 
 | 205 | 	local_irq_restore(flags); | 
 | 206 |  | 
 | 207 | 	return 0; | 
 | 208 | } | 
 | 209 |  | 
 | 210 | static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 
 | 211 | { | 
| Richard Purdie | 945b957 | 2006-01-05 20:44:57 +0000 | [diff] [blame] | 212 | 	sharpsl_pcmcia_init_reset(skt); | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 213 |  | 
 | 214 | 	/* Enable interrupt */ | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 215 | 	write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); | 
 | 216 | 	write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); | 
 | 217 | 	SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 218 | } | 
 | 219 |  | 
 | 220 | static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 
 | 221 | { | 
| Richard Purdie | 945b957 | 2006-01-05 20:44:57 +0000 | [diff] [blame] | 222 | 	sharpsl_pcmcia_init_reset(skt); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 223 | } | 
 | 224 |  | 
| Russell King | 4e5e8de | 2008-04-24 15:28:11 +0100 | [diff] [blame] | 225 | static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 226 | 	.owner                  = THIS_MODULE, | 
 | 227 | 	.hw_init                = sharpsl_pcmcia_hw_init, | 
 | 228 | 	.hw_shutdown            = sharpsl_pcmcia_hw_shutdown, | 
 | 229 | 	.socket_state           = sharpsl_pcmcia_socket_state, | 
 | 230 | 	.configure_socket       = sharpsl_pcmcia_configure_socket, | 
 | 231 | 	.socket_init            = sharpsl_pcmcia_socket_init, | 
 | 232 | 	.socket_suspend         = sharpsl_pcmcia_socket_suspend, | 
 | 233 | 	.first                  = 0, | 
 | 234 | 	.nr                     = 0, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 235 | }; | 
 | 236 |  | 
| Pavel Machek | 77bb86a | 2005-10-30 23:39:02 +0000 | [diff] [blame] | 237 | #ifdef CONFIG_SA1100_COLLIE | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 238 | #include "sa11xx_base.h" | 
 | 239 |  | 
| Pavel Machek | 77bb86a | 2005-10-30 23:39:02 +0000 | [diff] [blame] | 240 | int __init pcmcia_collie_init(struct device *dev) | 
 | 241 | { | 
 | 242 |        int ret = -ENODEV; | 
 | 243 |  | 
 | 244 |        if (machine_is_collie()) | 
 | 245 |                ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1); | 
 | 246 |  | 
 | 247 |        return ret; | 
 | 248 | } | 
 | 249 |  | 
 | 250 | #else | 
 | 251 |  | 
| Richard Purdie | a63ae44 | 2005-11-08 19:15:43 +0000 | [diff] [blame] | 252 | static struct platform_device *sharpsl_pcmcia_device; | 
 | 253 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 254 | static int __init sharpsl_pcmcia_init(void) | 
 | 255 | { | 
 | 256 | 	int ret; | 
 | 257 |  | 
| Dmitry Baryshkov | ae1036a | 2009-04-20 17:48:28 +0100 | [diff] [blame] | 258 | 	if (!platform_scoop_config) | 
 | 259 | 		return -ENODEV; | 
 | 260 |  | 
| Richard Purdie | b016450 | 2006-01-10 17:16:12 +0000 | [diff] [blame] | 261 | 	sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs; | 
 | 262 | 	sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 
 | 263 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 264 | 	if (!sharpsl_pcmcia_device) | 
 | 265 | 		return -ENOMEM; | 
| Richard Purdie | 0ce7625 | 2005-09-05 20:49:54 +0100 | [diff] [blame] | 266 |  | 
| Russell King | 4e5e8de | 2008-04-24 15:28:11 +0100 | [diff] [blame] | 267 | 	ret = platform_device_add_data(sharpsl_pcmcia_device, | 
 | 268 | 			&sharpsl_pcmcia_ops, sizeof(sharpsl_pcmcia_ops)); | 
 | 269 | 	if (ret == 0) { | 
 | 270 | 		sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; | 
 | 271 | 		ret = platform_device_add(sharpsl_pcmcia_device); | 
 | 272 | 	} | 
| Richard Purdie | b016450 | 2006-01-10 17:16:12 +0000 | [diff] [blame] | 273 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 274 | 	if (ret) | 
| Richard Purdie | b016450 | 2006-01-10 17:16:12 +0000 | [diff] [blame] | 275 | 		platform_device_put(sharpsl_pcmcia_device); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 276 |  | 
 | 277 | 	return ret; | 
 | 278 | } | 
 | 279 |  | 
 | 280 | static void __exit sharpsl_pcmcia_exit(void) | 
 | 281 | { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 282 | 	platform_device_unregister(sharpsl_pcmcia_device); | 
 | 283 | } | 
 | 284 |  | 
| Richard Purdie | f36598a | 2005-09-03 19:39:25 +0100 | [diff] [blame] | 285 | fs_initcall(sharpsl_pcmcia_init); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 286 | module_exit(sharpsl_pcmcia_exit); | 
| Pavel Machek | 77bb86a | 2005-10-30 23:39:02 +0000 | [diff] [blame] | 287 | #endif | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 288 |  | 
 | 289 | MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); | 
 | 290 | MODULE_LICENSE("GPL"); | 
| Kay Sievers | 43cc71e | 2007-08-18 04:40:39 +0200 | [diff] [blame] | 291 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); |