Update Linux to v5.4.2

Change-Id: Idf6911045d9d382da2cfe01b1edff026404ac8fd
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index cbbe4a2..e004d8d 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -1,9 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
 #
 # PCCARD (PCMCIA/CardBus) bus subsystem configuration
 #
 
 menuconfig PCCARD
 	tristate "PCCard (PCMCIA/CardBus) support"
+	depends on !UML
 	---help---
 	  Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
 	  computer.  These are credit-card size devices such as network cards,
@@ -63,6 +65,9 @@
 
 	  If unsure, say Y.
 
+config PCMCIA_MAX1600
+	tristate
+
 comment "PC-card bridges"
 
 config YENTA
@@ -191,6 +196,8 @@
 	select PCMCIA_SOC_COMMON
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
+	select PCMCIA_MAX1600 if ASSABET_NEPONSET
+	select PCMCIA_MAX1600 if ARCH_LUBBOCK && SA1111
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
@@ -207,6 +214,7 @@
 		    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
 		    || MACH_COLIBRI320 || MACH_H4700)
 	select PCMCIA_SOC_COMMON
+	select PCMCIA_MAX1600 if MACH_MAINSTONE
 	help
 	  Say Y here to include support for the PXA2xx PCMCIA controller
 
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 28502bd..01779c5 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -35,6 +35,7 @@
 obj-$(CONFIG_AT91_CF)				+= at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o
 obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)		+= db1xxx_ss.o
+obj-$(CONFIG_PCMCIA_MAX1600)			+= max1600.o
 
 sa1111_cs-y					+= sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1111_neponset.o
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 7da7b0f..7db0e9c 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * at91_cf.c -- AT91 CompactFlash controller driver
  *
  * Copyright (C) 2005 David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 5c01705..c502dfb 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * cardbus.c -- 16-bit PCMCIA core support
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index ac0672b..629359f 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
@@ -24,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/io.h>
+#include <linux/security.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
@@ -1578,6 +1576,10 @@
 	struct pcmcia_socket *s;
 	int error;
 
+	error = security_locked_down(LOCKDOWN_PCMCIA_CIS);
+	if (error)
+		return error;
+
 	s = to_socket(container_of(kobj, struct device, kobj));
 
 	if (off)
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 8c8caec..e211e26 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * cs.c -- Kernel Card Services - core services
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 03ec438..33c9b6e 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -1,10 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * cs_internal.h -- definitions internal to the PCMCIA core modules
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
@@ -12,7 +9,6 @@
  * (C) 1999		David A. Hinds
  * (C) 2003 - 2010	Dominik Brodowski
  *
- *
  * This file contains definitions _only_ needed by the PCMCIA core modules.
  * It must not be included by PCMCIA socket drivers or by PCMCIA device
  * drivers.
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 19e1782..590e594 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * PCMCIA socket code for the Alchemy Db1xxx/Pb1xxx boards.
  *
@@ -254,8 +255,10 @@
 	switch (state->Vcc) {
 	case 50:
 		++v;
+		/* fall through */
 	case 33:
 		++v;
+		/* fall through */
 	case 0:
 		break;
 	default:
@@ -266,9 +269,11 @@
 	switch (state->Vpp) {
 	case 12:
 		++p;
+		/* fall through */
 	case 33:
 	case 50:
 		++p;
+		/* fall through */
 	case 0:
 		break;
 	default:
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index a9258f6..09d06b0 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * ds.c -- 16-bit PCMCIA core support
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
@@ -67,7 +64,7 @@
 			       "be 0x%x\n", p_drv->name, did->prod_id[i],
 			       did->prod_id_hash[i], hash);
 			printk(KERN_DEBUG "pcmcia: see "
-				"Documentation/pcmcia/devicetable.txt for "
+				"Documentation/pcmcia/devicetable.rst for "
 				"details\n");
 		}
 		did++;
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c
index 9671ded..f2741c0 100644
--- a/drivers/pcmcia/electra_cf.c
+++ b/drivers/pcmcia/electra_cf.c
@@ -1,23 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (C) 2007 PA Semi, Inc
  *
  * Maintained by: Olof Johansson <olof@lixom.net>
  *
  * Based on drivers/pcmcia/omap_cf.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 #include <linux/module.h>
