All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion
@ 2018-11-28 11:10 Russell King - ARM Linux
  2018-11-28 11:11 ` [PATCH 1/8] ARM: sa1100: explicitly register sa11x0-pcmcia devices Russell King
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Russell King - ARM Linux @ 2018-11-28 11:10 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds a generic MAX1600 library which uses the GPIOD
interfaces to control the PCMCIA power switches, and converts
some SA11x0/PXA drivers to it, reducing the code duplication.
This also allows us to kill the SA1111 private GPIO interfaces.

 arch/arm/common/sa1111.c                   |  59 --------------
 arch/arm/include/asm/hardware/sa1111.h     |   4 -
 arch/arm/mach-pxa/Kconfig                  |   1 +
 arch/arm/mach-pxa/include/mach/mainstone.h |   4 +
 arch/arm/mach-pxa/lubbock.c                |  16 ++++
 arch/arm/mach-pxa/mainstone.c              |  53 +++++++++++++
 arch/arm/mach-sa1100/generic.c             |  10 ---
 arch/arm/mach-sa1100/h3100.c               |   1 +
 arch/arm/mach-sa1100/jornada720.c          |  12 +++
 arch/arm/mach-sa1100/neponset.c            |  19 +++++
 drivers/pcmcia/Kconfig                     |   6 ++
 drivers/pcmcia/Makefile                    |   1 +
 drivers/pcmcia/max1600.c                   | 122 +++++++++++++++++++++++++++++
 drivers/pcmcia/max1600.h                   |  32 ++++++++
 drivers/pcmcia/pxa2xx_mainstone.c          | 113 ++++++++------------------
 drivers/pcmcia/sa1100_simpad.c             |   4 +-
 drivers/pcmcia/sa1111_jornada720.c         |  83 +++++++++++++-------
 drivers/pcmcia/sa1111_lubbock.c            | 110 +++++---------------------
 drivers/pcmcia/sa1111_neponset.c           |  79 +++++--------------
 19 files changed, 396 insertions(+), 333 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/8] ARM: sa1100: explicitly register sa11x0-pcmcia devices
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
@ 2018-11-28 11:11 ` Russell King
  2018-11-28 11:11 ` [PATCH 2/8] pcmcia: add MAX1600 library Russell King
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Russell King @ 2018-11-28 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

Simplify the code by getting rid of the conditional automatic
registration of the sa11x0 PCMCIA interfaces in sa1100_init(), and
require all platforms to explicitly call sa11x0_register_pcmcia().
Only one platform (iPAQ) is affected by this change.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/generic.c | 10 ----------
 arch/arm/mach-sa1100/h3100.c   |  1 +
 2 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 800321c6cbd8..755290bf658b 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -235,18 +235,11 @@ void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
 	sa11x0_register_device(&sa11x0fb_device, inf);
 }
 
-static bool sa11x0pcmcia_legacy = true;
-static struct platform_device sa11x0pcmcia_device = {
-	.name		= "sa11x0-pcmcia",
-	.id		= -1,
-};
-
 void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
 {
 	if (table)
 		gpiod_add_lookup_table(table);
 	platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
-	sa11x0pcmcia_legacy = false;
 }
 
 static struct platform_device sa11x0mtd_device = {
@@ -331,9 +324,6 @@ static int __init sa1100_init(void)
 {
 	pm_power_off = sa1100_power_off;
 
-	if (sa11x0pcmcia_legacy)
-		platform_device_register(&sa11x0pcmcia_device);
-
 	regulator_has_full_constraints();
 
 	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index c6b412054a3c..9dc5bcb7326b 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -126,6 +126,7 @@ static void __init h3100_mach_init(void)
 {
 	h3xxx_mach_init();
 
+	sa11x0_register_pcmcia(-1, NULL);
 	sa11x0_register_lcd(&h3100_lcd_info);
 	sa11x0_register_irda(&h3100_irda_data);
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/8] pcmcia: add MAX1600 library
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
  2018-11-28 11:11 ` [PATCH 1/8] ARM: sa1100: explicitly register sa11x0-pcmcia devices Russell King
@ 2018-11-28 11:11 ` Russell King
  2018-11-28 11:11 ` [PATCH 3/8] ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs Russell King
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Russell King @ 2018-11-28 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add a library for the MAX1600 PCMCIA power switch device.  This is a
dual-channel device, controlled via four GPIO signals per channel.
Two signals control the Vcc output, and two control the Vpp output.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/Kconfig   |   3 ++
 drivers/pcmcia/Makefile  |   1 +
 drivers/pcmcia/max1600.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pcmcia/max1600.h |  32 +++++++++++++
 4 files changed, 158 insertions(+)
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index cbbe4a285b48..1a257a323923 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -63,6 +63,9 @@ config CARDBUS
 
 	  If unsure, say Y.
 
