[RFC PATCH 1/2] PCMCIA: Add soc_common support for banked SoC drivers.

Martin Fuzzey mfuzzey at gmail.com
Tue Oct 27 13:26:57 EDT 2009


Some SoCs (like freescale MXC) require configuring a device register
to set the bank mapped into the memory window.

Also allow interrupt flags to be configured (to support shared interrupts).

Signed-off-by: Martin Fuzzey <mfuzzey at gmail.com>

---

 drivers/pcmcia/soc_common.c |   21 +++++++++++++++------
 drivers/pcmcia/soc_common.h |    7 +++++++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 163cf98..c06440c 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -257,7 +257,8 @@ static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev)
 	struct soc_pcmcia_socket *skt = dev;
 
 	debug(skt, 3, "servicing IRQ %d\n", irq);
-
+	if (skt->ops->ack_interrupt)
+		skt->ops->ack_interrupt(skt);
 	soc_common_check_status(skt);
 
 	return IRQ_HANDLED;
@@ -335,6 +336,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
 {
 	struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
 	unsigned short speed = map->speed;
+	int ret = 0;
 
 	debug(skt, 2, "map %u  speed %u start 0x%08x stop 0x%08x\n",
 		map->map, map->speed, map->start, map->stop);
@@ -367,11 +369,14 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
 	if (map->stop == 1)
 		map->stop = PAGE_SIZE-1;
 
+	if (skt->ops->set_io_map)
+		ret = skt->ops->set_io_map(skt, map);
+
 	map->stop -= map->start;
 	map->stop += skt->socket.io_offset;
 	map->start = skt->socket.io_offset;
 
-	return 0;
+	return ret;
 }
 
 
@@ -389,6 +394,7 @@ soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map
 	struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
 	struct resource *res;
 	unsigned short speed = map->speed;
+	int ret = 0;
 
 	debug(skt, 2, "map %u speed %u card_start %08x\n",
 		map->map, map->speed, map->card_start);
@@ -423,10 +429,12 @@ soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map
 	}
 
 	skt->ops->set_timing(skt);
+	if (skt->ops->set_mem_map)
+		ret = skt->ops->set_mem_map(skt, map);
+	else
+		map->static_start = res->start + map->card_start;
 
-	map->static_start = res->start + map->card_start;
-
-	return 0;
+	return ret;
 }
 
 struct bittbl {
@@ -519,7 +527,8 @@ int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
 		if (irqs[i].sock != skt->nr)
 			continue;
 		res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
-				  IRQF_DISABLED, irqs[i].str, skt);
+				  IRQF_DISABLED | irqs[i].flags,
+				  irqs[i].str, skt);
 		if (res)
 			break;
 		set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 290e143..9076003 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -113,6 +113,12 @@ struct pcmcia_low_level {
 	 */
 	int (*frequency_change)(struct soc_pcmcia_socket *, unsigned long, struct cpufreq_freqs *);
 #endif
+	void (*ack_interrupt)(struct soc_pcmcia_socket *);
+
+	/* Hardware specific mapping */
+	int (*set_mem_map)(struct soc_pcmcia_socket *, struct pccard_mem_map *);
+	int (*set_io_map)(struct soc_pcmcia_socket *, struct pccard_io_map *map);
+
 };
 
 
@@ -120,6 +126,7 @@ struct pcmcia_irqs {
 	int sock;
 	int irq;
 	const char *str;
+	unsigned long flags;
 };
 
 struct soc_pcmcia_timing {




More information about the linux-arm-kernel mailing list