@@ -230,7 +217,7 @@
 
 	if (!cf->mem_base || !cf->io_virt || !cf->gpio_base ||
 	    (__ioremap_at(io.start, cf->io_virt, cf->io_size,
-		  pgprot_val(pgprot_noncached(__pgprot(0)))) == NULL)) {
+			  pgprot_noncached(PAGE_KERNEL)) == NULL)) {
 		dev_err(device, "can't ioremap ranges\n");
 		status = -ENOMEM;
 		goto fail1;
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index aae7e6d..245d601 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /* 
  * Driver for Intel I82092AA PCI-PCMCIA bridge.
  *
@@ -116,9 +117,9 @@
 		
 		if (card_present(i)) {
 			sockets[i].card_state = 3;
-			dprintk(KERN_DEBUG "i82092aa: slot %i is occupied\n",i);
+			dev_dbg(&dev->dev, "i82092aa: slot %i is occupied\n", i);
 		} else {
-			dprintk(KERN_DEBUG "i82092aa: slot %i is vacant\n",i);
+			dev_dbg(&dev->dev, "i82092aa: slot %i is vacant\n", i);
 		}
 	}
 		
@@ -127,7 +128,7 @@
 	pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
 
 	/* Register the interrupt handler */
-	dprintk(KERN_DEBUG "Requesting interrupt %i \n",dev->irq);
+	dev_dbg(&dev->dev, "Requesting interrupt %i\n", dev->irq);
 	if ((ret = request_irq(dev->irq, i82092aa_interrupt, IRQF_SHARED, "i82092aa", i82092aa_interrupt))) {
 		printk(KERN_ERR "i82092aa: Failed to register IRQ %d, aborting\n", dev->irq);
 		goto err_out_free_res;
diff --git a/drivers/pcmcia/max1600.c b/drivers/pcmcia/max1600.c
new file mode 100644
index 0000000..379875a
--- /dev/null
+++ b/drivers/pcmcia/max1600.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MAX1600 PCMCIA power switch library
+ *
+ * Copyright (C) 2016 Russell King
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+#include "max1600.h"
+
+static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = {
+	{ "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
+	{ "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+	unsigned int channel, unsigned int code)
+{
+	struct max1600 *m;
+	int chan;
+	int i;
+
+	switch (channel) {
+	case MAX1600_CHAN_A:
+		chan = 0;
+		break;
+	case MAX1600_CHAN_B:
+		chan = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH)
+		return -EINVAL;
+
+	m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
+	if (!m)
+		return -ENOMEM;
+
+	m->dev = dev;
+	m->code = code;
+
+	for (i = 0; i < MAX1600_GPIO_MAX; i++) {
+		const char *name;
+
+		name = max1600_gpio_name[chan][i];
+		if (i != MAX1600_GPIO_0VPP) {
+			m->gpio[i] = devm_gpiod_get(dev, name, GPIOD_OUT_LOW);
+		} else {
+			m->gpio[i] = devm_gpiod_get_optional(dev, name,
+							     GPIOD_OUT_LOW);
+			if (!m->gpio[i])
+				break;
+		}
+		if (IS_ERR(m->gpio[i]))
+			return PTR_ERR(m->gpio[i]);
+	}
+
+	*ptr = m;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(max1600_init);
+
+int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp)
+{
+	DECLARE_BITMAP(values, MAX1600_GPIO_MAX) = { 0, };
+	int n = MAX1600_GPIO_0VPP;
+
+	if (m->gpio[MAX1600_GPIO_0VPP]) {
+		if (vpp == 0) {
+			__assign_bit(MAX1600_GPIO_0VPP, values, 0);
+			__assign_bit(MAX1600_GPIO_1VPP, values, 0);
+		} else if (vpp == 120) {
+			__assign_bit(MAX1600_GPIO_0VPP, values, 0);
+			__assign_bit(MAX1600_GPIO_1VPP, values, 1);
+		} else if (vpp == vcc) {
+			__assign_bit(MAX1600_GPIO_0VPP, values, 1);
+			__assign_bit(MAX1600_GPIO_1VPP, values, 0);
+		} else {
+			dev_err(m->dev, "unrecognised Vpp %u.%uV\n",
+				vpp / 10, vpp % 10);
+			return -EINVAL;
+		}
+		n = MAX1600_GPIO_MAX;
+	} else if (vpp != vcc && vpp != 0) {
+		dev_err(m->dev, "no VPP control\n");
+		return -EINVAL;
+	}
+
+	if (vcc == 0) {
+		__assign_bit(MAX1600_GPIO_0VCC, values, 0);
+		__assign_bit(MAX1600_GPIO_1VCC, values, 0);
+	} else if (vcc == 33) { /* VY */
+		__assign_bit(MAX1600_GPIO_0VCC, values, 1);
+		__assign_bit(MAX1600_GPIO_1VCC, values, 0);
+	} else if (vcc == 50) { /* VX */
+		__assign_bit(MAX1600_GPIO_0VCC, values, 0);
+		__assign_bit(MAX1600_GPIO_1VCC, values, 1);
+	} else {
+		dev_err(m->dev, "unrecognised Vcc %u.%uV\n",
+			vcc / 10, vcc % 10);
+		return -EINVAL;
+	}
+
+	if (m->code == MAX1600_CODE_HIGH) {
+		/*
+		 * Cirrus mode appears to be the same as Intel mode,
+		 * except the VCC pins are inverted.
+		 */
+		__change_bit(MAX1600_GPIO_0VCC, values);
+		__change_bit(MAX1600_GPIO_1VCC, values);
+	}
+
+	return gpiod_set_array_value_cansleep(n, m->gpio, NULL, values);
+}
+EXPORT_SYMBOL_GPL(max1600_configure);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pcmcia/max1600.h b/drivers/pcmcia/max1600.h
new file mode 100644
index 0000000..00bf1a0
--- /dev/null
+++ b/drivers/pcmcia/max1600.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef MAX1600_H
+#define MAX1600_H
+
+struct gpio_desc;
+
+enum {
+	MAX1600_GPIO_0VCC = 0,
+	MAX1600_GPIO_1VCC,
+	MAX1600_GPIO_0VPP,
+	MAX1600_GPIO_1VPP,
+	MAX1600_GPIO_MAX,
+
+	MAX1600_CHAN_A,
+	MAX1600_CHAN_B,
+
+	MAX1600_CODE_LOW,
+	MAX1600_CODE_HIGH,
+};
+
+struct max1600 {
+	struct gpio_desc *gpio[MAX1600_GPIO_MAX];
+	struct device *dev;
+	unsigned int code;
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+	unsigned int channel, unsigned int code);
+
+int max1600_configure(struct max1600 *, unsigned int vcc, unsigned int vpp);
+
+#endif
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index c2a17a7..0a04eb0 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * omap_cf.c -- OMAP 16xx CompactFlash controller driver
  *
  * Copyright (c) 2005 David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/module.h>
@@ -22,7 +18,7 @@
 
 #include <mach/hardware.h>
 #include <asm/io.h>
-#include <asm/sizes.h>
+#include <linux/sizes.h>
 
 #include <mach/mux.h>
 #include <mach/tc.h>
diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c
index 1c05d74..b553f7a 100644
--- a/drivers/pcmcia/pcmcia_cis.c
+++ b/drivers/pcmcia/pcmcia_cis.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * PCMCIA high-level CIS access functions
  *
@@ -7,11 +8,6 @@
  *
  * Copyright (C) 1999	     David A. Hinds
  * Copyright (C) 2004-2010   Dominik Brodowski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/slab.h>
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 1880209..e3a6b6c 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * PCMCIA 16-bit resource management functions
  *
@@ -7,11 +8,6 @@
  *
  * Copyright (C) 1999	     David A. Hinds
  * Copyright (C) 2004-2010   Dominik Brodowski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/module.h>
@@ -284,7 +280,7 @@
 		io_on.stop = s->io[i].res->end;
 
 		s->ops->set_io_map(s, &io_off);
-		mdelay(40);
+		msleep(40);
 		s->ops->set_io_map(s, &io_on);
 	}
 unlock:
@@ -567,7 +563,7 @@
 			!(flags & CONF_ENABLE_PULSE_IRQ))
 			option |= COR_LEVEL_REQ;
 		pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &option);
-		mdelay(40);
+		msleep(40);
 	}
 	if (p_dev->config_regs & PRESENT_STATUS)
 		pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &status);
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c
index 2ef576c..5fe1da7 100644
--- a/drivers/pcmcia/pxa2xx_balloon3.c
+++ b/drivers/pcmcia/pxa2xx_balloon3.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_balloon3.c
  *