+config PCMCIA_MAX1600
+	tristate
+
 comment "PC-card bridges"
 
 config YENTA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 28502bd159e0..01779c5c45f3 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_OMAP_CF)				+= omap_cf.o
 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/max1600.c b/drivers/pcmcia/max1600.c
new file mode 100644
index 000000000000..379875a5e7cd
--- /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 000000000000..00bf1a09464f
--- /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
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/8] ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
  2018-11-28 11:11 ` [PATCH 1/8] ARM: sa1100: explicitly register sa11x0-pcmcia devices Russell King
  2018-11-28 11:11 ` [PATCH 2/8] pcmcia: add MAX1600 library Russell King
@ 2018-11-28 11:11 ` Russell King
  2018-11-28 11:11 ` [PATCH 4/8] ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and " Russell King
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Russell King @ 2018-11-28 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the low level PCMCIA driver to gpiod APIs for controlling
the socket power.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/jornada720.c  | 12 ++++++
 drivers/pcmcia/sa1111_jornada720.c | 83 +++++++++++++++++++++++++-------------
 2 files changed, 67 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 0a2ca9be00e6..6298bad09ef3 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -190,6 +190,17 @@ static struct platform_device s1d13xxxfb_device = {
 	.resource	= s1d13xxxfb_resources,
 };
 
+static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
+	.dev_id = "1800",
+	.table = {
+		GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static struct resource sa1111_resources[] = {
 	[0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
 	[1] = DEFINE_RES_IRQ(IRQ_GPIO1),
@@ -265,6 +276,7 @@ static int __init jornada720_init(void)
 		udelay(20);		/* give it some time to restart */
 
 		gpiod_add_lookup_table(&jornada_ts_gpiod_table);
+		gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index 3d4ca87ca76c..1083e1b4f25d 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 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 	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 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 	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 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = {
 
 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);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/8] ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and gpiod APIs
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
                   ` (2 preceding siblings ...)
  2018-11-28 11:11 ` [PATCH 3/8] ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs Russell King
@ 2018-11-28 11:11 ` Russell King
  2018-11-28 11:11 ` [PATCH 5/8] ARM: pxa/mainstone: " Russell King
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Russell King @ 2018-11-28 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

Convert Neponset to use the gpiod API to specify which GPIOs are used
for PCMCIA, and use the MAX1600 power switch library for Neponset,
simplifying the neponset pcmcia driver as a result.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c  | 19 ++++++++++
 drivers/pcmcia/Kconfig           |  1 +
 drivers/pcmcia/sa1111_neponset.c | 79 +++++++++-------------------------------
 3 files changed, 38 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index b1823f445358..eb60a71cf125 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -5,6 +5,7 @@
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/gpio-reg.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -96,6 +97,19 @@ struct neponset_drvdata {
 	struct gpio_chip *gpio[4];
 };
 
+static struct gpiod_lookup_table neponset_pcmcia_table = {
+	.dev_id = "1800",
+	.table = {
+		GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static struct neponset_drvdata *nep;
 
 void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -374,6 +388,8 @@ static int neponset_probe(struct platform_device *dev)
 			   d->base + AUD_CTL, AUD_NGPIO, false,
 			   neponset_aud_names);
 
+	gpiod_add_lookup_table(&neponset_pcmcia_table);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -424,6 +440,9 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->sa1111);
 	if (!IS_ERR(d->smc91x))
 		platform_device_unregister(d->smc91x);
+
+	gpiod_remove_lookup_table(&neponset_pcmcia_table);
+
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
 	nep = NULL;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1a257a323923..8e8db3aa9fce 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -194,6 +194,7 @@ config PCMCIA_SA1111
 	select PCMCIA_SOC_COMMON
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
+	select PCMCIA_MAX1600 if ASSABET_NEPONSET
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index 0ccf05a28a4b..de0ce13355b4 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_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+	struct max1600 *m;
 	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;
+	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;
 
-	default:
-		return -1;
-	}
+	return ret;
+}
 
