aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2005-11-08 14:15:43 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-11-08 14:15:43 -0500
commita63ae4427c6af66d6eda26e5da8fed53f8fbede3 (patch)
treecb30bd5993c07bae7f66564713292d8b224d591f
parent1d23b65de54c35844e82bdb08bc85d8142e310ea (diff)
[ARM] 3093/1: SharpSL PCMCIA Updates for Cxx00 models
Patch from Richard Purdie The Sharp SL-Cxx00 models have a combined power control for the SD and CF slot 0. This patch adds hooks to the scoop driver to allow machines to provide a custom control function for this and such a function is added for spitz/akita/borzoi. It also moves the gpio init code into the machine files as this is machine dependent and differs between some models. A couple of warnings when compiling for collie are also fixed. Signed-off-by: Richard Purdie Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/common/scoop.c6
-rw-r--r--arch/arm/mach-pxa/corgi.c48
-rw-r--r--arch/arm/mach-pxa/poodle.c32
-rw-r--r--arch/arm/mach-pxa/spitz.c95
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c140
-rw-r--r--include/asm-arm/hardware/scoop.h10
6 files changed, 220 insertions, 111 deletions
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index bb4eff614413..c7fdf390cef9 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -19,12 +19,6 @@
19 19
20#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) 20#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
21 21
22/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
23 There is no easy way to link multiple scoop devices into one
24 single entity for the pxa2xx_pcmcia device */
25int scoop_num;
26struct scoop_pcmcia_dev *scoop_devs;
27
28struct scoop_dev { 22struct scoop_dev {
29 void *base; 23 void *base;
30 spinlock_t scoop_lock; 24 spinlock_t scoop_lock;
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index eb5f6d744a4a..100fb31b5156 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = {
62 .io_out = CORGI_SCOOP_IO_OUT, 62 .io_out = CORGI_SCOOP_IO_OUT,
63}; 63};
64 64
65struct platform_device corgiscoop_device = {
66 .name = "sharp-scoop",
67 .id = -1,
68 .dev = {
69 .platform_data = &corgi_scoop_setup,
70 },
71 .num_resources = ARRAY_SIZE(corgi_scoop_resources),
72 .resource = corgi_scoop_resources,
73};
74
75static void corgi_pcmcia_init(void)
76{
77 /* Setup default state of GPIO outputs
78 before we enable them as outputs. */
79 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
80 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
81 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
82 GPIO_bit(GPIO53_nPCE_2);
83
84 pxa_gpio_mode(GPIO48_nPOE_MD);
85 pxa_gpio_mode(GPIO49_nPWE_MD);
86 pxa_gpio_mode(GPIO50_nPIOR_MD);
87 pxa_gpio_mode(GPIO51_nPIOW_MD);
88 pxa_gpio_mode(GPIO55_nPREG_MD);
89 pxa_gpio_mode(GPIO56_nPWAIT_MD);
90 pxa_gpio_mode(GPIO57_nIOIS16_MD);
91 pxa_gpio_mode(GPIO52_nPCE_1_MD);
92 pxa_gpio_mode(GPIO53_nPCE_2_MD);
93 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
94}
95
65static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { 96static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
66{ 97{
67 .dev = &corgiscoop_device.dev, 98 .dev = &corgiscoop_device.dev,
@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
71}, 102},
72}; 103};
73 104
74struct platform_device corgiscoop_device = { 105static struct scoop_pcmcia_config corgi_pcmcia_config = {
75 .name = "sharp-scoop", 106 .devs = &corgi_pcmcia_scoop[0],
76 .id = -1, 107 .num_devs = 1,
77 .dev = { 108 .pcmcia_init = corgi_pcmcia_init,
78 .platform_data = &corgi_scoop_setup,
79 },
80 .num_resources = ARRAY_SIZE(corgi_scoop_resources),
81 .resource = corgi_scoop_resources,
82}; 109};
83 110
111EXPORT_SYMBOL(corgiscoop_device);
112
84 113
85/* 114/*
86 * Corgi SSP Device 115 * Corgi SSP Device
@@ -294,8 +323,7 @@ static void __init corgi_init(void)
294 pxa_set_mci_info(&corgi_mci_platform_data); 323 pxa_set_mci_info(&corgi_mci_platform_data);
295 pxa_set_ficp_info(&corgi_ficp_platform_data); 324 pxa_set_ficp_info(&corgi_ficp_platform_data);
296 325
297 scoop_num = 1; 326 platform_scoop_config = &corgi_pcmcia_config;
298 scoop_devs = &corgi_pcmcia_scoop[0];
299 327
300 platform_add_devices(devices, ARRAY_SIZE(devices)); 328 platform_add_devices(devices, ARRAY_SIZE(devices));
301} 329}
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index ad6a13f95a62..eef3de26ad37 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = {
65 .resource = poodle_scoop_resources, 65 .resource = poodle_scoop_resources,
66}; 66};
67 67
68static void poodle_pcmcia_init(void)
69{
70 /* Setup default state of GPIO outputs
71 before we enable them as outputs. */
72 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
73 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
74 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
75 GPIO_bit(GPIO53_nPCE_2);
76
77 pxa_gpio_mode(GPIO48_nPOE_MD);
78 pxa_gpio_mode(GPIO49_nPWE_MD);
79 pxa_gpio_mode(GPIO50_nPIOR_MD);
80 pxa_gpio_mode(GPIO51_nPIOW_MD);
81 pxa_gpio_mode(GPIO55_nPREG_MD);
82 pxa_gpio_mode(GPIO56_nPWAIT_MD);
83 pxa_gpio_mode(GPIO57_nIOIS16_MD);
84 pxa_gpio_mode(GPIO52_nPCE_1_MD);
85 pxa_gpio_mode(GPIO53_nPCE_2_MD);
86 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
87}
88
68static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { 89static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
69{ 90{
70 .dev = &poodle_scoop_device.dev, 91 .dev = &poodle_scoop_device.dev,
@@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
74}, 95},
75}; 96};
76 97
98static struct scoop_pcmcia_config poodle_pcmcia_config = {
99 .devs = &poodle_pcmcia_scoop[0],
100 .num_devs = 1,
101 .pcmcia_init = poodle_pcmcia_init,
102};
103
104EXPORT_SYMBOL(poodle_scoop_device);
105
77 106
78/* LoCoMo device */ 107/* LoCoMo device */
79static struct resource locomo_resources[] = { 108static struct resource locomo_resources[] = {
@@ -268,8 +297,7 @@ static void __init poodle_init(void)
268 pxa_set_mci_info(&poodle_mci_platform_data); 297 pxa_set_mci_info(&poodle_mci_platform_data);
269 pxa_set_ficp_info(&poodle_ficp_platform_data); 298 pxa_set_ficp_info(&poodle_ficp_platform_data);
270 299
271 scoop_num = 1; 300 platform_scoop_config = &poodle_pcmcia_config;
272 scoop_devs = &poodle_pcmcia_scoop[0];
273 301
274 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 302 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
275 if (ret) { 303 if (ret) {
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 6c6878cd2207..4e9a699ee428 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = {
104 .resource = spitz_scoop2_resources, 104 .resource = spitz_scoop2_resources,
105}; 105};
106 106
107#define SPITZ_PWR_SD 0x01
108#define SPITZ_PWR_CF 0x02
109
110/* Power control is shared with between one of the CF slots and SD */
111static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr)
112{
113 unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
114
115 if (new_cpr & 0x0007) {
116 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
117 if (!(cpr & 0x0002) && !(cpr & 0x0004))
118 mdelay(5);
119 if (device == SPITZ_PWR_CF)
120 cpr |= 0x0002;
121 if (device == SPITZ_PWR_SD)
122 cpr |= 0x0004;
123 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
124 } else {
125 if (device == SPITZ_PWR_CF)
126 cpr &= ~0x0002;
127 if (device == SPITZ_PWR_SD)
128 cpr &= ~0x0004;
129 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
130 if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
131 mdelay(1);
132 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
133 }
134 }
135}
136
137static void spitz_pcmcia_init(void)
138{
139 /* Setup default state of GPIO outputs
140 before we enable them as outputs. */
141 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
142 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
143 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2);
144 GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1);
145
146 pxa_gpio_mode(GPIO48_nPOE_MD);
147 pxa_gpio_mode(GPIO49_nPWE_MD);
148 pxa_gpio_mode(GPIO50_nPIOR_MD);
149 pxa_gpio_mode(GPIO51_nPIOW_MD);
150 pxa_gpio_mode(GPIO55_nPREG_MD);
151 pxa_gpio_mode(GPIO56_nPWAIT_MD);
152 pxa_gpio_mode(GPIO57_nIOIS16_MD);
153 pxa_gpio_mode(GPIO85_nPCE_1_MD);
154 pxa_gpio_mode(GPIO54_nPCE_2_MD);
155 pxa_gpio_mode(GPIO104_pSKTSEL_MD);
156}
157
158static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr)
159{
160 /* Only need to override behaviour for slot 0 */
161 if (nr == 0)
162 spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr);
163 else
164 write_scoop_reg(scoop, SCOOP_CPR, cpr);
165}
166
107static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { 167static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
108{ 168{
109 .dev = &spitzscoop_device.dev, 169 .dev = &spitzscoop_device.dev,
@@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
117}, 177},
118}; 178};
119 179
180static struct scoop_pcmcia_config spitz_pcmcia_config = {
181 .devs = &spitz_pcmcia_scoop[0],
182 .num_devs = 2,
183 .pcmcia_init = spitz_pcmcia_init,
184 .power_ctrl = spitz_pcmcia_pwr,
185};
186
187EXPORT_SYMBOL(spitzscoop_device);
188EXPORT_SYMBOL(spitzscoop2_device);
189
120 190
121/* 191/*
122 * Spitz SSP Device 192 * Spitz SSP Device
@@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
235 return 0; 305 return 0;
236} 306}
237 307
238/* Power control is shared with one of the CF slots so we have a mess */
239static void spitz_mci_setpower(struct device *dev, unsigned int vdd) 308static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
240{ 309{
241 struct pxamci_platform_data* p_d = dev->platform_data; 310 struct pxamci_platform_data* p_d = dev->platform_data;
242 311
243 unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); 312 if (( 1 << vdd) & p_d->ocr_mask)
244 313 spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004);
245 if (( 1 << vdd) & p_d->ocr_mask) { 314 else
246 /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ 315 spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
247 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
248 mdelay(2);
249 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
250 } else {
251 /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
252 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
253
254 if (!(cpr | 0x02)) {
255 mdelay(1);
256 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
257 }
258 }
259} 316}
260 317
261static int spitz_mci_get_ro(struct device *dev) 318static int spitz_mci_get_ro(struct device *dev)
@@ -351,8 +408,8 @@ static void __init common_init(void)
351 408
352static void __init spitz_init(void) 409static void __init spitz_init(void)
353{ 410{
354 scoop_num = 2; 411 platform_scoop_config = &spitz_pcmcia_config;
355 scoop_devs = &spitz_pcmcia_scoop[0]; 412
356 spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; 413 spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
357 414
358 common_init(); 415 common_init();
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index fe5ea36e7de3..56c58831e80e 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -22,16 +22,20 @@
22#include <asm/hardware.h> 22#include <asm/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/hardware/scoop.h> 24#include <asm/hardware/scoop.h>
25#ifdef CONFIG_SA1100_COLLIE
26#include <asm/arch-sa1100/collie.h>
27#else
28#include <asm/arch-pxa/pxa-regs.h>
29#endif
30 25
31#include "soc_common.h" 26#include "soc_common.h"
32 27
33#define NO_KEEP_VS 0x0001 28#define NO_KEEP_VS 0x0001
34 29
30/* PCMCIA to Scoop linkage
31
32 There is no easy way to link multiple scoop devices into one
33 single entity for the pxa2xx_pcmcia device so this structure
34 is used which is setup by the platform code
35*/
36struct scoop_pcmcia_config *platform_scoop_config;
37#define SCOOP_DEV platform_scoop_config->devs
38
35static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) 39static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
36{ 40{
37 reset_scoop(scoopdev->dev); 41 reset_scoop(scoopdev->dev);
@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
43{ 47{
44 int ret; 48 int ret;
45 49
46#ifndef CONFIG_SA1100_COLLIE 50 if (platform_scoop_config->pcmcia_init)
47 /* 51 platform_scoop_config->pcmcia_init();
48 * Setup default state of GPIO outputs
49 * before we enable them as outputs.
50 */
51 GPSR(GPIO48_nPOE) =
52 GPIO_bit(GPIO48_nPOE) |
53 GPIO_bit(GPIO49_nPWE) |
54 GPIO_bit(GPIO50_nPIOR) |
55 GPIO_bit(GPIO51_nPIOW) |
56 GPIO_bit(GPIO52_nPCE_1) |
57 GPIO_bit(GPIO53_nPCE_2);
58
59 pxa_gpio_mode(GPIO48_nPOE_MD);
60 pxa_gpio_mode(GPIO49_nPWE_MD);
61 pxa_gpio_mode(GPIO50_nPIOR_MD);
62 pxa_gpio_mode(GPIO51_nPIOW_MD);
63 pxa_gpio_mode(GPIO52_nPCE_1_MD);
64 pxa_gpio_mode(GPIO53_nPCE_2_MD);
65 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
66 pxa_gpio_mode(GPIO55_nPREG_MD);
67 pxa_gpio_mode(GPIO56_nPWAIT_MD);
68 pxa_gpio_mode(GPIO57_nIOIS16_MD);
69#endif
70 52
71 /* Register interrupts */ 53 /* Register interrupts */
72 if (scoop_devs[skt->nr].cd_irq >= 0) { 54 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
73 struct pcmcia_irqs cd_irq; 55 struct pcmcia_irqs cd_irq;
74 56
75 cd_irq.sock = skt->nr; 57 cd_irq.sock = skt->nr;
76 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 58 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
77 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 59 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
78 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); 60 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
79 61
80 if (ret) { 62 if (ret) {
@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
83 } 65 }
84 } 66 }
85 67
86 skt->irq = scoop_devs[skt->nr].irq; 68 skt->irq = SCOOP_DEV[skt->nr].irq;
87 69
88 return 0; 70 return 0;
89} 71}
90 72
91static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 73static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
92{ 74{
93 if (scoop_devs[skt->nr].cd_irq >= 0) { 75 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
94 struct pcmcia_irqs cd_irq; 76 struct pcmcia_irqs cd_irq;
95 77
96 cd_irq.sock = skt->nr; 78 cd_irq.sock = skt->nr;
97 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 79 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
98 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 80 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
99 soc_pcmcia_free_irqs(skt, &cd_irq, 1); 81 soc_pcmcia_free_irqs(skt, &cd_irq, 1);
100 } 82 }
101} 83}
@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
105 struct pcmcia_state *state) 87 struct pcmcia_state *state)
106{ 88{
107 unsigned short cpr, csr; 89 unsigned short cpr, csr;
108 struct device *scoop = scoop_devs[skt->nr].dev; 90 struct device *scoop = SCOOP_DEV[skt->nr].dev;
109 91
110 cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); 92 cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
111 93
112 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); 94 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
113 write_scoop_reg(scoop, SCOOP_ISR, 0x0000); 95 write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
116 if (csr & 0x0004) { 98 if (csr & 0x0004) {
117 /* card eject */ 99 /* card eject */
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 100 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
119 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 101 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
120 } 102 }
121 else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { 103 else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
122 /* keep vs1,vs2 */ 104 /* keep vs1,vs2 */
123 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 105 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
124 csr |= scoop_devs[skt->nr].keep_vs; 106 csr |= SCOOP_DEV[skt->nr].keep_vs;
125 } 107 }
126 else if (cpr & 0x0003) { 108 else if (cpr & 0x0003) {
127 /* power on */ 109 /* power on */
128 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 110 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
129 scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); 111 SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
130 } 112 }
131 else { 113 else {
132 /* card detect */ 114 /* card detect */
133 write_scoop_reg(scoop, SCOOP_CDR, 0x0002); 115 if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
116 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
117 } else {
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
119 }
134 } 120 }
135 121
136 state->detect = (csr & 0x0004) ? 0 : 1; 122 state->detect = (csr & 0x0004) ? 0 : 1;
@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
144 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { 130 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
145 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); 131 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
146 } 132 }
147
148} 133}
149 134
150 135
@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
152 const socket_state_t *state) 137 const socket_state_t *state)
153{ 138{
154 unsigned long flags; 139 unsigned long flags;
155 struct device *scoop = scoop_devs[skt->nr].dev; 140 struct device *scoop = SCOOP_DEV[skt->nr].dev;
156 141
157 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; 142 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
158 143
@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
177 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; 162 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
178 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; 163 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
179 164
180 ncpr |= (state->Vcc == 33) ? 0x0001 : 165 if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
181 (state->Vcc == 50) ? 0x0002 : 0; 166 ncpr |= (state->Vcc == 33) ? 0x0002 :
167 (state->Vcc == 50) ? 0x0002 : 0;
168 } else {
169 ncpr |= (state->Vcc == 33) ? 0x0001 :
170 (state->Vcc == 50) ? 0x0002 : 0;
171 }
182 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; 172 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
183 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; 173 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
184 nccr |= (state->flags&SS_RESET)? 0x0080: 0; 174 nccr |= (state->flags&SS_RESET)? 0x0080: 0;
@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
190 ((skt->status&SS_WRPROT) ? 0x0008 : 0); 180 ((skt->status&SS_WRPROT) ? 0x0008 : 0);
191 181
192 if (!(ncpr & 0x0003)) { 182 if (!(ncpr & 0x0003)) {
193 scoop_devs[skt->nr].keep_rd = 0; 183 SCOOP_DEV[skt->nr].keep_rd = 0;
194 } else if (!scoop_devs[skt->nr].keep_rd) { 184 } else if (!SCOOP_DEV[skt->nr].keep_rd) {
195 if (nccr & 0x0080) 185 if (nccr & 0x0080)
196 scoop_devs[skt->nr].keep_rd = 1; 186 SCOOP_DEV[skt->nr].keep_rd = 1;
197 else 187 else
198 nccr |= 0x0080; 188 nccr |= 0x0080;
199 } 189 }
200 190
201 if (mcr != nmcr) 191 if (mcr != nmcr)
202 write_scoop_reg(scoop, SCOOP_MCR, nmcr); 192 write_scoop_reg(scoop, SCOOP_MCR, nmcr);
203 if (cpr != ncpr) 193 if (cpr != ncpr) {
204 write_scoop_reg(scoop, SCOOP_CPR, ncpr); 194 if (platform_scoop_config->power_ctrl)
195 platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
196 else
197 write_scoop_reg(scoop, SCOOP_CPR, ncpr);
198 }
205 if (ccr != nccr) 199 if (ccr != nccr)
206 write_scoop_reg(scoop, SCOOP_CCR, nccr); 200 write_scoop_reg(scoop, SCOOP_CCR, nccr);
207 if (imr != nimr) 201 if (imr != nimr)
@@ -214,43 +208,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
214 208
215static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) 209static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
216{ 210{
217 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 211 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
218 212
219 /* Enable interrupt */ 213 /* Enable interrupt */
220 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); 214 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
221 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); 215 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
222 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 216 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
223 217
224 if (machine_is_collie()) 218 if (machine_is_collie())
225 /* We need to disable SS_OUTPUT_ENA here. */ 219 /* We need to disable SS_OUTPUT_ENA here. */
226 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 220 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
227} 221}
228 222
229static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 223static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
230{ 224{
231 /* CF_BUS_OFF */ 225 /* CF_BUS_OFF */
232 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 226 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
233 227
234 if (machine_is_collie()) 228 if (machine_is_collie())
235 /* We need to disable SS_OUTPUT_ENA here. */ 229 /* We need to disable SS_OUTPUT_ENA here. */
236 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 230 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
237} 231}
238 232
239static struct pcmcia_low_level sharpsl_pcmcia_ops = { 233static struct pcmcia_low_level sharpsl_pcmcia_ops = {
240 .owner = THIS_MODULE, 234 .owner = THIS_MODULE,
241 .hw_init = sharpsl_pcmcia_hw_init, 235 .hw_init = sharpsl_pcmcia_hw_init,
242 .hw_shutdown = sharpsl_pcmcia_hw_shutdown, 236 .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
243 .socket_state = sharpsl_pcmcia_socket_state, 237 .socket_state = sharpsl_pcmcia_socket_state,
244 .configure_socket = sharpsl_pcmcia_configure_socket, 238 .configure_socket = sharpsl_pcmcia_configure_socket,
245 .socket_init = sharpsl_pcmcia_socket_init, 239 .socket_init = sharpsl_pcmcia_socket_init,
246 .socket_suspend = sharpsl_pcmcia_socket_suspend, 240 .socket_suspend = sharpsl_pcmcia_socket_suspend,
247 .first = 0, 241 .first = 0,
248 .nr = 0, 242 .nr = 0,
249}; 243};
250 244
251static struct platform_device *sharpsl_pcmcia_device;
252
253#ifdef CONFIG_SA1100_COLLIE 245#ifdef CONFIG_SA1100_COLLIE
246#include "sa11xx_base.h"
247
254int __init pcmcia_collie_init(struct device *dev) 248int __init pcmcia_collie_init(struct device *dev)
255{ 249{
256 int ret = -ENODEV; 250 int ret = -ENODEV;
@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev)
263 257
264#else 258#else
265 259
260static struct platform_device *sharpsl_pcmcia_device;
261
266static int __init sharpsl_pcmcia_init(void) 262static int __init sharpsl_pcmcia_init(void)
267{ 263{
268 int ret; 264 int ret;
269 265
270 sharpsl_pcmcia_ops.nr=scoop_num; 266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
271 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); 267 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
272 if (!sharpsl_pcmcia_device) 268 if (!sharpsl_pcmcia_device)
273 return -ENOMEM; 269 return -ENOMEM;
@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
275 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); 271 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
276 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; 272 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
277 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 273 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
278 sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; 274 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
279 275
280 ret = platform_device_register(sharpsl_pcmcia_device); 276 ret = platform_device_register(sharpsl_pcmcia_device);
281 if (ret) 277 if (ret)
diff --git a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h
index a8f1013930e3..d37bf7443264 100644
--- a/include/asm-arm/hardware/scoop.h
+++ b/include/asm-arm/hardware/scoop.h
@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev {
52 unsigned char keep_rd; 52 unsigned char keep_rd;
53}; 53};
54 54
55extern int scoop_num; 55struct scoop_pcmcia_config {
56extern struct scoop_pcmcia_dev *scoop_devs; 56 struct scoop_pcmcia_dev *devs;
57 int num_devs;
58 void (*pcmcia_init)(void);
59 void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
60};
61
62extern struct scoop_pcmcia_config *platform_scoop_config;
57 63
58void reset_scoop(struct device *dev); 64void reset_scoop(struct device *dev);
59unsigned short set_scoop_gpio(struct device *dev, unsigned short bit); 65unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);