@@ -9,10 +10,6 @@
  *  Derived from pxa2xx_mainstone.c, by Nico Pitre
  *
  * Various modification by Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 91b5f57..d6d2f75 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -1,10 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*======================================================================
 
   Device driver for the PCMCIA control functionality of PXA2xx
   microprocessors.
 
-    The contents of this file may be used under the
-    terms of the GNU Public License version 2 (the "GPL")
 
     (c) Ian Molton (spyro@f2s.com) 2003
     (c) Stefan Eletzhofer (stefan.eletzhofer@inquant.de) 2003,4
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index da40908..c0b6b84 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Compulab Ltd., 2003, 2007, 2008
  * Mike Rapoport <mike@compulab.co.il>
- *
  */
 
 #include <linux/platform_device.h>
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index f59223f..36e35da 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa/pxa_cm_x270.c
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Compulab Ltd., 2003, 2007, 2008
  * Mike Rapoport <mike@compulab.co.il>
- *
  */
 
 #include <linux/platform_device.h>
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c
index 6e7dcfd..14eae23 100644
--- a/drivers/pcmcia/pxa2xx_cm_x2xx.c
+++ b/drivers/pcmcia/pxa2xx_cm_x2xx.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa/pxa_cm_x2xx.c
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Compulab Ltd., 2003, 2007, 2008
  * Mike Rapoport <mike@compulab.co.il>
