aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-09 12:26:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-09 12:26:36 -0400
commit7886e8aa7ff59198271ac650878eb247627a8b9a (patch)
treeac6f337a50d43db95e489517296247f10a6d10b9 /drivers
parent4a1e00524cbdd38567e36f9c54a0444deebd864a (diff)
parent64b2f129c38713a059e1299662fc68fc6bf6f0a6 (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/Makefile4
-rw-r--r--drivers/pcmcia/sa1100_assabet.c100
-rw-r--r--drivers/pcmcia/sa1100_cerf.c86
-rw-r--r--drivers/pcmcia/sa1100_generic.c115
-rw-r--r--drivers/pcmcia/sa1100_generic.h4
-rw-r--r--drivers/pcmcia/sa1100_h3600.c16
-rw-r--r--drivers/pcmcia/sa1100_nanoengine.c133
-rw-r--r--drivers/pcmcia/sa1100_shannon.c104
-rw-r--r--drivers/pcmcia/sa1100_simpad.c12
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
43sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o 43sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o
44 44
45sa1100_cs-y += sa1100_generic.o 45sa1100_cs-y += sa1100_generic.o
46sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
47sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
48sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o 46sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
49sa1100_cs-$(CONFIG_SA1100_H3100) += sa1100_h3600.o 47sa1100_cs-$(CONFIG_SA1100_H3100) += sa1100_h3600.o
50sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o 48sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
51sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o
52sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
53sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o 49sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
54 50
55pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o 51pxa2xx_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
21static 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
35static int
36assabet_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 */
75static 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
84static 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
92int 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
24static 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
44static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
45{
46 gpio_free(CERF_GPIO_CF_RESET);
47}
48
49static int
50cerf_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
70static 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
78int 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
46static 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
53static 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
85static 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
91static 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
44int __init pcmcia_collie_init(struct device *dev); 98int __init pcmcia_collie_init(struct device *dev);
45 99
46static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { 100static 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
70static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) 112static 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
86static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) 128static 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
141static 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
166static 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
99static struct platform_driver sa11x0_pcmcia_driver = { 180static 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 */
8extern int pcmcia_adsbitsy_init(struct device *); 8extern int pcmcia_adsbitsy_init(struct device *);
9extern int pcmcia_assabet_init(struct device *);
10extern int pcmcia_badge4_init(struct device *); 9extern int pcmcia_badge4_init(struct device *);
11extern int pcmcia_cerf_init(struct device *);
12extern int pcmcia_flexanet_init(struct device *); 10extern int pcmcia_flexanet_init(struct device *);
13extern int pcmcia_freebird_init(struct device *); 11extern int pcmcia_freebird_init(struct device *);
14extern int pcmcia_gcplus_init(struct device *); 12extern int pcmcia_gcplus_init(struct device *);
15extern int pcmcia_graphicsmaster_init(struct device *); 13extern int pcmcia_graphicsmaster_init(struct device *);
16extern int pcmcia_h3600_init(struct device *); 14extern int pcmcia_h3600_init(struct device *);
17extern int pcmcia_nanoengine_init(struct device *);
18extern int pcmcia_pangolin_init(struct device *); 15extern int pcmcia_pangolin_init(struct device *);
19extern int pcmcia_pfs168_init(struct device *); 16extern int pcmcia_pfs168_init(struct device *);
20extern int pcmcia_shannon_init(struct device *);
21extern int pcmcia_simpad_init(struct device *); 17extern int pcmcia_simpad_init(struct device *);
22extern int pcmcia_stork_init(struct device *); 18extern int pcmcia_stork_init(struct device *);
23extern int pcmcia_system3_init(struct device *); 19extern 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
38struct nanoengine_pins {
39 unsigned output_pins;
40 unsigned clear_outputs;
41 int gpio_rst;
42 int gpio_cd;
43 int gpio_rdy;
44};
45
46static 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
58unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
59
60static 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
81static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
82{
83 gpio_free(nano_skts[skt->nr].gpio_rst);
84}
85
86static 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
99static 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
113static 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
123int 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
20static 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
43static void
44shannon_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
64static int
65shannon_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
89static 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
96int 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
32static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 29static 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