-	/*
-	 * 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;
-	}
+static int
+neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+	struct max1600 *m = skt->driver_data;
+	int ret;
 
 	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 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
 
 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);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/8] ARM: pxa/mainstone: switch PCMCIA to MAX1600 library and gpiod APIs
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
                   ` (3 preceding siblings ...)
  2018-11-28 11:11 ` [PATCH 4/8] ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and " Russell King
@ 2018-11-28 11:11 ` Russell King
  2018-11-29 17:32   ` Robert Jarzmik
  2018-11-28 11:12 ` [PATCH 6/8] ARM: pxa/lubbock: switch PCMCIA to MAX1600 library Russell King
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Russell King @ 2018-11-28 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

Convert mainstone to use the MAX1600 library and gpiod APIs for socket
status and control signals.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/Kconfig                  |   1 +
 arch/arm/mach-pxa/include/mach/mainstone.h |   4 +
 arch/arm/mach-pxa/mainstone.c              |  53 ++++++++++++++
 drivers/pcmcia/Kconfig                     |   1 +
 drivers/pcmcia/pxa2xx_mainstone.c          | 113 +++++++++--------------------
 5 files changed, 93 insertions(+), 79 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index a68b34183107..fd724a71c2e1 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -46,6 +46,7 @@ config ARCH_LUBBOCK
 
 config MACH_MAINSTONE
 	bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
+	select GPIO_REG
 	select PXA27x
 
 config MACH_ZYLONITE
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h
index e82a7d31104e..474041a83d80 100644
--- a/arch/arm/mach-pxa/include/mach/mainstone.h
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -119,6 +119,10 @@
 #define MST_PCMCIA_PWR_VCC_33   0x8	   /* voltage VCC = 3.3V */
 #define MST_PCMCIA_PWR_VCC_50   0x4	   /* voltage VCC = 5.0V */
 
+#define MST_PCMCIA_INPUTS \
+	(MST_PCMCIA_nIRQ | MST_PCMCIA_nSPKR_BVD2 | MST_PCMCIA_nSTSCHG_BVD1 | \
+	 MST_PCMCIA_nVS2 | MST_PCMCIA_nVS1 | MST_PCMCIA_nCD)
+
 /* board specific IRQs */
 #define MAINSTONE_NR_IRQS	IRQ_BOARD_START
 
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index afd62a94fdbf..d40de190d630 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -13,6 +13,7 @@
  *  published by the Free Software Foundation.
  */
 #include <linux/gpio.h>
+#include <linux/gpio/gpio-reg.h>
 #include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -507,12 +508,64 @@ static void __init mainstone_init_keypad(void)
 static inline void mainstone_init_keypad(void) {}
 #endif
 