- *
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c
index 4dee7b2..f0f725e 100644
--- a/drivers/pcmcia/pxa2xx_colibri.c
+++ b/drivers/pcmcia/pxa2xx_colibri.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_colibri.c
  *
  * Driver for Toradex Colibri PXA270 CF socket
  *
  * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c
index 8751a32..72caa6d 100644
--- a/drivers/pcmcia/pxa2xx_e740.c
+++ b/drivers/pcmcia/pxa2xx_e740.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Toshiba e740 PCMCIA specific routines.
  *
  * (c) 2004 Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/init.h>
diff --git a/drivers/pcmcia/pxa2xx_hx4700.c b/drivers/pcmcia/pxa2xx_hx4700.c
index 7dfef3e..87b6a16 100644
--- a/drivers/pcmcia/pxa2xx_hx4700.c
+++ b/drivers/pcmcia/pxa2xx_hx4700.c
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  *  Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 7e32e25..a076e41 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_mainstone.c
  *
@@ -6,61 +7,56 @@
  * Created:	May 12, 2004
  * Author:	Nicolas Pitre
  * Copyright:	MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * 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 +64,18 @@
 	 * 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 = {
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
index ed7d4db..cfff41a 100644
--- a/drivers/pcmcia/pxa2xx_palmld.c
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_palmld.c
  *
@@ -5,11 +6,6 @@
  *
  * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
  * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c
index 81225a7..8fe0561 100644
--- a/drivers/pcmcia/pxa2xx_palmtc.c
+++ b/drivers/pcmcia/pxa2xx_palmtc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_palmtc.c
  *
@@ -5,11 +6,6 @@
  *
  * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
  * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index 069b6bb..c449ca7 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_palmtx.c
  *
  * Driver for Palm T|X PCMCIA
  *
  * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 89ebd8c..5fdd25a 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Sharp SL-C7xx Series PCMCIA routines
  *
  * Copyright (c) 2004-2005 Richard Purdie
  *
  * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c
index 1d73c44..6efb7f8 100644
--- a/drivers/pcmcia/pxa2xx_stargate2.c
+++ b/drivers/pcmcia/pxa2xx_stargate2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_stargate2.c
  *
@@ -7,10 +8,6 @@
  * Author:	Ed C. Epp
  * Copyright:	Intel Corp 2005
  *              Jonathan Cameron <jic23@cam.ac.uk> 2009
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
index d326ba1..6db8fe8 100644
--- a/drivers/pcmcia/pxa2xx_trizeps4.c
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_trizeps4.c
  *
@@ -6,10 +7,6 @@
  * Author:	Jürgen Schindele
  * Created:	20 02, 2006
  * Copyright:	Jürgen Schindele
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c
index 33c5b88..3565add 100644
--- a/drivers/pcmcia/pxa2xx_vpac270.c
+++ b/drivers/pcmcia/pxa2xx_vpac270.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_vpac270.c
  *
  * Driver for Voipac PXA270 PCMCIA and CF sockets
  *
  * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/gpio.h>
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c
index f53c237..b04b164 100644
--- a/drivers/pcmcia/rsrc_iodyn.c
+++ b/drivers/pcmcia/rsrc_iodyn.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * rsrc_iodyn.c -- Resource management routines for MEM-static sockets.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index df2cb70..2528932 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * rsrc_mgr.c -- Resource management routines and/or wrappers
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 49377d5..9e6922c 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * rsrc_nonstatic.c -- Resource management routines for !SS_CAP_STATIC_MAP sockets
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index e235ee1..e2e8729 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -39,8 +39,8 @@
 {
 	long cs3reg = simpad_get_cs3_ro();
 
-	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
-	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
+	/* bvd1 might be cs3reg & PCMCIA_BVD1 */
+	/* bvd2 might be cs3reg & PCMCIA_BVD2 */
 
 	if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
 			(PCMCIA_VS1|PCMCIA_VS2)) {
diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c
index 93a5c74..e76d5ba 100644
--- a/drivers/pcmcia/sa1111_badge4.c
+++ b/drivers/pcmcia/sa1111_badge4.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/sa1100_badge4.c
  *
@@ -6,11 +7,6 @@
  *   Christopher Hoover <ch@hpl.hp.com>
  *
  * Copyright (C) 2002 Hewlett-Packard Company
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 5ef351f..1178341 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/sa1111_generic.c
  *
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index 3d4ca87..1083e1b 100644
--- a/drivers/pcmcia/sa1111_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -6,29 +6,62 @@
  *
  */
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
 
 #include "sa1111_generic.h"
 
-/* Does SOCKET1_3V actually do anything? */
-#define SOCKET0_POWER	GPIO_GPIO0
-#define SOCKET0_3V	GPIO_GPIO2
-#define SOCKET1_POWER	(GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V	GPIO_GPIO3
+/*
+ * Socket 0 power: GPIO A0
+ * Socket 0 3V: GPIO A2
+ * Socket 1 power: GPIO A1 & GPIO A3
+ * Socket 1 3V: GPIO A3
+ * Does Socket 1 3V actually do anything?
+ */
+enum {
+	J720_GPIO_PWR,
+	J720_GPIO_3V,
+	J720_GPIO_MAX,
+};
+struct jornada720_data {
+	struct gpio_desc *gpio[J720_GPIO_MAX];
+};
+
+static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct device *dev = skt->socket.dev.parent;
+	struct jornada720_data *j;
+
+	j = devm_kzalloc(dev, sizeof(*j), GFP_KERNEL);
+	if (!j)
+		return -ENOMEM;
+
+	j->gpio[J720_GPIO_PWR] = devm_gpiod_get(dev, skt->nr ? "s1-power" :
+						"s0-power", GPIOD_OUT_LOW);
+	if (IS_ERR(j->gpio[J720_GPIO_PWR]))
+		return PTR_ERR(j->gpio[J720_GPIO_PWR]);
+
+	j->gpio[J720_GPIO_3V] = devm_gpiod_get(dev, skt->nr ? "s1-3v" :
+					       "s0-3v", GPIOD_OUT_LOW);
+	if (IS_ERR(j->gpio[J720_GPIO_3V]))
+		return PTR_ERR(j->gpio[J720_GPIO_3V]);
+
+	skt->driver_data = j;
+
+	return 0;
+}
 
 static int
 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set;
+	struct jornada720_data *j = skt->driver_data;
+	DECLARE_BITMAP(values, J720_GPIO_MAX) = { 0, };
 	int ret;
 
 	printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
@@ -36,35 +69,34 @@
 
 	switch (skt->nr) {
 	case 0:
-		pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
 		switch (state->Vcc) {
 		default:
 		case  0:
-			pa_dwr_set = 0;
+			__assign_bit(J720_GPIO_PWR, values, 0);
+			__assign_bit(J720_GPIO_3V, values, 0);
 			break;
 		case 33:
-			pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+			__assign_bit(J720_GPIO_PWR, values, 1);
+			__assign_bit(J720_GPIO_3V, values, 1);
 			break;
 		case 50:
-			pa_dwr_set = SOCKET0_POWER;
+			__assign_bit(J720_GPIO_PWR, values, 1);
+			__assign_bit(J720_GPIO_3V, values, 0);
 			break;
 		}
 		break;
 
 	case 1:
-		pa_dwr_mask = SOCKET1_POWER;
-
 		switch (state->Vcc) {
 		default:
 		case 0:
-			pa_dwr_set = 0;
+			__assign_bit(J720_GPIO_PWR, values, 0);
+			__assign_bit(J720_GPIO_3V, values, 0);
 			break;
 		case 33:
-			pa_dwr_set = SOCKET1_POWER;
-			break;
 		case 50:
-			pa_dwr_set = SOCKET1_POWER;
+			__assign_bit(J720_GPIO_PWR, values, 1);
+			__assign_bit(J720_GPIO_3V, values, 1);
 			break;
 		}
 		break;
@@ -81,13 +113,15 @@
 
 	ret = sa1111_pcmcia_configure_socket(skt, state);
 	if (ret == 0)
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+		ret = gpiod_set_array_value_cansleep(J720_GPIO_MAX, j->gpio,
+						     NULL, values);
 
 	return ret;
 }
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= jornada720_pcmcia_hw_init,
 	.configure_socket	= jornada720_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -95,16 +129,9 @@
 
 int pcmcia_jornada720_init(struct sa1111_dev *sadev)
 {
-	unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
 	/* Fixme: why messing around with SA11x0's GPIO1? */
 	GRER |= 0x00000002;
 
-	/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-	sa1111_set_io_dir(sadev, pin, 0, 0);
-	sa1111_set_io(sadev, pin, 0);
-	sa1111_set_sleep_io(sadev, pin, 0);
-
 	sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
 	return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
 				 sa11xx_drv_pcmcia_add_one);
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index e741f49..7feb8d6 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * linux/drivers/pcmcia/pxa2xx_lubbock.c
  *
@@ -5,14 +6,9 @@
  * Created:	Jan 10, 2002
  * Copyright:	MontaVista Software Inc.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
  *
  * Lubbock PCMCIA specific routines.
- *
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -24,20 +20,31 @@
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
-#include <mach/lubbock.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
+
+static int lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct max1600 *m;
+	int ret;
+
+	ret = max1600_init(skt->socket.dev.parent, &m,
+			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+			   MAX1600_CODE_HIGH);
+	if (ret == 0)
+		skt->driver_data = m;
+
+	return ret;
+}
 
 static int
 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 				const socket_state_t *state)
 {
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
+	struct max1600 *m = skt->driver_data;
 	int ret = 0;
 
-	pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
-
 	/* Lubbock uses the Maxim MAX1602, with the following connections:
 	 *
 	 * Socket 0 (PCMCIA):
@@ -71,74 +78,7 @@
  again:
 	switch (skt->nr) {
 	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			pa_dwr_set |= GPIO_A3;
-			break;
-
-		case 50: /* VX */
-			pa_dwr_set |= GPIO_A2;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-		}
-
-		switch (state->Vpp) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 120: /* 12IN */
-			pa_dwr_set |= GPIO_A1;
-			break;
-
-		default: /* VCC */
-			if (state->Vpp == state->Vcc)
-				pa_dwr_set |= GPIO_A0;
-			else {
-				printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-				       __func__, state->Vpp);
-				ret = -1;
-				break;
-			}
-		}
-		break;
-
 	case 1:
