summaryrefslogtreecommitdiff
path: root/drivers/pcmcia/pxa2xx_mainstone.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 11:23:17 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 11:23:17 -0800
commit1205b62390eed4e747232d183fbf412a5aecacd9 (patch)
tree7fde1a5aaee01a23e6ea4137329f332d5e179adf /drivers/pcmcia/pxa2xx_mainstone.c
parent9ee3b3f4a5eb523ef27675ac2fcd2269b9d68767 (diff)
parent6de92920a717ea2b7b45bb3d651b8bb951eab185 (diff)
Merge tag 'for-4.21' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King: "Included in this update: - Florian Fainelli noticed that userspace segfaults caused by the lack of kernel-userspace helpers was hard to diagnose; we now issue a warning when userspace tries to use the helpers but the kernel has them disabled. - Ben Dooks wants compatibility for the old ATAG serial number with DT systems. - Some cleanup of assembly by Nicolas Pitre. - User accessors optimisation from Vincent Whitchurch. - More robust kdump on SMP systems from Yufen Wang. - Sebastian Andrzej Siewior noticed problems with the SMP "boot_lock" on RT kernels, and so we convert the Versatile series of platforms to use a raw spinlock instead, consolidating the Versatile implementation. We entirely remove the boot_lock on OMAP systems, where it's unnecessary. Further patches for other systems will be submitted for the following merge window. - Start switching old StrongARM-11x0 systems to use gpiolib rather than their private GPIO implementation - mostly PCMCIA bits. - ARM Kconfig cleanups. - Cleanup a mostly harmless mistake in the recent Spectre patch in 4.20 (which had the effect that data that can be placed into the init sections was incorrectly always placed in the rodata section)" * tag 'for-4.21' of git://git.armlinux.org.uk/~rmk/linux-arm: (25 commits) ARM: omap2: remove unnecessary boot_lock ARM: versatile: rename and comment SMP implementation ARM: versatile: convert boot_lock to raw ARM: vexpress/realview: consolidate immitation CPU hotplug ARM: fix the cockup in the previous patch ARM: sa1100/cerf: switch to using gpio_led_register_device() ARM: sa1100/assabet: switch to using gpio leds ARM: sa1100/assabet: add gpio keys support for right-hand two buttons ARM: sa1111: remove legacy GPIO interfaces pcmcia: sa1100*: remove redundant bvd1/bvd2 setting ARM: pxa/lubbock: switch PCMCIA to MAX1600 library ARM: pxa/mainstone: switch PCMCIA to MAX1600 library and gpiod APIs ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and gpiod APIs ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs pcmcia: add MAX1600 library ARM: sa1100: explicitly register sa11x0-pcmcia devices ARM: 8813/1: Make aligned 2-byte getuser()/putuser() atomic on ARMv6+ ARM: 8812/1: Optimise copy_{from/to}_user for !CPU_USE_DOMAINS ARM: 8811/1: always list both ldrd/strd registers explicitly ARM: 8808/1: kexec:offline panic_smp_self_stop CPU ...
Diffstat (limited to 'drivers/pcmcia/pxa2xx_mainstone.c')
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c113
1 files changed, 34 insertions, 79 deletions
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 7e32e25cdcb2..770c7bf0171d 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -11,56 +11,55 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <pcmcia/ss.h>
#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <mach/pxa2xx-regs.h>
-#include <mach/mainstone.h>
#include "soc_common.h"
-
+#include "max1600.h"
static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- /*
- * Setup default state of GPIO outputs
- * before we enable them as outputs.
- */
- if (skt->nr == 0) {
- skt->socket.pci_irq = MAINSTONE_S0_IRQ;
- skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ;
- skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
- skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ;
- skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
- } else {
- skt->socket.pci_irq = MAINSTONE_S1_IRQ;
- skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ;
- skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
- skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ;
- skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG";
- }
- return 0;
+ struct device *dev = skt->socket.dev.parent;
+ struct max1600 *m;
+ int ret;
+
+ skt->stat[SOC_STAT_CD].name = skt->nr ? "bdetect" : "adetect";
+ skt->stat[SOC_STAT_BVD1].name = skt->nr ? "bbvd1" : "abvd1";
+ skt->stat[SOC_STAT_BVD2].name = skt->nr ? "bbvd2" : "abvd2";
+ skt->stat[SOC_STAT_RDY].name = skt->nr ? "bready" : "aready";
+ skt->stat[SOC_STAT_VS1].name = skt->nr ? "bvs1" : "avs1";
+ skt->stat[SOC_STAT_VS2].name = skt->nr ? "bvs2" : "avs2";
+
+ skt->gpio_reset = devm_gpiod_get(dev, skt->nr ? "breset" : "areset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(skt->gpio_reset))
+ return PTR_ERR(skt->gpio_reset);
+
+ ret = max1600_init(dev, &m, skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+ MAX1600_CODE_HIGH);
+ if (ret)
+ return ret;
+
+ skt->driver_data = m;
+
+ return soc_pcmcia_request_gpiods(skt);
}
-static unsigned long mst_pcmcia_status[2];
+static unsigned int mst_pcmcia_bvd1_status[2];
static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
- unsigned long status, flip;
-
- status = (skt->nr == 0) ? MST_PCMCIA0 : MST_PCMCIA1;
- flip = (status ^ mst_pcmcia_status[skt->nr]) & MST_PCMCIA_nSTSCHG_BVD1;
+ unsigned int flip = mst_pcmcia_bvd1_status[skt->nr] ^ state->bvd1;
/*
* Workaround for STSCHG which can't be deasserted:
@@ -68,62 +67,18 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
* as needed to avoid IRQ locks.
*/
if (flip) {
- mst_pcmcia_status[skt->nr] = status;
- if (status & MST_PCMCIA_nSTSCHG_BVD1)
- enable_irq( (skt->nr == 0) ? MAINSTONE_S0_STSCHG_IRQ
- : MAINSTONE_S1_STSCHG_IRQ );
+ mst_pcmcia_bvd1_status[skt->nr] = state->bvd1;
+ if (state->bvd1)
+ enable_irq(skt->stat[SOC_STAT_BVD1].irq);
else
- disable_irq( (skt->nr == 0) ? MAINSTONE_S0_STSCHG_IRQ
- : MAINSTONE_S1_STSCHG_IRQ );
+ disable_irq(skt->stat[SOC_STAT_BVD2].irq);
}
-
- state->detect = (status & MST_PCMCIA_nCD) ? 0 : 1;
- state->ready = (status & MST_PCMCIA_nIRQ) ? 1 : 0;
- state->bvd1 = (status & MST_PCMCIA_nSTSCHG_BVD1) ? 1 : 0;
- state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
- state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1;
- state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1;
}
static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
- unsigned long power = 0;
- int ret = 0;
-
- switch (state->Vcc) {
- case 0: power |= MST_PCMCIA_PWR_VCC_0; break;
- case 33: power |= MST_PCMCIA_PWR_VCC_33; break;
- case 50: power |= MST_PCMCIA_PWR_VCC_50; break;
- default:
- printk(KERN_ERR "%s(): bad Vcc %u\n",
- __func__, state->Vcc);
- ret = -1;
- }
-
- switch (state->Vpp) {
- case 0: power |= MST_PCMCIA_PWR_VPP_0; break;
- case 120: power |= MST_PCMCIA_PWR_VPP_120; break;
- default:
- if(state->Vpp == state->Vcc) {
- power |= MST_PCMCIA_PWR_VPP_VCC;
- } else {
- printk(KERN_ERR "%s(): bad Vpp %u\n",
- __func__, state->Vpp);
- ret = -1;
- }
- }
-
- if (state->flags & SS_RESET)
- power |= MST_PCMCIA_RESET;
-
- switch (skt->nr) {
- case 0: MST_PCMCIA0 = power; break;
- case 1: MST_PCMCIA1 = power; break;
- default: ret = -1;
- }
-
- return ret;
+ return max1600_configure(skt->driver_data, state->Vcc, state->Vpp);
}
static struct pcmcia_low_level mst_pcmcia_ops __initdata = {