+static int mst_pcmcia0_irqs[11] = {
+	[0 ... 10] = -1,
+	[5] = MAINSTONE_S0_CD_IRQ,
+	[8] = MAINSTONE_S0_STSCHG_IRQ,
+	[10] = MAINSTONE_S0_IRQ,
+};
+
+static int mst_pcmcia1_irqs[11] = {
+	[0 ... 10] = -1,
+	[5] = MAINSTONE_S1_CD_IRQ,
+	[8] = MAINSTONE_S1_STSCHG_IRQ,
+	[10] = MAINSTONE_S1_IRQ,
+};
+
+static struct gpiod_lookup_table mainstone_pcmcia_gpio_table = {
+	.dev_id = "pxa2xx-pcmcia",
+	.table = {
+		GPIO_LOOKUP("mst-pcmcia0",  0, "a0vpp",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0",  1, "a1vpp",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0",  2, "a0vcc",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0",  3, "a1vcc",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0",  4, "areset",  GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0",  5, "adetect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("mst-pcmcia0",  6, "avs1",    GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("mst-pcmcia0",  7, "avs2",    GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("mst-pcmcia0",  8, "abvd1",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0",  9, "abvd2",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia0", 10, "aready",  GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  0, "b0vpp",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  1, "b1vpp",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  2, "b0vcc",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  3, "b1vcc",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  4, "breset",  GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  5, "bdetect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("mst-pcmcia1",  6, "bvs1",    GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("mst-pcmcia1",  7, "bvs2",    GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("mst-pcmcia1",  8, "bbvd1",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1",  9, "bbvd2",   GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("mst-pcmcia1", 10, "bready",  GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void __init mainstone_init(void)
 {
 	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
 
+	/* Register board control register(s) as GPIOs */
+	gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0, -1, 11,
+		      "mst-pcmcia0", MST_PCMCIA_INPUTS, 0, NULL,
+		      NULL, mst_pcmcia0_irqs);
+	gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA1, -1, 11,
+		      "mst-pcmcia1", MST_PCMCIA_INPUTS, 0, NULL,
+		      NULL, mst_pcmcia1_irqs);
+	gpiod_add_lookup_table(&mainstone_pcmcia_gpio_table);
+
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 8e8db3aa9fce..9ac3d4a68075 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -211,6 +211,7 @@ config PCMCIA_PXA2XX
 		    || 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/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 = {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/8] ARM: pxa/lubbock: switch PCMCIA to MAX1600 library
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
                   ` (4 preceding siblings ...)
  2018-11-28 11:11 ` [PATCH 5/8] ARM: pxa/mainstone: " Russell King
@ 2018-11-28 11:12 ` Russell King
  2018-11-30 17:18   ` Robert Jarzmik
  2018-11-28 11:12 ` [PATCH 7/8] pcmcia: sa1100*: remove redundant bvd1/bvd2 setting Russell King
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Russell King @ 2018-11-28 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

As Lubbock now provides GPIOs via gpiolib for controlling the socket
power, we can use the MAX1600 driver.  Switch Lubbock to use this
driver, which simplifies the code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/lubbock.c     |  16 ++++++
 drivers/pcmcia/Kconfig          |   1 +
 drivers/pcmcia/sa1111_lubbock.c | 110 ++++++++--------------------------------
 3 files changed, 37 insertions(+), 90 deletions(-)

diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index fe2ef9b78602..8e24455facd8 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -136,10 +136,26 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
 	// no D+ pullup; lubbock can't connect/disconnect in software
 };
 
+/* GPIOs for SA1111 PCMCIA */
+static struct gpiod_lookup_table sa1111_pcmcia_gpio_table = {
+	.dev_id = "1800",
+	.table = {
+		{ "sa1111", 0, "a0vpp", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 1, "a1vpp", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 2, "a0vcc", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 3, "a1vcc", GPIO_ACTIVE_HIGH },
+		{ "lubbock", 14, "b0vcc", GPIO_ACTIVE_HIGH },
+		{ "lubbock", 15, "b1vcc", GPIO_ACTIVE_HIGH },
+		{ },
+	},
+};
+
 static void lubbock_init_pcmcia(void)
 {
 	struct clk *clk;
 
+	gpiod_add_lookup_table(&sa1111_pcmcia_gpio_table);
+
 	/* Add an alias for the SA1111 PCMCIA clock */
 	clk = clk_get_sys("pxa2xx-pcmcia", NULL);
 	if (!IS_ERR(clk)) {
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 9ac3d4a68075..d687a7640f6a 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -195,6 +195,7 @@ config PCMCIA_SA1111
 	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
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index e741f499c875..e3fc14cfb42b 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -24,20 +24,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 +82,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  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 +91,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 	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 +116,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 			/*
 			 * 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 +141,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 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 +151,6 @@ static struct pcmcia_low_level lubbock_pcmcia_ops = {
 
 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,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 7/8] pcmcia: sa1100*: remove redundant bvd1/bvd2 setting
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
                   ` (5 preceding siblings ...)
  2018-11-28 11:12 ` [PATCH 6/8] ARM: pxa/lubbock: switch PCMCIA to MAX1600 library Russell King
@ 2018-11-28 11:12 ` Russell King
  2018-11-28 11:12 ` [PATCH 8/8] ARM: sa1111: remove legacy GPIO interfaces Russell King
  2018-11-28 14:34 ` [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Dominik Brodowski
  8 siblings, 0 replies; 14+ messages in thread
From: Russell King @ 2018-11-28 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

bvd1 and bvd2 both default to 1 in the generic soc_common code, so
having a driver repeat this is redundant.  Remove it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_simpad.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index e235ee14eaa6..e2e8729afd9d 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -39,8 +39,8 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	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)) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 8/8] ARM: sa1111: remove legacy GPIO interfaces
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
                   ` (6 preceding siblings ...)
  2018-11-28 11:12 ` [PATCH 7/8] pcmcia: sa1100*: remove redundant bvd1/bvd2 setting Russell King
@ 2018-11-28 11:12 ` Russell King
  2018-11-28 14:34 ` [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Dominik Brodowski
  8 siblings, 0 replies; 14+ messages in thread
From: Russell King @ 2018-11-28 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have migrated all users of the legacy private SA1111 gpio
interfaces, we can remove these redundant GPIO interfaces.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/common/sa1111.c               | 59 ----------------------------------
 arch/arm/include/asm/hardware/sa1111.h |  4 ---
 2 files changed, 63 deletions(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a2c878769eaf..45412d21aa6b 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1282,65 +1282,6 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
 }
 EXPORT_SYMBOL(sa1111_get_audio_rate);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev,
-		       unsigned int bits, unsigned int dir,
-		       unsigned int sleep_dir)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-#define MODIFY_BITS(port, mask, dir)		\
-	if (mask) {				\
-		val = readl_relaxed(port);	\
-		val &= ~(mask);			\
-		val |= (dir) & (mask);		\
-		writel_relaxed(val, port);	\
-	}
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16);
-
-	MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io_dir);
-
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io);
-
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_sleep_io);
-
 /*
  * Individual device operations.
  */
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 798e520e8a49..d134b9a5ff94 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -433,10 +433,6 @@ int sa1111_check_dma_bug(dma_addr_t addr);
 int sa1111_driver_register(struct sa1111_driver *);
 void sa1111_driver_unregister(struct sa1111_driver *);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir);
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-
 struct sa1111_platform_data {
 	int	irq_base;	/* base for cascaded on-chip IRQs */
 	unsigned disable_devs;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion
  2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
                   ` (7 preceding siblings ...)
  2018-11-28 11:12 ` [PATCH 8/8] ARM: sa1111: remove legacy GPIO interfaces Russell King
@ 2018-11-28 14:34 ` Dominik Brodowski
  8 siblings, 0 replies; 14+ messages in thread
From: Dominik Brodowski @ 2018-11-28 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 28, 2018 at 11:10:41AM +0000, Russell King - ARM Linux wrote:
> This series adds a generic MAX1600 library which uses the GPIOD
> interfaces to control the PCMCIA power switches, and converts
> some SA11x0/PXA drivers to it, reducing the code duplication.
> This also allows us to kill the SA1111 private GPIO interfaces.

As I'll presume you'll push this upstream via arm, you may add my

	Acked-by: Dominik Brodowski <linux@dominikbrodowski.net>

in relation to the PCMCIA-related changes.

Thanks,
	Dominik

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/8] ARM: pxa/mainstone: switch PCMCIA to MAX1600 library and gpiod APIs
  2018-11-28 11:11 ` [PATCH 5/8] ARM: pxa/mainstone: " Russell King
@ 2018-11-29 17:32   ` Robert Jarzmik
  2018-11-29 17:42     ` Russell King - ARM Linux
  0 siblings, 1 reply; 14+ messages in thread
From: Robert Jarzmik @ 2018-11-29 17:32 UTC (permalink / raw)
  To: Russell King
  Cc: Haojian Zhuang, Kristoffer Ericson, Dominik Brodowski,
	Daniel Mack, linux-arm-kernel

Russell King <rmk+kernel@armlinux.org.uk> writes:

Hi Russell,

I reviewed the code, and I didn't quite understand this chunk :
> @@ -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);
>  	}

