diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-09 12:26:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-09 12:26:36 -0400 |
commit | 7886e8aa7ff59198271ac650878eb247627a8b9a (patch) | |
tree | ac6f337a50d43db95e489517296247f10a6d10b9 /drivers | |
parent | 4a1e00524cbdd38567e36f9c54a0444deebd864a (diff) | |
parent | 64b2f129c38713a059e1299662fc68fc6bf6f0a6 (diff) |
Merge branch 'for-linus-sa1100' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM SA1100 updates from Russell King:
"We have support for arbitary MMIO registers providing platform GPIOs,
which allows us to abstract some of the SA11x0 CF support.
This set of updates makes that change"
* 'for-linus-sa1100' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: sa1100/simpad: switch simpad CF to use gpiod APIs
ARM: sa1100/shannon: convert to generic CF sockets
ARM: sa1100/nanoengine: convert to generic CF sockets
ARM: sa1100/h3xxx: switch h3xxx PCMCIA to use gpiod APIs
ARM: sa1100/cerf: convert to generic CF sockets
ARM: sa1100/assabet: convert to generic CF sockets
ARM: sa1100: provide infrastructure to support generic CF sockets
pcmcia: sa1100: provide generic CF support
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/Makefile | 4 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_assabet.c | 100 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_cerf.c | 86 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_generic.c | 115 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_generic.h | 4 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_h3600.c | 16 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_nanoengine.c | 133 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_shannon.c | 104 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_simpad.c | 12 |
9 files changed, 108 insertions, 466 deletions
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index f1f89ddb1bfd..28502bd159e0 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -43,13 +43,9 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1111_jornada720.o | |||
43 | sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o | 43 | sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o |
44 | 44 | ||
45 | sa1100_cs-y += sa1100_generic.o | 45 | sa1100_cs-y += sa1100_generic.o |
46 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o | ||
47 | sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o | ||
48 | sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o | 46 | sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o |
49 | sa1100_cs-$(CONFIG_SA1100_H3100) += sa1100_h3600.o | 47 | sa1100_cs-$(CONFIG_SA1100_H3100) += sa1100_h3600.o |
50 | sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o | 48 | sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o |
51 | sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o | ||
52 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o | ||
53 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o | 49 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o |
54 | 50 | ||
55 | pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o | 51 | pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o |
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c deleted file mode 100644 index 78ad2bba76db..000000000000 --- a/drivers/pcmcia/sa1100_assabet.c +++ /dev/null | |||
@@ -1,100 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * drivers/pcmcia/sa1100_assabet.c | ||
4 | * | ||
5 | * PCMCIA implementation routines for Assabet | ||
6 | * | ||
7 | */ | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/gpio.h> | ||
15 | |||
16 | #include <asm/mach-types.h> | ||
17 | #include <mach/assabet.h> | ||
18 | |||
19 | #include "sa1100_generic.h" | ||
20 | |||
21 | static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
22 | { | ||
23 | skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD; | ||
24 | skt->stat[SOC_STAT_CD].name = "CF CD"; | ||
25 | skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1; | ||
26 | skt->stat[SOC_STAT_BVD1].name = "CF BVD1"; | ||
27 | skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2; | ||
28 | skt->stat[SOC_STAT_BVD2].name = "CF BVD2"; | ||
29 | skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ; | ||
30 | skt->stat[SOC_STAT_RDY].name = "CF RDY"; | ||
31 | |||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | ||
37 | { | ||
38 | unsigned int mask; | ||
39 | |||
40 | switch (state->Vcc) { | ||
41 | case 0: | ||
42 | mask = 0; | ||
43 | break; | ||
44 | |||
45 | case 50: | ||
46 | printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n", | ||
47 | __func__); | ||
48 | |||
49 | case 33: /* Can only apply 3.3V to the CF slot. */ | ||
50 | mask = ASSABET_BCR_CF_PWR; | ||
51 | break; | ||
52 | |||
53 | default: | ||
54 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__, | ||
55 | state->Vcc); | ||
56 | return -1; | ||
57 | } | ||
58 | |||
59 | /* Silently ignore Vpp, speaker enable. */ | ||
60 | |||
61 | if (state->flags & SS_RESET) | ||
62 | mask |= ASSABET_BCR_CF_RST; | ||
63 | if (!(state->flags & SS_OUTPUT_ENA)) | ||
64 | mask |= ASSABET_BCR_CF_BUS_OFF; | ||
65 | |||
66 | ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR | | ||
67 | ASSABET_BCR_CF_BUS_OFF, mask); | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Disable card status IRQs on suspend. | ||
74 | */ | ||
75 | static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
76 | { | ||
77 | /* | ||
78 | * Tristate the CF bus signals. Also assert CF | ||
79 | * reset as per user guide page 4-11. | ||
80 | */ | ||
81 | ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); | ||
82 | } | ||
83 | |||
84 | static struct pcmcia_low_level assabet_pcmcia_ops = { | ||
85 | .owner = THIS_MODULE, | ||
86 | .hw_init = assabet_pcmcia_hw_init, | ||
87 | .socket_state = soc_common_cf_socket_state, | ||
88 | .configure_socket = assabet_pcmcia_configure_socket, | ||
89 | .socket_suspend = assabet_pcmcia_socket_suspend, | ||
90 | }; | ||
91 | |||
92 | int pcmcia_assabet_init(struct device *dev) | ||
93 | { | ||
94 | int ret = -ENODEV; | ||
95 | |||
96 | if (machine_is_assabet() && !machine_has_neponset()) | ||
97 | ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1); | ||
98 | |||
99 | return ret; | ||
100 | } | ||
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c deleted file mode 100644 index 2a54081d161d..000000000000 --- a/drivers/pcmcia/sa1100_cerf.c +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * drivers/pcmcia/sa1100_cerf.c | ||
4 | * | ||
5 | * PCMCIA implementation routines for CerfBoard | ||
6 | * Based off the Assabet. | ||
7 | * | ||
8 | */ | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/gpio.h> | ||
15 | |||
16 | #include <mach/hardware.h> | ||
17 | #include <asm/mach-types.h> | ||
18 | #include <asm/irq.h> | ||
19 | #include <mach/cerf.h> | ||
20 | #include "sa1100_generic.h" | ||
21 | |||
22 | #define CERF_SOCKET 1 | ||
23 | |||
24 | static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
25 | { | ||
26 | int ret; | ||
27 | |||
28 | ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET"); | ||
29 | if (ret) | ||
30 | return ret; | ||
31 | |||
32 | skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD; | ||
33 | skt->stat[SOC_STAT_CD].name = "CF_CD"; | ||
34 | skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1; | ||
35 | skt->stat[SOC_STAT_BVD1].name = "CF_BVD1"; | ||
36 | skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2; | ||
37 | skt->stat[SOC_STAT_BVD2].name = "CF_BVD2"; | ||
38 | skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ; | ||
39 | skt->stat[SOC_STAT_RDY].name = "CF_IRQ"; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
45 | { | ||
46 | gpio_free(CERF_GPIO_CF_RESET); | ||
47 | } | ||
48 | |||
49 | static int | ||
50 | cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | ||
51 | const socket_state_t *state) | ||
52 | { | ||
53 | switch (state->Vcc) { | ||
54 | case 0: | ||
55 | case 50: | ||
56 | case 33: | ||
57 | break; | ||
58 | |||
59 | default: | ||
60 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | ||
61 | __func__, state->Vcc); | ||
62 | return -1; | ||
63 | } | ||
64 | |||
65 | gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET)); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static struct pcmcia_low_level cerf_pcmcia_ops = { | ||
71 | .owner = THIS_MODULE, | ||
72 | .hw_init = cerf_pcmcia_hw_init, | ||
73 | .hw_shutdown = cerf_pcmcia_hw_shutdown, | ||
74 | .socket_state = soc_common_cf_socket_state, | ||
75 | .configure_socket = cerf_pcmcia_configure_socket, | ||
76 | }; | ||
77 | |||
78 | int pcmcia_cerf_init(struct device *dev) | ||
79 | { | ||
80 | int ret = -ENODEV; | ||
81 | |||
82 | if (machine_is_cerf()) | ||
83 | ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1); | ||
84 | |||
85 | return ret; | ||
86 | } | ||
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 66acdc85727c..47b060c57418 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c | |||
@@ -31,7 +31,9 @@ | |||
31 | ======================================================================*/ | 31 | ======================================================================*/ |
32 | 32 | ||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/gpio/consumer.h> | ||
34 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/regulator/consumer.h> | ||
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
36 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
37 | 39 | ||
@@ -41,24 +43,64 @@ | |||
41 | 43 | ||
42 | #include "sa1100_generic.h" | 44 | #include "sa1100_generic.h" |
43 | 45 | ||
46 | static const char *sa11x0_cf_gpio_names[] = { | ||
47 | [SOC_STAT_CD] = "detect", | ||
48 | [SOC_STAT_BVD1] = "bvd1", | ||
49 | [SOC_STAT_BVD2] = "bvd2", | ||
50 | [SOC_STAT_RDY] = "ready", | ||
51 | }; | ||
52 | |||
53 | static int sa11x0_cf_hw_init(struct soc_pcmcia_socket *skt) | ||
54 | { | ||
55 | struct device *dev = skt->socket.dev.parent; | ||
56 | int i; | ||
57 | |||
58 | skt->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); | ||
59 | if (IS_ERR(skt->gpio_reset)) | ||
60 | return PTR_ERR(skt->gpio_reset); | ||
61 | |||
62 | skt->gpio_bus_enable = devm_gpiod_get_optional(dev, "bus-enable", | ||
63 | GPIOD_OUT_HIGH); | ||
64 | if (IS_ERR(skt->gpio_bus_enable)) | ||
65 | return PTR_ERR(skt->gpio_bus_enable); | ||
66 | |||
67 | skt->vcc.reg = devm_regulator_get_optional(dev, "vcc"); | ||
68 | if (IS_ERR(skt->vcc.reg)) | ||
69 | return PTR_ERR(skt->vcc.reg); | ||
70 | |||
71 | if (!skt->vcc.reg) | ||
72 | dev_warn(dev, | ||
73 | "no Vcc regulator provided, ignoring Vcc controls\n"); | ||
74 | |||
75 | for (i = 0; i < ARRAY_SIZE(sa11x0_cf_gpio_names); i++) { | ||
76 | skt->stat[i].name = sa11x0_cf_gpio_names[i]; | ||
77 | skt->stat[i].desc = devm_gpiod_get_optional(dev, | ||
78 | sa11x0_cf_gpio_names[i], GPIOD_IN); | ||
79 | if (IS_ERR(skt->stat[i].desc)) | ||
80 | return PTR_ERR(skt->stat[i].desc); | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int sa11x0_cf_configure_socket(struct soc_pcmcia_socket *skt, | ||
86 | const socket_state_t *state) | ||
87 | { | ||
88 | return soc_pcmcia_regulator_set(skt, &skt->vcc, state->Vcc); | ||
89 | } | ||
90 | |||
91 | static struct pcmcia_low_level sa11x0_cf_ops = { | ||
92 | .owner = THIS_MODULE, | ||
93 | .hw_init = sa11x0_cf_hw_init, | ||
94 | .socket_state = soc_common_cf_socket_state, | ||
95 | .configure_socket = sa11x0_cf_configure_socket, | ||
96 | }; | ||
97 | |||
44 | int __init pcmcia_collie_init(struct device *dev); | 98 | int __init pcmcia_collie_init(struct device *dev); |
45 | 99 | ||
46 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | 100 | static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = { |
47 | #ifdef CONFIG_SA1100_ASSABET | ||
48 | pcmcia_assabet_init, | ||
49 | #endif | ||
50 | #ifdef CONFIG_SA1100_CERF | ||
51 | pcmcia_cerf_init, | ||
52 | #endif | ||
53 | #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) | 101 | #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) |
54 | pcmcia_h3600_init, | 102 | pcmcia_h3600_init, |
55 | #endif | 103 | #endif |
56 | #ifdef CONFIG_SA1100_NANOENGINE | ||
57 | pcmcia_nanoengine_init, | ||
58 | #endif | ||
59 | #ifdef CONFIG_SA1100_SHANNON | ||
60 | pcmcia_shannon_init, | ||
61 | #endif | ||
62 | #ifdef CONFIG_SA1100_SIMPAD | 104 | #ifdef CONFIG_SA1100_SIMPAD |
63 | pcmcia_simpad_init, | 105 | pcmcia_simpad_init, |
64 | #endif | 106 | #endif |
@@ -67,15 +109,15 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | |||
67 | #endif | 109 | #endif |
68 | }; | 110 | }; |
69 | 111 | ||
70 | static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) | 112 | static int sa11x0_drv_pcmcia_legacy_probe(struct platform_device *dev) |
71 | { | 113 | { |
72 | int i, ret = -ENODEV; | 114 | int i, ret = -ENODEV; |
73 | 115 | ||
74 | /* | 116 | /* |
75 | * Initialise any "on-board" PCMCIA sockets. | 117 | * Initialise any "on-board" PCMCIA sockets. |
76 | */ | 118 | */ |
77 | for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) { | 119 | for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_legacy_hw_init); i++) { |
78 | ret = sa11x0_pcmcia_hw_init[i](&dev->dev); | 120 | ret = sa11x0_pcmcia_legacy_hw_init[i](&dev->dev); |
79 | if (ret == 0) | 121 | if (ret == 0) |
80 | break; | 122 | break; |
81 | } | 123 | } |
@@ -83,7 +125,7 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) | |||
83 | return ret; | 125 | return ret; |
84 | } | 126 | } |
85 | 127 | ||
86 | static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) | 128 | static int sa11x0_drv_pcmcia_legacy_remove(struct platform_device *dev) |
87 | { | 129 | { |
88 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); | 130 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); |
89 | int i; | 131 | int i; |
@@ -96,6 +138,45 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) | |||
96 | return 0; | 138 | return 0; |
97 | } | 139 | } |
98 | 140 | ||
141 | static int sa11x0_drv_pcmcia_probe(struct platform_device *pdev) | ||
142 | { | ||
143 | struct soc_pcmcia_socket *skt; | ||
144 | struct device *dev = &pdev->dev; | ||
145 | |||
146 | if (pdev->id == -1) | ||
147 | return sa11x0_drv_pcmcia_legacy_probe(pdev); | ||
148 | |||
149 | skt = devm_kzalloc(dev, sizeof(*skt), GFP_KERNEL); | ||
150 | if (!skt) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | platform_set_drvdata(pdev, skt); | ||
154 | |||
155 | skt->nr = pdev->id; | ||
156 | skt->clk = devm_clk_get(dev, NULL); | ||
157 | if (IS_ERR(skt->clk)) | ||
158 | return PTR_ERR(skt->clk); | ||
159 | |||
160 | sa11xx_drv_pcmcia_ops(&sa11x0_cf_ops); | ||
161 | soc_pcmcia_init_one(skt, &sa11x0_cf_ops, dev); | ||
162 | |||
163 | return sa11xx_drv_pcmcia_add_one(skt); | ||
164 | } | ||
165 | |||
166 | static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) | ||
167 | { | ||
168 | struct soc_pcmcia_socket *skt; | ||
169 | |||
170 | if (dev->id == -1) | ||
171 | return sa11x0_drv_pcmcia_legacy_remove(dev); | ||
172 | |||
173 | skt = platform_get_drvdata(dev); | ||
174 | |||
175 | soc_pcmcia_remove_one(skt); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
99 | static struct platform_driver sa11x0_pcmcia_driver = { | 180 | static struct platform_driver sa11x0_pcmcia_driver = { |
100 | .driver = { | 181 | .driver = { |
101 | .name = "sa11x0-pcmcia", | 182 | .name = "sa11x0-pcmcia", |
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h index a5f1f1dd63cb..7b7cdcd20187 100644 --- a/drivers/pcmcia/sa1100_generic.h +++ b/drivers/pcmcia/sa1100_generic.h | |||
@@ -6,18 +6,14 @@ | |||
6 | * Declaration for all machine specific init/exit functions. | 6 | * Declaration for all machine specific init/exit functions. |
7 | */ | 7 | */ |
8 | extern int pcmcia_adsbitsy_init(struct device *); | 8 | extern int pcmcia_adsbitsy_init(struct device *); |
9 | extern int pcmcia_assabet_init(struct device *); | ||
10 | extern int pcmcia_badge4_init(struct device *); | 9 | extern int pcmcia_badge4_init(struct device *); |
11 | extern int pcmcia_cerf_init(struct device *); | ||
12 | extern int pcmcia_flexanet_init(struct device *); | 10 | extern int pcmcia_flexanet_init(struct device *); |
13 | extern int pcmcia_freebird_init(struct device *); | 11 | extern int pcmcia_freebird_init(struct device *); |
14 | extern int pcmcia_gcplus_init(struct device *); | 12 | extern int pcmcia_gcplus_init(struct device *); |
15 | extern int pcmcia_graphicsmaster_init(struct device *); | 13 | extern int pcmcia_graphicsmaster_init(struct device *); |
16 | extern int pcmcia_h3600_init(struct device *); | 14 | extern int pcmcia_h3600_init(struct device *); |
17 | extern int pcmcia_nanoengine_init(struct device *); | ||
18 | extern int pcmcia_pangolin_init(struct device *); | 15 | extern int pcmcia_pangolin_init(struct device *); |
19 | extern int pcmcia_pfs168_init(struct device *); | 16 | extern int pcmcia_pfs168_init(struct device *); |
20 | extern int pcmcia_shannon_init(struct device *); | ||
21 | extern int pcmcia_simpad_init(struct device *); | 17 | extern int pcmcia_simpad_init(struct device *); |
22 | extern int pcmcia_stork_init(struct device *); | 18 | extern int pcmcia_stork_init(struct device *); |
23 | extern int pcmcia_system3_init(struct device *); | 19 | extern int pcmcia_system3_init(struct device *); |
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index aebf9a66fdde..a91222bc3824 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c | |||
@@ -24,13 +24,15 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
24 | { | 24 | { |
25 | int err; | 25 | int err; |
26 | 26 | ||
27 | skt->stat[SOC_STAT_CD].name = skt->nr ? "pcmcia1-detect" : "pcmcia0-detect"; | ||
28 | skt->stat[SOC_STAT_RDY].name = skt->nr ? "pcmcia1-ready" : "pcmcia0-ready"; | ||
29 | |||
30 | err = soc_pcmcia_request_gpiods(skt); | ||
31 | if (err) | ||
32 | return err; | ||
33 | |||
27 | switch (skt->nr) { | 34 | switch (skt->nr) { |
28 | case 0: | 35 | case 0: |
29 | skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0; | ||
30 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD0"; | ||
31 | skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0; | ||
32 | skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0"; | ||
33 | |||
34 | err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); | 36 | err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); |
35 | if (err) | 37 | if (err) |
36 | goto err01; | 38 | goto err01; |
@@ -57,10 +59,6 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
57 | goto err06; | 59 | goto err06; |
58 | break; | 60 | break; |
59 | case 1: | 61 | case 1: |
60 | skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1; | ||
61 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD1"; | ||
62 | skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1; | ||
63 | skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1"; | ||
64 | break; | 62 | break; |
65 | } | 63 | } |
66 | return 0; | 64 | return 0; |
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c deleted file mode 100644 index 35c30ff41e81..000000000000 --- a/drivers/pcmcia/sa1100_nanoengine.c +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/pcmcia/sa1100_nanoengine.c | ||
3 | * | ||
4 | * PCMCIA implementation routines for BSI nanoEngine. | ||
5 | * | ||
6 | * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine | ||
7 | * board you should carefully read this: | ||
8 | * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/ | ||
9 | * | ||
10 | * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> | ||
11 | * | ||
12 | * Based on original work for kernel 2.4 by | ||
13 | * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License version 2 as | ||
17 | * published by the Free Software Foundation. | ||
18 | * | ||
19 | */ | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/signal.h> | ||
29 | |||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/irq.h> | ||
32 | |||
33 | #include <mach/hardware.h> | ||
34 | #include <mach/nanoengine.h> | ||
35 | |||
36 | #include "sa1100_generic.h" | ||
37 | |||
38 | struct nanoengine_pins { | ||
39 | unsigned output_pins; | ||
40 | unsigned clear_outputs; | ||
41 | int gpio_rst; | ||
42 | int gpio_cd; | ||
43 | int gpio_rdy; | ||
44 | }; | ||
45 | |||
46 | static struct nanoengine_pins nano_skts[] = { | ||
47 | { | ||
48 | .gpio_rst = GPIO_PC_RESET0, | ||
49 | .gpio_cd = GPIO_PC_CD0, | ||
50 | .gpio_rdy = GPIO_PC_READY0, | ||
51 | }, { | ||
52 | .gpio_rst = GPIO_PC_RESET1, | ||
53 | .gpio_cd = GPIO_PC_CD1, | ||
54 | .gpio_rdy = GPIO_PC_READY1, | ||
55 | } | ||
56 | }; | ||
57 | |||
58 | unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); | ||
59 | |||
60 | static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
61 | { | ||
62 | unsigned i = skt->nr; | ||
63 | int ret; | ||
64 | |||
65 | if (i >= num_nano_pcmcia_sockets) | ||
66 | return -ENXIO; | ||
67 | |||
68 | ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW, | ||
69 | i ? "PC RST1" : "PC RST0"); | ||
70 | if (ret) | ||
71 | return ret; | ||
72 | |||
73 | skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd; | ||
74 | skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0"; | ||
75 | skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy; | ||
76 | skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0"; | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
82 | { | ||
83 | gpio_free(nano_skts[skt->nr].gpio_rst); | ||
84 | } | ||
85 | |||
86 | static int nanoengine_pcmcia_configure_socket( | ||
87 | struct soc_pcmcia_socket *skt, const socket_state_t *state) | ||
88 | { | ||
89 | unsigned i = skt->nr; | ||
90 | |||
91 | if (i >= num_nano_pcmcia_sockets) | ||
92 | return -ENXIO; | ||
93 | |||
94 | gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET)); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static void nanoengine_pcmcia_socket_state( | ||
100 | struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | ||
101 | { | ||
102 | unsigned i = skt->nr; | ||
103 | |||
104 | if (i >= num_nano_pcmcia_sockets) | ||
105 | return; | ||
106 | |||
107 | state->bvd1 = 1; | ||
108 | state->bvd2 = 1; | ||
109 | state->vs_3v = 1; /* Can only apply 3.3V */ | ||
110 | state->vs_Xv = 0; | ||
111 | } | ||
112 | |||
113 | static struct pcmcia_low_level nanoengine_pcmcia_ops = { | ||
114 | .owner = THIS_MODULE, | ||
115 | |||
116 | .hw_init = nanoengine_pcmcia_hw_init, | ||
117 | .hw_shutdown = nanoengine_pcmcia_hw_shutdown, | ||
118 | |||
119 | .configure_socket = nanoengine_pcmcia_configure_socket, | ||
120 | .socket_state = nanoengine_pcmcia_socket_state, | ||
121 | }; | ||
122 | |||
123 | int pcmcia_nanoengine_init(struct device *dev) | ||
124 | { | ||
125 | int ret = -ENODEV; | ||
126 | |||
127 | if (machine_is_nanoengine()) | ||
128 | ret = sa11xx_drv_pcmcia_probe( | ||
129 | dev, &nanoengine_pcmcia_ops, 0, 2); | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c deleted file mode 100644 index 0e52a575986e..000000000000 --- a/drivers/pcmcia/sa1100_shannon.c +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * drivers/pcmcia/sa1100_shannon.c | ||
4 | * | ||
5 | * PCMCIA implementation routines for Shannon | ||
6 | * | ||
7 | */ | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/io.h> | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | #include <asm/mach-types.h> | ||
16 | #include <mach/shannon.h> | ||
17 | #include <asm/irq.h> | ||
18 | #include "sa1100_generic.h" | ||
19 | |||
20 | static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
21 | { | ||
22 | /* All those are inputs */ | ||
23 | GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) | | ||
24 | GPIO_GPIO(SHANNON_GPIO_EJECT_1) | | ||
25 | GPIO_GPIO(SHANNON_GPIO_RDY_0) | | ||
26 | GPIO_GPIO(SHANNON_GPIO_RDY_1)); | ||
27 | |||
28 | if (skt->nr == 0) { | ||
29 | skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0; | ||
30 | skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0"; | ||
31 | skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0; | ||
32 | skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0"; | ||
33 | } else { | ||
34 | skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1; | ||
35 | skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1"; | ||
36 | skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1; | ||
37 | skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1"; | ||
38 | } | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static void | ||
44 | shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | ||
45 | struct pcmcia_state *state) | ||
46 | { | ||
47 | switch (skt->nr) { | ||
48 | case 0: | ||
49 | state->bvd1 = 1; | ||
50 | state->bvd2 = 1; | ||
51 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ | ||
52 | state->vs_Xv = 0; | ||
53 | break; | ||
54 | |||
55 | case 1: | ||
56 | state->bvd1 = 1; | ||
57 | state->bvd2 = 1; | ||
58 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ | ||
59 | state->vs_Xv = 0; | ||
60 | break; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | static int | ||
65 | shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | ||
66 | const socket_state_t *state) | ||
67 | { | ||
68 | switch (state->Vcc) { | ||
69 | case 0: /* power off */ | ||
70 | printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __func__); | ||
71 | break; | ||
72 | case 50: | ||
73 | printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __func__); | ||
74 | case 33: | ||
75 | break; | ||
76 | default: | ||
77 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | ||
78 | __func__, state->Vcc); | ||
79 | return -1; | ||
80 | } | ||
81 | |||
82 | printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __func__); | ||
83 | |||
84 | /* Silently ignore Vpp, output enable, speaker enable. */ | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static struct pcmcia_low_level shannon_pcmcia_ops = { | ||
90 | .owner = THIS_MODULE, | ||
91 | .hw_init = shannon_pcmcia_hw_init, | ||
92 | .socket_state = shannon_pcmcia_socket_state, | ||
93 | .configure_socket = shannon_pcmcia_configure_socket, | ||
94 | }; | ||
95 | |||
96 | int pcmcia_shannon_init(struct device *dev) | ||
97 | { | ||
98 | int ret = -ENODEV; | ||
99 | |||
100 | if (machine_is_shannon()) | ||
101 | ret = sa11xx_drv_pcmcia_probe(dev, &shannon_pcmcia_ops, 0, 2); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c index 7ce65bb23a8e..e235ee14eaa6 100644 --- a/drivers/pcmcia/sa1100_simpad.c +++ b/drivers/pcmcia/sa1100_simpad.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <mach/hardware.h> | 13 | #include <mach/hardware.h> |
14 | #include <asm/mach-types.h> | 14 | #include <asm/mach-types.h> |
15 | #include <asm/irq.h> | ||
16 | #include <mach/simpad.h> | 15 | #include <mach/simpad.h> |
17 | #include "sa1100_generic.h" | 16 | #include "sa1100_generic.h" |
18 | 17 | ||
@@ -21,12 +20,10 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
21 | 20 | ||
22 | simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 21 | simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
23 | 22 | ||
24 | skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD; | 23 | skt->stat[SOC_STAT_CD].name = "cf-detect"; |
25 | skt->stat[SOC_STAT_CD].name = "CF_CD"; | 24 | skt->stat[SOC_STAT_RDY].name = "cf-ready"; |
26 | skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ; | ||
27 | skt->stat[SOC_STAT_RDY].name = "CF_RDY"; | ||
28 | 25 | ||
29 | return 0; | 26 | return soc_pcmcia_request_gpiods(skt); |
30 | } | 27 | } |
31 | 28 | ||
32 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 29 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
@@ -42,9 +39,6 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
42 | { | 39 | { |
43 | long cs3reg = simpad_get_cs3_ro(); | 40 | long cs3reg = simpad_get_cs3_ro(); |
44 | 41 | ||
45 | /* the detect signal is inverted - fix that up here */ | ||
46 | state->detect = !state->detect; | ||
47 | |||
48 | state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ | 42 | state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ |
49 | state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ | 43 | state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ |
50 | 44 | ||