-		misc_mask = (1 << 15) | (1 << 14);
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			misc_set |= 1 << 15;
-			break;
-
-		case 50: /* VX */
-			misc_set |= 1 << 14;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-			break;
-		}
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-			       __func__, state->Vpp);
-			ret = -1;
-			break;
-		}
 		break;
 
 	default:
@@ -147,11 +87,8 @@
 
 	if (ret == 0)
 		ret = sa1111_pcmcia_configure_socket(skt, state);
-
-	if (ret == 0) {
-		lubbock_set_misc_wr(misc_mask, misc_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
+	if (ret == 0)
+		ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 #if 1
 	if (ret == 0 && state->Vcc == 33) {
@@ -175,8 +112,7 @@
 			/*
 			 * Switch to 5V,  Configure socket with 5V voltage
 			 */
-			lubbock_set_misc_wr(misc_mask, 0);
-			sa1111_set_io(s->dev, pa_dwr_mask, 0);
+			max1600_configure(m, 0, 0);
 
 			/*
 			 * It takes about 100ms to turn off Vcc.
@@ -201,6 +137,7 @@
 
 static struct pcmcia_low_level lubbock_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= lubbock_pcmcia_hw_init,
 	.configure_socket	= lubbock_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -210,17 +147,6 @@
 
 int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 {
-	/*
-	 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-	 * and switch to standby mode.
-	 */
-	sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-	sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-	sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
-	/* Set CF Socket 1 power to standby mode. */
-	lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
-
 	pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
 	pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
 	return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index 0ccf05a..de0ce13 100644
--- a/drivers/pcmcia/sa1111_neponset.c
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -10,12 +10,10 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/neponset.h>
-#include <asm/hardware/sa1111.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
 
 /*
  * Neponset uses the Maxim MAX1600, with the following connections:
@@ -40,70 +38,36 @@
  * "Standard Intel code" mode. Refer to the Maxim data sheet for
  * the corresponding truth table.
  */
+static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct max1600 *m;
+	int ret;
+
+	ret = max1600_init(skt->socket.dev.parent, &m,
+			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+			   MAX1600_CODE_LOW);
+	if (ret == 0)
+		skt->driver_data = m;
+
+	return ret;
+}
 
 static int
 neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+	struct max1600 *m = skt->driver_data;
 	int ret;
 
-	switch (skt->nr) {
-	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1;
-		ncr_mask = NCR_A0VPP | NCR_A1VPP;
-
-		if (state->Vpp == 0)
-			ncr_set = 0;
-		else if (state->Vpp == 120)
-			ncr_set = NCR_A1VPP;
-		else if (state->Vpp == state->Vcc)
-			ncr_set = NCR_A0VPP;
-		else {
-			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
-
-	case 1:
-		pa_dwr_mask = GPIO_A2 | GPIO_A3;
-		ncr_mask = 0;
-		ncr_set = 0;
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
-
-	default:
-		return -1;
-	}
-
-	/*
-	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
-	 * pa_dwr_mask selects which bits (and therefore socket) we change.
-	 */
-	switch (state->Vcc) {
-	default:
-	case 0:  pa_dwr_set = 0;		break;
-	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
-	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
-	}
-
 	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		neponset_ncr_frob(ncr_mask, ncr_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
+	if (ret == 0)
+		ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 	return ret;
 }
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= neponset_pcmcia_hw_init,
 	.configure_socket	= neponset_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -111,13 +75,6 @@
 
 int pcmcia_neponset_init(struct sa1111_dev *sadev)
 {
-	/*
-	 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-	 * and switch to standby mode.
-	 */
-	sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-	sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-	sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
 	sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
 	return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
 				 sa11xx_drv_pcmcia_add_one);
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index c5f2344..3a8c84b 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -351,19 +351,20 @@
 
 	if (ret == 0) {
 		struct gpio_desc *descs[2];
-		int values[2], n = 0;
+		DECLARE_BITMAP(values, 2);
+		int n = 0;
 
 		if (skt->gpio_reset) {
 			descs[n] = skt->gpio_reset;
-			values[n++] = !!(state->flags & SS_RESET);
+			__assign_bit(n++, values, state->flags & SS_RESET);
 		}
 		if (skt->gpio_bus_enable) {
 			descs[n] = skt->gpio_bus_enable;
-			values[n++] = !!(state->flags & SS_OUTPUT_ENA);
+			__assign_bit(n++, values, state->flags & SS_OUTPUT_ENA);
 		}
 
 		if (n)
-			gpiod_set_array_value_cansleep(n, descs, values);
+			gpiod_set_array_value_cansleep(n, descs, NULL, values);
 
 		/*
 		 * This really needs a better solution.  The IRQ
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index d688151..d1b220a 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * socket_sysfs.c -- most of socket-related sysfs output
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * (C) 2003 - 2004		Dominik Brodowski
  */
 
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 1e5fa21..177d778 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services.
  *
  * Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@linux-mips.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
 #include <linux/ioport.h>
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c
index b2a1895..b11c7ab 100644
--- a/drivers/pcmcia/xxs1500_ss.c
+++ b/drivers/pcmcia/xxs1500_ss.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * PCMCIA socket code for the MyCable XXS1500 system.
  *
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index ac6a3f4..810761a 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Regular cardbus driver ("yenta_socket")
  *