In the former code, the enable_irq() and disable_irq() were called with the same
interrupt number. But with the new code, if I understand it correctly, the irq
is different. As I don't fully grasp this chunk, I'll pinpoint it so that you
can have a second look.

I'll try to have a live test, but as PCMCIA is not working on my mainstone board
(ie. kernel side regression I'm trying to catch), I might not be able to test it
properly.

Cheers.

-- 
Robert

PS: The "regression" I'm talking about, which is there before your changes and
after them as well, is in the exact same area, so I'll leave you the backtrace
of linux-master (without your patches) for information (but not analysis,
spare your free time) :

------------[ cut here ]------------
WARNING: CPU: 0 PID: 114 at kernel/irq/manage.c:559 enable_irq+0x34/0x6c
Unbalanced enable for IRQ 314
Modules linked in: pxa2xx_mainstone(+) pxa2xx_base soc_common
CPU: 0 PID: 114 Comm: modprobe Not tainted 4.20.0-rc4-00098-g60b5482 #2931
Hardware name: Intel HCDDBBVA0 Development Platform (aka Mainstone)
[<c00101ac>] (unwind_backtrace) from [<c000db80>] (show_stack+0x10/0x14)
[<c000db80>] (show_stack) from [<c0019e38>] (__warn+0xe4/0x10c)
[<c0019e38>] (__warn) from [<c0019e98>] (warn_slowpath_fmt+0x38/0x48)
[<c0019e98>] (warn_slowpath_fmt) from [<c0051ff8>] (enable_irq+0x34/0x6c)
[<c0051ff8>] (enable_irq) from [<bf00a140>] (mst_pcmcia_socket_state+0x5c/0xe4 [pxa2xx_mainstone])
[<bf00a140>] (mst_pcmcia_socket_state [pxa2xx_mainstone]) from [<bf0007e8>] (soc_common_pcmcia_skt_state+0x134/0x1d0 [soc_common])
[<bf0007e8>] (soc_common_pcmcia_skt_state [soc_common]) from [<bf000b00>] (soc_pcmcia_add_one+0x27c/0x374 [soc_common])
[<bf000b00>] (soc_pcmcia_add_one [soc_common]) from [<bf0063e4>] (pxa2xx_drv_pcmcia_probe+0xbc/0x138 [pxa2xx_base])
[<bf0063e4>] (pxa2xx_drv_pcmcia_probe [pxa2xx_base]) from [<c0267128>] (platform_drv_probe+0x30/0x80)
[<c0267128>] (platform_drv_probe) from [<c026507c>] (really_probe+0x1e4/0x404)
[<c026507c>] (really_probe) from [<c0265450>] (driver_probe_device+0x74/0x1c0)
[<c0265450>] (driver_probe_device) from [<c0263174>] (bus_for_each_drv+0x5c/0x8c)
[<c0263174>] (bus_for_each_drv) from [<c0264dfc>] (__device_attach+0xac/0x140)
[<c0264dfc>] (__device_attach) from [<c02640f8>] (bus_probe_device+0x84/0x90)
[<c02640f8>] (bus_probe_device) from [<c0261ee0>] (device_add+0x3e8/0x5e4)
[<c0261ee0>] (device_add) from [<c0266e34>] (platform_device_add+0xbc/0x250)
[<c0266e34>] (platform_device_add) from [<bf00c040>] (mst_pcmcia_init+0x40/0xc0 [pxa2xx_mainstone])
[<bf00c040>] (mst_pcmcia_init [pxa2xx_mainstone]) from [<c000a640>] (do_one_initcall+0x48/0x1ac)
[<c000a640>] (do_one_initcall) from [<c00790c4>] (do_init_module+0x58/0x2fc)
[<c00790c4>] (do_init_module) from [<c0077eb4>] (load_module+0x1adc/0x2080)
[<c0077eb4>] (load_module) from [<c007855c>] (sys_init_module+0x104/0x16c)
[<c007855c>] (sys_init_module) from [<c0009000>] (ret_fast_syscall+0x0/0x50)
Exception stack(0xc294dfa8 to 0xc294dff0)
dfa0:                   000b86c8 000b85d0 000b96e8 0000155c 000b85d0 00000000
dfc0: 000b86c8 000b85d0 000b96e8 00000080 000b86c8 00000000 000b78bc 000b9600
dfe0: b6f7b1bc bea76b7c 0001ca3c b6f7b1cc
---[ end trace 36648ae9205933e8 ]---
------------[ cut here ]------------
WARNING: CPU: 0 PID: 114 at kernel/irq/manage.c:559 enable_irq+0x34/0x6c
Unbalanced enable for IRQ 318
Modules linked in: pxa2xx_mainstone(+) pxa2xx_base soc_common
CPU: 0 PID: 114 Comm: modprobe Tainted: G        W         4.20.0-rc4-00098-g60b5482 #2931
Hardware name: Intel HCDDBBVA0 Development Platform (aka Mainstone)
[<c00101ac>] (unwind_backtrace) from [<c000db80>] (show_stack+0x10/0x14)
[<c000db80>] (show_stack) from [<c0019e38>] (__warn+0xe4/0x10c)
[<c0019e38>] (__warn) from [<c0019e98>] (warn_slowpath_fmt+0x38/0x48)
[<c0019e98>] (warn_slowpath_fmt) from [<c0051ff8>] (enable_irq+0x34/0x6c)
[<c0051ff8>] (enable_irq) from [<bf00a140>] (mst_pcmcia_socket_state+0x5c/0xe4 [pxa2xx_mainstone])
[<bf00a140>] (mst_pcmcia_socket_state [pxa2xx_mainstone]) from [<bf0007e8>] (soc_common_pcmcia_skt_state+0x134/0x1d0 [soc_common])
[<bf0007e8>] (soc_common_pcmcia_skt_state [soc_common]) from [<bf000b00>] (soc_pcmcia_add_one+0x27c/0x374 [soc_common])
[<bf000b00>] (soc_pcmcia_add_one [soc_common]) from [<bf0063e4>] (pxa2xx_drv_pcmcia_probe+0xbc/0x138 [pxa2xx_base])
[<bf0063e4>] (pxa2xx_drv_pcmcia_probe [pxa2xx_base]) from [<c0267128>] (platform_drv_probe+0x30/0x80)
[<c0267128>] (platform_drv_probe) from [<c026507c>] (really_probe+0x1e4/0x404)
[<c026507c>] (really_probe) from [<c0265450>] (driver_probe_device+0x74/0x1c0)
[<c0265450>] (driver_probe_device) from [<c0263174>] (bus_for_each_drv+0x5c/0x8c)
[<c0263174>] (bus_for_each_drv) from [<c0264dfc>] (__device_attach+0xac/0x140)
[<c0264dfc>] (__device_attach) from [<c02640f8>] (bus_probe_device+0x84/0x90)
[<c02640f8>] (bus_probe_device) from [<c0261ee0>] (device_add+0x3e8/0x5e4)
[<c0261ee0>] (device_add) from [<c0266e34>] (platform_device_add+0xbc/0x250)
[<c0266e34>] (platform_device_add) from [<bf00c040>] (mst_pcmcia_init+0x40/0xc0 [pxa2xx_mainstone])
[<bf00c040>] (mst_pcmcia_init [pxa2xx_mainstone]) from [<c000a640>] (do_one_initcall+0x48/0x1ac)
[<c000a640>] (do_one_initcall) from [<c00790c4>] (do_init_module+0x58/0x2fc)
[<c00790c4>] (do_init_module) from [<c0077eb4>] (load_module+0x1adc/0x2080)
[<c0077eb4>] (load_module) from [<c007855c>] (sys_init_module+0x104/0x16c)
[<c007855c>] (sys_init_module) from [<c0009000>] (ret_fast_syscall+0x0/0x50)
Exception stack(0xc294dfa8 to 0xc294dff0)
dfa0:                   000b86c8 000b85d0 000b96e8 0000155c 000b85d0 00000000
dfc0: 000b86c8 000b85d0 000b96e8 00000080 000b86c8 00000000 000b78bc 000b9600
dfe0: b6f7b1bc bea76b7c 0001ca3c b6f7b1cc
---[ end trace 36648ae9205933e9 ]---

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/8] ARM: pxa/mainstone: switch PCMCIA to MAX1600 library and gpiod APIs
  2018-11-29 17:32   ` Robert Jarzmik
@ 2018-11-29 17:42     ` Russell King - ARM Linux
  2018-11-30 17:21       ` Robert Jarzmik
  0 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2018-11-29 17:42 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Kristoffer Ericson, Dominik Brodowski,
	Daniel Mack, linux-arm-kernel

On Thu, Nov 29, 2018 at 06:32:02PM +0100, Robert Jarzmik wrote:
> Russell King <rmk+kernel@armlinux.org.uk> writes:
> 
> Hi Russell,
> 
> I reviewed the code, and I didn't quite understand this chunk :
> > @@ -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);
> >  	}
> 
> In the former code, the enable_irq() and disable_irq() were called with the same
> interrupt number. But with the new code, if I understand it correctly, the irq
> is different. As I don't fully grasp this chunk, I'll pinpoint it so that you
> can have a second look.

Good catch, that's supposed to be SOC_STAT_BVD1 not SOC_STAT_BVD2 there.

> PS: The "regression" I'm talking about, which is there before your changes and
> after them as well, is in the exact same area, so I'll leave you the backtrace
> of linux-master (without your patches) for information (but not analysis,
> spare your free time) :
> 
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 114 at kernel/irq/manage.c:559 enable_irq+0x34/0x6c
> Unbalanced enable for IRQ 314
> Modules linked in: pxa2xx_mainstone(+) pxa2xx_base soc_common
> CPU: 0 PID: 114 Comm: modprobe Not tainted 4.20.0-rc4-00098-g60b5482 #2931
> Hardware name: Intel HCDDBBVA0 Development Platform (aka Mainstone)
> [<c00101ac>] (unwind_backtrace) from [<c000db80>] (show_stack+0x10/0x14)
> [<c000db80>] (show_stack) from [<c0019e38>] (__warn+0xe4/0x10c)
> [<c0019e38>] (__warn) from [<c0019e98>] (warn_slowpath_fmt+0x38/0x48)
> [<c0019e98>] (warn_slowpath_fmt) from [<c0051ff8>] (enable_irq+0x34/0x6c)
> [<c0051ff8>] (enable_irq) from [<bf00a140>] (mst_pcmcia_socket_state+0x5c/0xe4 [pxa2xx_mainstone])
> [<bf00a140>] (mst_pcmcia_socket_state [pxa2xx_mainstone]) from [<bf0007e8>] (soc_common_pcmcia_skt_state+0x134/0x1d0 [soc_common])
> [<bf0007e8>] (soc_common_pcmcia_skt_state [soc_common]) from [<bf000b00>] (soc_pcmcia_add_one+0x27c/0x374 [soc_common])
> [<bf000b00>] (soc_pcmcia_add_one [soc_common]) from [<bf0063e4>] (pxa2xx_drv_pcmcia_probe+0xbc/0x138 [pxa2xx_base])
> [<bf0063e4>] (pxa2xx_drv_pcmcia_probe [pxa2xx_base]) from [<c0267128>] (platform_drv_probe+0x30/0x80)
> [<c0267128>] (platform_drv_probe) from [<c026507c>] (really_probe+0x1e4/0x404)
> [<c026507c>] (really_probe) from [<c0265450>] (driver_probe_device+0x74/0x1c0)
> [<c0265450>] (driver_probe_device) from [<c0263174>] (bus_for_each_drv+0x5c/0x8c)
> [<c0263174>] (bus_for_each_drv) from [<c0264dfc>] (__device_attach+0xac/0x140)
> [<c0264dfc>] (__device_attach) from [<c02640f8>] (bus_probe_device+0x84/0x90)
> [<c02640f8>] (bus_probe_device) from [<c0261ee0>] (device_add+0x3e8/0x5e4)
> [<c0261ee0>] (device_add) from [<c0266e34>] (platform_device_add+0xbc/0x250)
> [<c0266e34>] (platform_device_add) from [<bf00c040>] (mst_pcmcia_init+0x40/0xc0 [pxa2xx_mainstone])
> [<bf00c040>] (mst_pcmcia_init [pxa2xx_mainstone]) from [<c000a640>] (do_one_initcall+0x48/0x1ac)
> [<c000a640>] (do_one_initcall) from [<c00790c4>] (do_init_module+0x58/0x2fc)
> [<c00790c4>] (do_init_module) from [<c0077eb4>] (load_module+0x1adc/0x2080)
> [<c0077eb4>] (load_module) from [<c007855c>] (sys_init_module+0x104/0x16c)
> [<c007855c>] (sys_init_module) from [<c0009000>] (ret_fast_syscall+0x0/0x50)
> Exception stack(0xc294dfa8 to 0xc294dff0)
> dfa0:                   000b86c8 000b85d0 000b96e8 0000155c 000b85d0 00000000
> dfc0: 000b86c8 000b85d0 000b96e8 00000080 000b86c8 00000000 000b78bc 000b9600
> dfe0: b6f7b1bc bea76b7c 0001ca3c b6f7b1cc
> ---[ end trace 36648ae9205933e8 ]---

Please try initialising mst_pcmcia_bvd1_status[] to 1.

Thanks for testing.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 6/8] ARM: pxa/lubbock: switch PCMCIA to MAX1600 library
  2018-11-28 11:12 ` [PATCH 6/8] ARM: pxa/lubbock: switch PCMCIA to MAX1600 library Russell King
