Subject: Re: linux-next: manual merge of the pcmcia tree with the arm tree

From: Dmitry Artamonow <[email-masked]>
Date: Sun, 6 Dec 2009 19:51:18 +0300

On 12:07 Sat 05 Dec     , Dominik Brodowski wrote:
> On Sat, Dec 05, 2009 at 10:30:38AM +0000, Russell King wrote:
> > Since Dominik has been ignoring this issue, and has already asked Linus to
> > pull his tree with my (unfortunately just discovered buggy) changes in, I'm
> > going to drop the H3600 PCMCIA changes until something can be sorted out.
> 
> Well, I hope that Linus merges the first bunch of PCMCIA changes soon, so
> that we have a clean base to work from and to sort the dependecies in
> ARM-related patches out.

Well, looks like PCMCIA changes hit Linus' tree already, so the only way
now is to rebase h3600 patches. Closer look show that only one patch in
series needs rebasing - this one:
  ARM: 5811/1: pcmcia: convert sa1100_h3600 driver to gpiolib

Russell, I submitted rebased version to your patch system as 5811/2
It also attached to this letter. Hope this would help to resolve issue.

-- 
Best regards,
Dmitry "MAD" Artamonow

>>From ce07b36a48f3b72d96f69c5138af3d0489ecd591 Mon Sep 17 00:00:00 2001
From: Dmitry Artamonow <[email-masked]>
Date: Wed, 14 Oct 2009 17:26:41 +0400
Subject: pcmcia: convert sa1100_h3600 driver to gpiolib

Convert all operations with GPLR/GPCR/GPSR to gpiolibs calls.
Also change all IRQ_GPIO* to gpio_to_irq(*GPIO*)

Signed-off-by: Dmitry Artamonow <[email-masked]>
---
 drivers/pcmcia/sa1100_h3600.c |   82 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 71 insertions(+), 11 deletions(-)

diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index 3a121ac..97e5667 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -10,26 +10,78 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <mach/h3600.h>
+#include <mach/h3600_gpio.h>
 
 #include "sa1100_generic.h"
 
 static struct pcmcia_irqs irqs[] = {
-	{ 0, IRQ_GPIO_H3600_PCMCIA_CD0, "PCMCIA CD0" },
-	{ 1, IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" }
+	{ .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
+	{ .sock = 1, .str = "PCMCIA CD1" }
 };
 
 static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
-				      : IRQ_GPIO_H3600_PCMCIA_IRQ0;
+	int err;
 
+	switch (skt->nr) {
+	case 0:
+		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0");
+		if (err)
+			goto err00;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0);
+		if (err)
+			goto err01;
+		skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
+
+		err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
+		if (err)
+			goto err01;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
+		if (err)
+			goto err02;
+		irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
+
+		err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+		if (err)
+			goto err02;
+		break;
+	case 1:
+		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1");
+		if (err)
+			goto err10;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1);
+		if (err)
+			goto err11;
+		skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
+
+		err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
+		if (err)
+			goto err11;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
+		if (err)
+			goto err12;
+		irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
+
+		err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+		if (err)
+			goto err12;
+		break;
+	}
+	return 0;
+
+err02:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+err01:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+err00:	return err;
 
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+err12:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+err11:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+err10:	return err;
 }
 
 static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
@@ -40,17 +92,25 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
 	assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
 	assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
+	switch (skt->nr) {
+	case 0:
+		gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+		gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+		break;
+	case 1:
+		gpio_free(H3XXX_GPIO_PCMCIA_CD1);
+		gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
+		break;
+	}
 }
 
 static void
 h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
-
 	switch (skt->nr) {
 	case 0:
-		state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
-		state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
+		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0);
+		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0);
 		state->bvd1 = 0;
 		state->bvd2 = 0;
 		state->wrprot = 0; /* Not available on H3600. */
@@ -59,8 +119,8 @@ h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *st
 		break;
 
 	case 1:
-		state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
-		state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
+		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
+		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
 		state->bvd1 = 0;
 		state->bvd2 = 0;
 		state->wrprot = 0; /* Not available on H3600. */
-- 
1.6.3.4