@ 2018-11-30 17:18   ` Robert Jarzmik
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2018-11-30 17:18 UTC (permalink / raw)
  To: Russell King
  Cc: Haojian Zhuang, Kristoffer Ericson, Dominik Brodowski,
	Daniel Mack, linux-arm-kernel

Russell King <rmk+kernel@armlinux.org.uk> writes:

> As Lubbock now provides GPIOs via gpiolib for controlling the socket
> power, we can use the MAX1600 driver.  Switch Lubbock to use this
> driver, which simplifies the code.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>

The test is only a read of the CIS of a PCCard in the PCMCIA slot, not actual
access to the storage.

Cheers.

--
Robert

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/8] ARM: pxa/mainstone: switch PCMCIA to MAX1600 library and gpiod APIs
  2018-11-29 17:42     ` Russell King - ARM Linux
@ 2018-11-30 17:21       ` Robert Jarzmik
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2018-11-30 17:21 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Haojian Zhuang, Kristoffer Ericson, Dominik Brodowski,
	Daniel Mack, linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> Please try initialising mst_pcmcia_bvd1_status[] to 1.
Indeed, that removes the warning.

With the fix to the interrupt thing, please have my :
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

> Thanks for testing.
That was rather done on the Lubbock side in the following patch, but I hope
that's a good enough health sign for the serie.

Cheers.

-- 
Robert

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-11-30 17:22 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-28 11:10 [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Russell King - ARM Linux
2018-11-28 11:11 ` [PATCH 1/8] ARM: sa1100: explicitly register sa11x0-pcmcia devices Russell King
2018-11-28 11:11 ` [PATCH 2/8] pcmcia: add MAX1600 library Russell King
2018-11-28 11:11 ` [PATCH 3/8] ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs Russell King
2018-11-28 11:11 ` [PATCH 4/8] ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and " Russell King
2018-11-28 11:11 ` [PATCH 5/8] ARM: pxa/mainstone: " Russell King
2018-11-29 17:32   ` Robert Jarzmik
2018-11-29 17:42     ` Russell King - ARM Linux
2018-11-30 17:21       ` Robert Jarzmik
2018-11-28 11:12 ` [PATCH 6/8] ARM: pxa/lubbock: switch PCMCIA to MAX1600 library Russell King
2018-11-30 17:18   ` Robert Jarzmik
2018-11-28 11:12 ` [PATCH 7/8] pcmcia: sa1100*: remove redundant bvd1/bvd2 setting Russell King
2018-11-28 11:12 ` [PATCH 8/8] ARM: sa1111: remove legacy GPIO interfaces Russell King
2018-11-28 14:34 ` [PATCH 0/8] SA11xx PCMCIA updates and GPIOD conversion Dominik Brodowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.