Skip to contentSkip to conversation

arm: davinci: DA850: wl12xx expansion card

PATCH Superseded Ido Yariv 8 participants 34 messages Jul 10, 2011 – Sep 1, 2011

Subsystems (4)
lore
Share & tools
lore

Ido Yariv

author
#0 lore raw

v2 cover arm: davinci: DA850: wl12xx expansion card

The following series adds support for an optional wl12xx based expansion card for the AM18x EVM:
http://processors.wiki.ti.com/index.php/AM18x_%2B_WL1271

The first couple of patches address issues which had to be fixed for this series to work. However, these should be fixed regardless of the wl12xx daughter board support.

Only the Wi-Fi functionality of the expansion card is supported. Bluetooth functionality is not yet supported.

The patches are based on v3.0-rc6.

Changes from v1:
* Explicitly set the default queue for all channel controllers on all platforms. As it makes little sense to set DA850's default queue to an invalid value and then fix it, merge the two patches
* Move pinmux configurations to separate patches
* Remove FREF Kconfig entry, use a default value of 38MHz instead
* Use msleep for long delays, usleep_range for shorter ones
* Minor cleanups

Ido.

Ido Yariv (6):
arm: davinci: Fix low level gpio irq handlers' argument
arm: davinci: Explicitly set channel controllers' default queues
arm: davinci: mmc: Add support for set_power callback
arm: davinci: DA850: Add MMC/SD1 pinmux configuration
arm: davinci: DA850: Add GPIO pinmux configuration for wl1271
arm: davinci: DA850: Add wl1271/wlan support

 arch/arm/mach-davinci/Kconfig             |   10 +++
 arch/arm/mach-davinci/board-da850-evm.c   |  127 +++++++++++++++++++++++++++++
 arch/arm/mach-davinci/da850.c             |    9 ++
 arch/arm/mach-davinci/devices-da8xx.c     |    3 +
 arch/arm/mach-davinci/devices-tnetv107x.c |    1 +
 arch/arm/mach-davinci/dm355.c             |    1 +
 arch/arm/mach-davinci/dm644x.c            |    1 +
 arch/arm/mach-davinci/dm646x.c            |    1 +
 arch/arm/mach-davinci/dma.c               |    2 -
 arch/arm/mach-davinci/gpio.c              |   32 +++++++-
 arch/arm/mach-davinci/include/mach/mmc.h  |    3 +
 arch/arm/mach-davinci/include/mach/mux.h  |   10 +++
 drivers/mmc/host/davinci_mmc.c            |   13 +++
 13 files changed, 207 insertions(+), 6 deletions(-)
Signature · 1 line
1.7.4.1
author
#1 lore raw

PATCH v2 1/6 arm: davinci: Fix low level gpio irq handlers' argument

Commit 7416401 ("arm: davinci: Fix fallout from generic irq chip conversion") introduced a bug, causing low level interrupt handlers to get a bogus irq number as an argument. The gpio irq handler falsely assumes that the handler data is the irq base number and that is no longer true.

Fix this by converting gpio_irq_handler's bank_irq argument to the corresponding irq base number.

CC Thomas Gleixner <[email protected]>
---
 arch/arm/mach-davinci/gpio.c |   32 ++++++++++++++++++++++++++++----
 1 files changed, 28 insertions(+), 4 deletions(-)
arch/arm/mach-davinci/gpio.c +28 -4
index e722139..ff43e2a 100644
@@ -249,16 +249,40 @@ static struct irq_chip gpio_irqchip = {
 	.flags		= IRQCHIP_SET_TYPE_MASKED,
 };
 
+static inline int bankirq_to_irqbase(unsigned int bank_irq)
+{
+	int gpio;
+	int index;
+
+	/* Each irq bank consists of up to 16 irqs */
+	gpio = 16 * (bank_irq - davinci_soc_info.gpio_irq);
+
+	/* Each controller controls 32 GPIOs */
+	index = gpio / 32;
+
+	if (unlikely(!davinci_soc_info.gpio_ctlrs))
+		return -EINVAL;
+
+	if (unlikely(index >= davinci_soc_info.gpio_ctlrs_num))
+		return -EINVAL;
+
+	return davinci_soc_info.gpio_ctlrs[index].irq_base;
+}
+
 static void
-gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+gpio_irq_handler(unsigned bank_irq, struct irq_desc *desc)
 {
 	struct davinci_gpio_regs __iomem *g;
 	u32 mask = 0xffff;
+	int irqbase = bankirq_to_irqbase(bank_irq);
+
+	if (unlikely(irqbase < 0))
+		return;
 
 	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
 
 	/* we only care about one bank */
-	if (irq & 1)
+	if (bank_irq & 1)
 		mask <<= 16;
 
 	/* temporarily mask (level sensitive) parent IRQ */
@@ -274,11 +298,11 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		if (!status)
 			break;
 		__raw_writel(status, &g->intstat);
-		if (irq & 1)
+		if (bank_irq & 1)
 			status >>= 16;
 
 		/* now demux them to the right lowlevel handler */
-		n = (int)irq_get_handler_data(irq);
+		n = irqbase;
 		while (status) {
 			res = ffs(status);
 			n += res;
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v2 1/6 arm: davinci: Fix low level gpio irq handlers' argument

Hi Ido,

Quoted 66 lines · Ido Yariv

Commit 7416401 ("arm: davinci: Fix fallout from generic irq chip conversion") introduced a bug, causing low level interrupt handlers to get a bogus irq number as an argument. The gpio irq handler falsely assumes that the handler data is the irq base number and that is no longer true.

Fix this by converting gpio_irq_handler's bank_irq argument to the corresponding irq base number.

CC Thomas Gleixner <[email protected]>
---
 arch/arm/mach-davinci/gpio.c |   32 ++++++++++++++++++++++++++++----
 1 files changed, 28 insertions(+), 4 deletions(-)
arch/arm/mach-davinci/gpio.c +26 -2
index e722139..ff43e2a 100644
@@ -249,16 +249,40 @@ static struct irq_chip gpio_irqchip = {
 	.flags		= IRQCHIP_SET_TYPE_MASKED,
 };
 
+static inline int bankirq_to_irqbase(unsigned int bank_irq)
+{
+	int gpio;
+	int index;
+
+	/* Each irq bank consists of up to 16 irqs */
+	gpio = 16 * (bank_irq - davinci_soc_info.gpio_irq);
+
+	/* Each controller controls 32 GPIOs */
+	index = gpio / 32;
+
+	if (unlikely(!davinci_soc_info.gpio_ctlrs))
+		return -EINVAL;
+
+	if (unlikely(index >= davinci_soc_info.gpio_ctlrs_num))
+		return -EINVAL;
+
+	return davinci_soc_info.gpio_ctlrs[index].irq_base;
+}
+
 static void
-gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+gpio_irq_handler(unsigned bank_irq, struct irq_desc *desc)
 {
 	struct davinci_gpio_regs __iomem *g;
 	u32 mask = 0xffff;
+	int irqbase = bankirq_to_irqbase(bank_irq);
+
+	if (unlikely(irqbase < 0))
+		return;
 
 	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
 
 	/* we only care about one bank */
-	if (irq & 1)
+	if (bank_irq & 1)
 		mask <<= 16;
 
 	/* temporarily mask (level sensitive) parent IRQ */
@@ -274,11 +298,11 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		if (!status)
 			break;
 		__raw_writel(status, &g->intstat);

arch/arm/mach-davinci/gpio.c gpio_irq_handler(unsigned irq, struct irq_desc *desc) · line 308

Quoted 10 lines
arch/arm/mach-davinci/gpio.c +2 -2
-		if (irq & 1)
+		if (bank_irq & 1)
 			status >>= 16;
 
 		/* now demux them to the right lowlevel handler */
-		n = (int)irq_get_handler_data(irq);
+		n = irqbase;
 		while (status) {
 			res = ffs(status);
 			n += res;

Thanks for the bug fix.

How about setting the handler data for bank IRQ in davinci_gpio_irq_setup() to &chips[bank]?

chips[bank].regs should give you the register base address
(g) and chips[bank].irq_base should give you 'n'.

Also please drop the rename of irq to bank_irq as it is not central to the bug fix.

If you spin in soon enough, we may make it to v3.0

Thanks,
Sekhar

author
#3 lore raw

PATCH v2 1/6 arm: davinci: Fix low level gpio irq handlers' argument

Hi Sekhar,

Quoted 5 lines · Sekhar

Thanks for the bug fix.

How about setting the handler data for bank IRQ in davinci_gpio_irq_setup() to &chips[bank]?

Quoted 7 lines

chips[bank].regs should give you the register base address
(g) and chips[bank].irq_base should give you 'n'.

Also please drop the rename of irq to bank_irq as it is not central to the bug fix.

If you spin in soon enough, we may make it to v3.0

Sure, I'll send a v3 in a few.

Thanks for the review,
Ido.

author
#4 lore raw

PATCH v3 1/6 arm: davinci: Fix low level gpio irq handlers' argument

In reply to Nori, Sekhar

Commit 7416401 ("arm: davinci: Fix fallout from generic irq chip conversion") introduced a bug, causing low level interrupt handlers to get a bogus irq number as an argument. The gpio irq handler falsely assumes that the handler data is the irq base number and that is no longer true.

Set the irq handler data to be a pointer to the corresponding gpio controller. The chained irq handler can then use it to extract both the irq base number and the gpio registers structure.

CC Thomas Gleixner <[email protected]>
---
 arch/arm/mach-davinci/gpio.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)
arch/arm/mach-davinci/gpio.c +11 -3
index e722139..7d64a07 100644
@@ -254,8 +254,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
 	struct davinci_gpio_regs __iomem *g;
 	u32 mask = 0xffff;
+	struct davinci_gpio_controller *ctl;
 
-	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
+	ctl = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
+	g = (struct davinci_gpio_regs __iomem *)ctl->regs;
 
 	/* we only care about one bank */
 	if (irq & 1)
@@ -278,7 +280,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			status >>= 16;
 
 		/* now demux them to the right lowlevel handler */
-		n = (int)irq_get_handler_data(irq);
+		n = ctl->irq_base;
 		while (status) {
 			res = ffs(status);
 			n += res;
@@ -424,7 +426,13 @@ static int __init davinci_gpio_irq_setup(void)
 
 		/* set up all irqs in this bank */
 		irq_set_chained_handler(bank_irq, gpio_irq_handler);
-		irq_set_handler_data(bank_irq, (__force void *)g);
+
+		/*
+		 * Each chip handles 32 gpios, and each irq bank consists of 16
+		 * gpio irqs. Pass the irq bank's corresponding controller to
+		 * the chained irq handler.
+		 */
+		irq_set_handler_data(bank_irq, &chips[bank * 16 / 32]);
 
 		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
 			irq_set_chip(irq, &gpio_irqchip);
Signature · 1 line
1.7.4.1
#5 lore raw

PATCH v3 1/6 arm: davinci: Fix low level gpio irq handlers' argument

Hi Ido,

Quoted 21 lines · Ido Yariv

Commit 7416401 ("arm: davinci: Fix fallout from generic irq chip conversion") introduced a bug, causing low level interrupt handlers to get a bogus irq number as an argument. The gpio irq handler falsely assumes that the handler data is the irq base number and that is no longer true.

Set the irq handler data to be a pointer to the corresponding gpio controller. The chained irq handler can then use it to extract both the irq base number and the gpio registers structure.

CC Thomas Gleixner <[email protected]>
---
 arch/arm/mach-davinci/gpio.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)
arch/arm/mach-davinci/gpio.c +0 -0
index e722139..7d64a07 100644

arch/arm/mach-davinci/gpio.c gpio_irq_handler(unsigned irq, struct irq_desc *desc) · line 257

Quoted 4 lines
arch/arm/mach-davinci/gpio.c +1 -0
@@ -254,8 +254,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
 	struct davinci_gpio_regs __iomem *g;
 	u32 mask = 0xffff;
+	struct davinci_gpio_controller *ctl;

Lets call the variable "d" to be consistent with the rest of the file.

arch/arm/mach-davinci/gpio.c gpio_irq_handler(unsigned irq, struct irq_desc *desc) · line 283

Quoted 13 lines
arch/arm/mach-davinci/gpio.c +3 -2
-	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
+	ctl = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
+	g = (struct davinci_gpio_regs __iomem *)ctl->regs;
 
 	/* we only care about one bank */
 	if (irq & 1)
@@ -278,7 +280,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			status >>= 16;
 
 		/* now demux them to the right lowlevel handler */
-		n = (int)irq_get_handler_data(irq);
+		n = ctl->irq_base;

I realized that this breaks for odd banks as the status is right shifted by 16. The GPIO you are using must have been in even bank?

Quoted 5 lines
arch/arm/mach-davinci/gpio.c +0 -0
 		while (status) {
 			res = ffs(status);
 			n += res;
@@ -424,7 +426,13 @@ static int __init davinci_gpio_irq_setup(void)
 

arch/arm/mach-davinci/gpio.c static int __init davinci_gpio_irq_setup(void) · line 435

Quoted 10 lines
arch/arm/mach-davinci/gpio.c +7 -1
 		/* set up all irqs in this bank */
 		irq_set_chained_handler(bank_irq, gpio_irq_handler);
-		irq_set_handler_data(bank_irq, (__force void *)g);
+
+		/*
+		 * Each chip handles 32 gpios, and each irq bank consists of 16
+		 * gpio irqs. Pass the irq bank's corresponding controller to
+		 * the chained irq handler.
+		 */
+		irq_set_handler_data(bank_irq, &chips[bank * 16 / 32]);

This can simply be:

		irq_set_handler_data(bank_irq, &chips[gpio / 32]);

In the interest of time, I did these fixes and pushed the
patch to "fixes" branch of git://gitorious.org/linux-davinci/linux-davinci.git

Can you please test it out and let me know if it works.

Updated patch also attached.

Thanks,
Sekhar

8<---------------------
From: Ido Yariv <[email protected]>
Subject: arm: davinci: Fix low level gpio irq handlers' argument

Commit 7416401 ("arm: davinci: Fix fallout from generic irq chip conversion") introduced a bug, causing low level interrupt handlers to get a bogus irq number as an argument. The gpio irq handler falsely assumes that the handler data is the irq base number and that is no longer true.

Set the irq handler data to be a pointer to the corresponding gpio controller. The chained irq handler can then use it to extract both the irq base number and the gpio registers structure.

CC Thomas Gleixner <[email protected]>

[nsekhar at ti.com: renamed "ctl" to "d", simplified indexing logic for chips and took care of odd bank handling in irq handler]

---
 arch/arm/mach-davinci/gpio.c |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)
arch/arm/mach-davinci/gpio.c +16 -5
index e722139..cafbe13 100644
@@ -254,8 +254,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
 	struct davinci_gpio_regs __iomem *g;
 	u32 mask = 0xffff;
+	struct davinci_gpio_controller *d;
 
-	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
+	d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
+	g = (struct davinci_gpio_regs __iomem *)d->regs;
 
 	/* we only care about one bank */
 	if (irq & 1)
@@ -274,11 +276,14 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		if (!status)
 			break;
 		__raw_writel(status, &g->intstat);
-		if (irq & 1)
-			status >>= 16;
 
 		/* now demux them to the right lowlevel handler */
-		n = (int)irq_get_handler_data(irq);
+		n = d->irq_base;
+		if (irq & 1) {
+			n += 16;
+			status >>= 16;
+		}
+
 		while (status) {
 			res = ffs(status);
 			n += res;
@@ -424,7 +429,13 @@ static int __init davinci_gpio_irq_setup(void)
 
 		/* set up all irqs in this bank */
 		irq_set_chained_handler(bank_irq, gpio_irq_handler);
-		irq_set_handler_data(bank_irq, (__force void *)g);
+
+		/*
+		 * Each chip handles 32 gpios, and each irq bank consists of 16
+		 * gpio irqs. Pass the irq bank's corresponding controller to
+		 * the chained irq handler.
+		 */
+		irq_set_handler_data(bank_irq, &chips[gpio / 32]);
 
 		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
 			irq_set_chip(irq, &gpio_irqchip);
author
#6 lore raw

PATCH v3 1/6 arm: davinci: Fix low level gpio irq handlers' argument

Hi Sekhar,

Quoted 9 lines · Sekhar
Quoted 9 lines
arch/arm/mach-davinci/gpio.c +2 -1
-	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
+	ctl = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
+	g = (struct davinci_gpio_regs __iomem *)ctl->regs;
 
 	/* we only care about one bank */
 	if (irq & 1)
@@ -278,7 +280,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			status >>= 16;
 
Quoted 7 lines

arch/arm/mach-davinci/gpio.c gpio_irq_handler(unsigned irq, struct irq_desc *desc)

Quoted 3 lines
arch/arm/mach-davinci/gpio.c +1 -1
 		/* now demux them to the right lowlevel handler */
-		n = (int)irq_get_handler_data(irq);
+		n = ctl->irq_base;

I realized that this breaks for odd banks as the status is right shifted by 16. The GPIO you are using must have been in even bank?

You're absolutely right, I missed that. And yes, I have been using an even bank GPIO.

Quoted 18 lines
Quoted 5 lines
arch/arm/mach-davinci/gpio.c +0 -0
 		while (status) {
 			res = ffs(status);
 			n += res;
@@ -424,7 +426,13 @@ static int __init davinci_gpio_irq_setup(void)
 

arch/arm/mach-davinci/gpio.c static int __init davinci_gpio_irq_setup(void) · line 435

Quoted 10 lines
arch/arm/mach-davinci/gpio.c +7 -1
 		/* set up all irqs in this bank */
 		irq_set_chained_handler(bank_irq, gpio_irq_handler);
-		irq_set_handler_data(bank_irq, (__force void *)g);
+
+		/*
+		 * Each chip handles 32 gpios, and each irq bank consists of 16
+		 * gpio irqs. Pass the irq bank's corresponding controller to
+		 * the chained irq handler.
+		 */
+		irq_set_handler_data(bank_irq, &chips[bank * 16 / 32]);

This can simply be:

Quoted 6 lines
		irq_set_handler_data(bank_irq, &chips[gpio / 32]);

In the interest of time, I did these fixes and pushed the
patch to "fixes" branch of git://gitorious.org/linux-davinci/linux-davinci.git

Can you please test it out and let me know if it works.

This patch seems to work just fine. I'm afraid I can't test an odd bank GPIO here to verify that this indeed fixed the issue you raised, but it looks correct.

Thanks,
Ido.

author
#7 lore raw

PATCH v2 2/6 arm: davinci: Explicitly set channel controllers' default queues

In reply to Ido Yariv

Davinci platforms may define a default queue for each channel controller. If one is not defined, the default queue is set to EVENTQ_1. However, there's no way to distinguish between an unset default queue to one that is set to EVENTQ_0, as EVENTQ_0 = 0.

Explicitly specify the default queue for all channel controllers on all Davinci platforms to EVENTQ_1, and don't overwrite it in the EDMA probe function.

One exception is the DA850 board, for which EVENTQ_1 is not a valid option for its second channel controller. Use EVENTQ_0 instead for that channel controller.

---
 arch/arm/mach-davinci/devices-da8xx.c     |    3 +++
 arch/arm/mach-davinci/devices-tnetv107x.c |    1 +
 arch/arm/mach-davinci/dm355.c             |    1 +
 arch/arm/mach-davinci/dm644x.c            |    1 +
 arch/arm/mach-davinci/dm646x.c            |    1 +
 arch/arm/mach-davinci/dma.c               |    2 --
 6 files changed, 7 insertions(+), 2 deletions(-)
arch/arm/mach-davinci/devices-da8xx.c +3 -0
index fc4e98e..502222a 100644
@@ -133,6 +133,7 @@ static struct edma_soc_info da830_edma_cc0_info = {
 	.n_cc			= 1,
 	.queue_tc_mapping	= da8xx_queue_tc_mapping,
 	.queue_priority_mapping	= da8xx_queue_priority_mapping,
+	.default_queue		= EVENTQ_1,
 };
 
 static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
@@ -148,6 +149,7 @@ static struct edma_soc_info da850_edma_cc_info[] = {
 		.n_cc			= 1,
 		.queue_tc_mapping	= da8xx_queue_tc_mapping,
 		.queue_priority_mapping	= da8xx_queue_priority_mapping,
+		.default_queue		= EVENTQ_1,
 	},
 	{
 		.n_channel		= 32,
@@ -157,6 +159,7 @@ static struct edma_soc_info da850_edma_cc_info[] = {
 		.n_cc			= 1,
 		.queue_tc_mapping	= da850_queue_tc_mapping,
 		.queue_priority_mapping	= da850_queue_priority_mapping,
+		.default_queue		= EVENTQ_0,
 	},
 };
 
arch/arm/mach-davinci/devices-tnetv107x.c +1 -0
index 6162cae..6298d46 100644
@@ -80,6 +80,7 @@ static struct edma_soc_info edma_cc0_info = {
 	.n_cc			= 1,
 	.queue_tc_mapping	= edma_tc_mapping,
 	.queue_priority_mapping	= edma_priority_mapping,
+	.default_queue		= EVENTQ_1;
 };
 
 static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
arch/arm/mach-davinci/dm355.c +1 -0
index a3a94e9..f1d9c75 100644
@@ -591,6 +591,7 @@ static struct edma_soc_info edma_cc0_info = {
 	.n_cc			= 1,
 	.queue_tc_mapping	= queue_tc_mapping,
 	.queue_priority_mapping	= queue_priority_mapping,
+	.default_queue		= EVENTQ_1;
 };
 
 static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
arch/arm/mach-davinci/dm644x.c +1 -0
index 4c82c27..9971990 100644
@@ -514,6 +514,7 @@ static struct edma_soc_info edma_cc0_info = {
 	.n_cc			= 1,
 	.queue_tc_mapping	= queue_tc_mapping,
 	.queue_priority_mapping	= queue_priority_mapping,
+	.default_queue		= EVENTQ_1;
 };
 
 static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
arch/arm/mach-davinci/dm646x.c +1 -0
index 1e0f809..a40372d 100644
@@ -551,6 +551,7 @@ static struct edma_soc_info edma_cc0_info = {
 	.n_cc			= 1,
 	.queue_tc_mapping	= dm646x_queue_tc_mapping,
 	.queue_priority_mapping	= dm646x_queue_priority_mapping,
+	.default_queue		= EVENTQ_1;
 };
 
 static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
arch/arm/mach-davinci/dma.c +0 -2
index 6b96698..6ba4191 100644
@@ -1450,8 +1450,6 @@ static int __init edma_probe(struct platform_device *pdev)
 							EDMA_MAX_CC);
 
 		edma_cc[j]->default_queue = info[j]->default_queue;
-		if (!edma_cc[j]->default_queue)
-			edma_cc[j]->default_queue = EVENTQ_1;
 
 		dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
 			edmacc_regs_base[j]);
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH v2 2/6 arm: davinci: Explicitly set channel controllers' default queues

Quoted 9 lines · Ido Yariv

Davinci platforms may define a default queue for each channel controller. If one is not defined, the default queue is set to EVENTQ_1. However, there's no way to distinguish between an unset default queue to one that is set to EVENTQ_0, as EVENTQ_0 = 0.

Explicitly specify the default queue for all channel controllers on all Davinci platforms to EVENTQ_1, and don't overwrite it in the EDMA probe function.

Quoted 5 lines

One exception is the DA850 board, for which EVENTQ_1 is not a valid option for its second channel controller. Use EVENTQ_0 instead for that channel controller.

Looks good to me. Will queue for v3.2/fixes

BTW, Arnd has indicated a preference for "ARM: davinci: " prefix so I will make that change while applying.

Thanks,
Sekhar

#9 lore raw

PATCH v2 2/6 arm: davinci: Explicitly set channel controllers' default queues

Hello.

Quoted 9 lines · Sekhar
Quoted 8 lines

Davinci platforms may define a default queue for each channel controller. If one is not defined, the default queue is set to EVENTQ_1. However, there's no way to distinguish between an unset default queue to one that is set to EVENTQ_0, as EVENTQ_0 = 0.

Explicitly specify the default queue for all channel controllers on all Davinci platforms to EVENTQ_1, and don't overwrite it in the EDMA probe function.

Quoted 7 lines
Quoted 5 lines

One exception is the DA850 board, for which EVENTQ_1 is not a valid option for its second channel controller. Use EVENTQ_0 instead for that channel controller.

Looks good to me. Will queue for v3.2/fixes

Why wait for 3.2? If this is considered a fix, it should be applied to 3.1, no?

WBR, Sergei

#10 lore raw

PATCH v2 2/6 arm: davinci: Explicitly set channel controllers' default queues

Hi Sergei,

Quoted 17 lines · Sergei Shtylyov

Hello.

Quoted 12 lines · Sekhar
Quoted 12 lines

Davinci platforms may define a default queue for each channel controller. If one is not defined, the default queue is set to EVENTQ_1. However, there's no way to distinguish between an unset default queue to one that is set to EVENTQ_0, as EVENTQ_0 = 0.

Explicitly specify the default queue for all channel controllers on all Davinci platforms to EVENTQ_1, and don't overwrite it in the EDMA probe function.

One exception is the DA850 board, for which EVENTQ_1 is not a valid option for its second channel controller. Use EVENTQ_0 instead for that channel controller.

Quoted 5 lines
Quoted 3 lines
Quoted 1 line

Looks good to me. Will queue for v3.2/fixes

Why wait for 3.2? If this is considered a fix, it should be applied to 3.1, no?

3.2/fixes just indicates it will be queued as a fix/cleanup for 3.2 so it will have higher priority for merge when compared to a new feature.

This patch doesn't really fix any existing broken functionality. It corrects event queue configuration for EDMA CC1 on DA850 for which there are no current users in mainline.

So, not sending for v3.1.

Thanks,
Sekhar

#11 lore raw

PATCH v2 2/6 arm: davinci: Explicitly set channel controllers' default queues

Quoted 30 lines · Sekhar

Hi Sergei,

Quoted 17 lines · Sergei Shtylyov

Hello.

Quoted 12 lines · Sekhar
Quoted 12 lines

Davinci platforms may define a default queue for each channel controller. If one is not defined, the default queue is set to EVENTQ_1. However, there's no way to distinguish between an unset default queue to one that is set to EVENTQ_0, as EVENTQ_0 = 0.

Explicitly specify the default queue for all channel controllers on all Davinci platforms to EVENTQ_1, and don't overwrite it in the EDMA probe function.

One exception is the DA850 board, for which EVENTQ_1 is not a valid option for its second channel controller. Use EVENTQ_0 instead for that channel controller.

Quoted 5 lines
Quoted 3 lines
Quoted 1 line

Looks good to me. Will queue for v3.2/fixes

? ? Why wait for 3.2? If this is considered a fix, it should be applied to 3.1, no?

3.2/fixes just indicates it will be queued as a fix/cleanup for 3.2 so it will have higher priority for merge when compared to a new feature.

Quoted 5 lines

This patch doesn't really fix any existing broken functionality. It corrects event queue configuration for EDMA CC1 on DA850 for which there are no current users in mainline.

So, not sending for v3.1.

If it's not too late:

Tested this patch and it fixes SD/MMC1 support on da850.

Thanks, Ido!

Best Regards,
Ben Gardiner

---
Nanometrics Inc.
http://www.nanometrics.ca

author
#12 lore raw

PATCH v2 3/6 arm: davinci: mmc: Add support for set_power callback

In reply to Ido Yariv

Some devices connected to the MMC bus are power controlled by external means. For instance, an SDIO device may be powered down/up by an external gpio line.

In order to avoid toggling power from within the MMC host driver, add a set_power callback function, which will be called by set_ios upon powering down/up.

---
 arch/arm/mach-davinci/include/mach/mmc.h |    3 +++
 drivers/mmc/host/davinci_mmc.c           |   13 +++++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/include/mach/mmc.h +3 -0
index d4f1e96..5ba6b22 100644
@@ -12,6 +12,9 @@ struct davinci_mmc_config {
 	/* get_cd()/get_wp() may sleep */
 	int	(*get_cd)(int module);
 	int	(*get_ro)(int module);
+
+	void	(*set_power)(int module, bool on);
+
 	/* wires == 0 is equivalent to wires == 4 (4-bit parallel) */
 	u8	wires;
 
drivers/mmc/host/davinci_mmc.c +13 -0
index 0076c74..64a8325 100644
@@ -807,12 +807,25 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
 static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmc_davinci_host *host = mmc_priv(mmc);
+	struct platform_device *pdev = to_platform_device(mmc->parent);
+	struct davinci_mmc_config *config = pdev->dev.platform_data;
 
 	dev_dbg(mmc_dev(host->mmc),
 		"clock %dHz busmode %d powermode %d Vdd %04x\n",
 		ios->clock, ios->bus_mode, ios->power_mode,
 		ios->vdd);
 
+	switch (ios->power_mode) {
+	case MMC_POWER_OFF:
+		if (config && config->set_power)
+			config->set_power(pdev->id, false);
+		break;
+	case MMC_POWER_UP:
+		if (config && config->set_power)
+			config->set_power(pdev->id, true);
+		break;
+	}
+
 	switch (ios->bus_width) {
 	case MMC_BUS_WIDTH_8:
 		dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n");
Signature · 1 line
1.7.4.1
#13 lore raw

PATCH v2 3/6 arm: davinci: mmc: Add support for set_power callback

Quoted 8 lines · Ido Yariv

Some devices connected to the MMC bus are power controlled by external means. For instance, an SDIO device may be powered down/up by an external gpio line.

In order to avoid toggling power from within the MMC host driver, add a set_power callback function, which will be called by set_ios upon powering down/up.

Quoted 6 lines
---
 arch/arm/mach-davinci/include/mach/mmc.h |    3 +++
 drivers/mmc/host/davinci_mmc.c           |   13 +++++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)

This looks good to me, but needs Ack/Sign-off from MMC maintainer. Please repost keeping him in CC.

Thanks,
Sekhar

author
#14 lore raw

PATCH v2 1/1 mmc: davinci: Add support for set_power callback

Some devices connected to the MMC bus are power controlled by external means. For instance, an SDIO device may be powered down/up by an external gpio line.

In order to avoid toggling power from within the MMC host driver, add a set_power callback function, which will be called by set_ios upon powering down/up.

---
 arch/arm/mach-davinci/include/mach/mmc.h |    3 +++
 drivers/mmc/host/davinci_mmc.c           |   13 +++++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/include/mach/mmc.h +3 -0
index d4f1e96..5ba6b22 100644
@@ -12,6 +12,9 @@ struct davinci_mmc_config {
 	/* get_cd()/get_wp() may sleep */
 	int	(*get_cd)(int module);
 	int	(*get_ro)(int module);
+
+	void	(*set_power)(int module, bool on);
+
 	/* wires == 0 is equivalent to wires == 4 (4-bit parallel) */
 	u8	wires;
 
drivers/mmc/host/davinci_mmc.c +13 -0
index 0076c74..64a8325 100644
@@ -807,12 +807,25 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
 static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmc_davinci_host *host = mmc_priv(mmc);
+	struct platform_device *pdev = to_platform_device(mmc->parent);
+	struct davinci_mmc_config *config = pdev->dev.platform_data;
 
 	dev_dbg(mmc_dev(host->mmc),
 		"clock %dHz busmode %d powermode %d Vdd %04x\n",
 		ios->clock, ios->bus_mode, ios->power_mode,
 		ios->vdd);
 
+	switch (ios->power_mode) {
+	case MMC_POWER_OFF:
+		if (config && config->set_power)
+			config->set_power(pdev->id, false);
+		break;
+	case MMC_POWER_UP:
+		if (config && config->set_power)
+			config->set_power(pdev->id, true);
+		break;
+	}
+
 	switch (ios->bus_width) {
 	case MMC_BUS_WIDTH_8:
 		dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n");
Signature · 1 line
1.7.4.1
#15 lore raw

PATCH v2 1/1 mmc: davinci: Add support for set_power callback

Hi,

Quoted 9 lines · Ido Yariv

Some devices connected to the MMC bus are power controlled by external means. For instance, an SDIO device may be powered down/up by an external gpio line.

In order to avoid toggling power from within the MMC host driver, add a set_power callback function, which will be called by set_ios upon powering down/up.

Quoted 50 lines
CC Chris Ball <[email protected]>
---
 arch/arm/mach-davinci/include/mach/mmc.h |    3 +++
 drivers/mmc/host/davinci_mmc.c           |   13 +++++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/include/mach/mmc.h +3 -0
index d4f1e96..5ba6b22 100644
@@ -12,6 +12,9 @@ struct davinci_mmc_config {
 	/* get_cd()/get_wp() may sleep */
 	int	(*get_cd)(int module);
 	int	(*get_ro)(int module);
+
+	void	(*set_power)(int module, bool on);
+
 	/* wires == 0 is equivalent to wires == 4 (4-bit parallel) */
 	u8	wires;
 
drivers/mmc/host/davinci_mmc.c +13 -0
index 0076c74..64a8325 100644
@@ -807,12 +807,25 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
 static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmc_davinci_host *host = mmc_priv(mmc);
+	struct platform_device *pdev = to_platform_device(mmc->parent);
+	struct davinci_mmc_config *config = pdev->dev.platform_data;
 
 	dev_dbg(mmc_dev(host->mmc),
 		"clock %dHz busmode %d powermode %d Vdd %04x\n",
 		ios->clock, ios->bus_mode, ios->power_mode,
 		ios->vdd);
 
+	switch (ios->power_mode) {
+	case MMC_POWER_OFF:
+		if (config && config->set_power)
+			config->set_power(pdev->id, false);
+		break;
+	case MMC_POWER_UP:
+		if (config && config->set_power)
+			config->set_power(pdev->id, true);
+		break;
+	}
+
 	switch (ios->bus_width) {
 	case MMC_BUS_WIDTH_8:
 		dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n");
Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child
author
#16 lore raw

PATCH v2 4/6 arm: davinci: DA850: Add MMC/SD1 pinmux configuration

In reply to Ido Yariv

AM18x has two MMC slots. Add the required pinmux configuration for the second slot.

---
 arch/arm/mach-davinci/da850.c            |    7 +++++++
 arch/arm/mach-davinci/include/mach/mux.h |    8 ++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/da850.c +7 -0
index 133aac4..f6eafb4 100644
@@ -525,6 +525,13 @@ static const struct mux_config da850_pins[] = {
 	MUX_CFG(DA850, MMCSD0_DAT_3,	10,	20,	15,	2,	false)
 	MUX_CFG(DA850, MMCSD0_CLK,	10,	0,	15,	2,	false)
 	MUX_CFG(DA850, MMCSD0_CMD,	10,	4,	15,	2,	false)
+	/* MMC/SD1 function */
+	MUX_CFG(DA850, MMCSD1_DAT_0,	18,	8,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD1_DAT_1,	19,	16,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD1_DAT_2,	19,	12,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD1_DAT_3,	19,	8,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD1_CLK,	18,	12,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD1_CMD,	18,	16,	15,	2,	false)
 	/* EMIF2.5/EMIFA function */
 	MUX_CFG(DA850, EMA_D_7,		9,	0,	15,	1,	false)
 	MUX_CFG(DA850, EMA_D_6,		9,	4,	15,	1,	false)
arch/arm/mach-davinci/include/mach/mux.h +8 -0
index 5d4e0fe..7fb7f1e 100644
@@ -857,6 +857,14 @@ enum davinci_da850_index {
 	DA850_MMCSD0_CLK,
 	DA850_MMCSD0_CMD,
 
+	/* MMC/SD1 function */
+	DA850_MMCSD1_DAT_0,
+	DA850_MMCSD1_DAT_1,
+	DA850_MMCSD1_DAT_2,
+	DA850_MMCSD1_DAT_3,
+	DA850_MMCSD1_CLK,
+	DA850_MMCSD1_CMD,
+
 	/* EMIF2.5/EMIFA function */
 	DA850_EMA_D_7,
 	DA850_EMA_D_6,
Signature · 1 line
1.7.4.1
author
#17 lore raw

PATCH v2 5/6 arm: davinci: DA850: Add GPIO pinmux configuration for wl1271

In reply to Ido Yariv

The wl1271 daughter board makes use of a few GPIOs:
GPIO6_9 is used for powering down/up the WLAN functionality. GPIO6_10 is used as an input IRQ line from the WLAN chip.

Add the required pinmux configuration for these GPIOs.

---
 arch/arm/mach-davinci/da850.c            |    2 ++
 arch/arm/mach-davinci/include/mach/mux.h |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/da850.c +2 -0
index f6eafb4..bfe9b71 100644
@@ -590,6 +590,8 @@ static const struct mux_config da850_pins[] = {
 	MUX_CFG(DA850, GPIO3_13,	7,	8,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_0,		10,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_1,		10,	24,	15,	8,	false)
+	MUX_CFG(DA850, GPIO6_9,		13,	24,	15,	8,	false)
+	MUX_CFG(DA850, GPIO6_10,	13,	20,	15,	8,	false)
 	MUX_CFG(DA850, GPIO6_13,	13,	8,	15,	8,	false)
 	MUX_CFG(DA850, RTC_ALARM,	0,	28,	15,	2,	false)
 #endif
arch/arm/mach-davinci/include/mach/mux.h +2 -0
index 7fb7f1e..a7e92fc 100644
@@ -924,6 +924,8 @@ enum davinci_da850_index {
 	DA850_GPIO3_13,
 	DA850_GPIO4_0,
 	DA850_GPIO4_1,
+	DA850_GPIO6_9,
+	DA850_GPIO6_10,
 	DA850_GPIO6_13,
 	DA850_RTC_ALARM,
 };
Signature · 1 line
1.7.4.1
#18 lore raw

PATCH v2 5/6 arm: davinci: DA850: Add GPIO pinmux configuration for wl1271

Quoted 7 lines · Ido Yariv

The wl1271 daughter board makes use of a few GPIOs:
GPIO6_9 is used for powering down/up the WLAN functionality. GPIO6_10 is used as an input IRQ line from the WLAN chip.

Add the required pinmux configuration for these GPIOs.

4/6 and 5/6 both look good, will queue for v3.2/features

Thanks,
Sekhar

#19 lore raw

RE: [PATCH v2 5/6] arm: davinci: DA850: Add GPIO pinmux configuration for wl1271

In reply to Ido Yariv
Quoted 7 lines · Ido Yariv

The wl1271 daughter board makes use of a few GPIOs:
GPIO6_9 is used for powering down/up the WLAN functionality. GPIO6_10 is used as an input IRQ line from the WLAN chip.

Add the required pinmux configuration for these GPIOs.

4/6 and 5/6 both look good, will queue for v3.2/features

Thanks,
Sekhar

author
#20 lore raw

PATCH v2 6/6 arm: davinci: DA850: Add wl1271/wlan support

In reply to Ido Yariv

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

This patch adds support for the WLAN capabilities of this expansion board.

---
 arch/arm/mach-davinci/Kconfig           |   10 +++
 arch/arm/mach-davinci/board-da850-evm.c |  127 +++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/Kconfig +10 -0
index c0deaca..32d837d 100644
@@ -192,6 +192,16 @@ config DA850_UI_RMII
 
 endchoice
 
+config DA850_WL12XX
+	bool "AM18x wl1271 daughter board"
+	depends on MACH_DAVINCI_DA850_EVM
+	help
+	  The wl1271 daughter card for AM18x EVMs is a combo wireless
+	  connectivity add-on card, based on the LS Research TiWi module with
+	  Texas Instruments' wl1271 solution.
+	  Say Y if you want to use a wl1271 expansion card connected to the
+	  AM18x EVM.
+
 config GPIO_PCA953X
 	default MACH_DAVINCI_DA850_EVM
 
arch/arm/mach-davinci/board-da850-evm.c +127 -0

151 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#21 lore raw

PATCH v2 6/6 arm: davinci: DA850: Add wl1271/wlan support

Quoted 32 lines · Ido Yariv

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

This patch adds support for the WLAN capabilities of this expansion board.

---

arch/arm/mach-davinci/board-da850-evm.c +14 -0
index a7b41bf..2dae1a1 100644
@@ -31,6 +31,8 @@
 
+#ifdef CONFIG_DA850_WL12XX
+
+static int da850_wl12xx_fref = WL12XX_REFCLOCK_38;
+
+static int __init setup_da850_wl12xx_fref(char *fref)
+{
+	if (!strcmp(fref, "19.2"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_19;
+	else if (!strcmp(fref, "26"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_26;
+	else if (!strcmp(fref, "38.4"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_38;
+	else if (!strcmp(fref, "52"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_52;

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1148

Quoted 10 lines
arch/arm/mach-davinci/board-da850-evm.c +10 -0
+	else if (!strcmp(fref, "XTAL26"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_26_XTAL;
+	else if (!strcmp(fref, "XTAL38.4"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_38_XTAL;
+	else
+		pr_info("da850_wl12xx_fref is invalid. Valid options: "
+			"19.2, 26, 38.4, 52, XTAL26 or XTAL38.4\n");
+	return 0;
+}
+__setup("da850_wl12xx_fref=", setup_da850_wl12xx_fref);

Adding a new kernel parameter requires update to Documentation/kernel-parameters.txt as well.

I am Ccing a couple of folks in case they have ideas on whether there is a better way to pass this information to the kernel. I assume there is no way to detect this from hardware.

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1175

Quoted 3 lines
arch/arm/mach-davinci/board-da850-evm.c +3 -0
+static struct davinci_mmc_config da850_mmc_wl12xx_config = {
+	.get_ro		= NULL,
+	.get_cd		= NULL,

You can get rid of these NULL initializers.

Quoted 37 lines
arch/arm/mach-davinci/board-da850-evm.c +36 -0
+	.set_power	= wl12xx_set_power,
+	.wires		= 4,
+	.max_freq	= 25000000,
+	.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE |
+			  MMC_CAP_POWER_OFF_CARD,
+	.version	= MMC_CTLR_VERSION_2,
+};
 
+static void da850_wl12xx_init(void)
+{
+	int ret;
+
+	ret = davinci_cfg_reg_list(da850_evm_mmc_wl12xx_pins);
+	if (ret) {
+		pr_warning("da850_evm_init: wl12xx/mmc mux setup failed:"
+			   " %d\n", ret);
+		return;
+	}
+
+	ret = da850_register_mmcsd1(&da850_mmc_wl12xx_config);
+	if (ret) {
+		pr_warning("da850_evm_init: wl12xx/mmc registration failed:"
+			   " %d\n", ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW, "wl12xx_en");
+	if (ret) {
+		pr_err("Error initializing the wl12xx enable gpio: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq");
+	if (ret) {
+		pr_err("Error initializing the wl12xx irq gpio: %d\n", ret);
+		gpio_free(DA850_WLAN_EN);
+		return;

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1235

Quoted 10 lines
arch/arm/mach-davinci/board-da850-evm.c +10 -0
+	}
+
+	da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
+	da850_wl12xx_wlan_data.board_ref_clock = da850_wl12xx_fref;
+
+	ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
+	if (ret) {
+		pr_err("Error setting wl12xx data: %d\n", ret);
+		gpio_free(DA850_WLAN_IRQ);
+		gpio_free(DA850_WLAN_EN);

Why not just use the traditional goto based bail out mechanism? You will avoid the multiple gpio_free() calls.

Thanks,
Sekhar

author
#22 lore raw

PATCH v2 6/6 arm: davinci: DA850: Add wl1271/wlan support

Hi Sekhar,

Quoted 7 lines · Sekhar

Adding a new kernel parameter requires update to Documentation/kernel-parameters.txt as well.

I am Ccing a couple of folks in case they have ideas on whether there is a better way to pass this information to the kernel. I assume there is no way to detect this from hardware.

Unfortunately, auto-detection of the reference clock is not currently possible. However, it might be a better idea to have the ability to override this value with a wl12xx module parameter instead of a kernel parameter. I'll drop this kernel parameter.

Quoted 5 lines

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1175

Quoted 3 lines
arch/arm/mach-davinci/board-da850-evm.c +3 -0
+static struct davinci_mmc_config da850_mmc_wl12xx_config = {
+	.get_ro		= NULL,
+	.get_cd		= NULL,

You can get rid of these NULL initializers.

Sure.

Quoted 7 lines
Quoted 7 lines
arch/arm/mach-davinci/board-da850-evm.c +7 -0
+	.set_power	= wl12xx_set_power,
+	.wires		= 4,
+	.max_freq	= 25000000,
+	.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE |
+			  MMC_CAP_POWER_OFF_CARD,
+	.version	= MMC_CTLR_VERSION_2,
+};

[...]

Quoted 16 lines
Quoted 16 lines
arch/arm/mach-davinci/board-da850-evm.c +16 -0
+	ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW, "wl12xx_en");
+	if (ret) {
+		pr_err("Error initializing the wl12xx enable gpio: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq");
+	if (ret) {
+		pr_err("Error initializing the wl12xx irq gpio: %d\n", ret);
+		gpio_free(DA850_WLAN_EN);
+		return;
+	}
+
+	da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
+	da850_wl12xx_wlan_data.board_ref_clock = da850_wl12xx_fref;
+
Quoted 8 lines

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1235

Quoted 5 lines
arch/arm/mach-davinci/board-da850-evm.c +5 -0
+	ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
+	if (ret) {
+		pr_err("Error setting wl12xx data: %d\n", ret);
+		gpio_free(DA850_WLAN_IRQ);
+		gpio_free(DA850_WLAN_EN);

Why not just use the traditional goto based bail out mechanism? You will avoid the multiple gpio_free() calls.

Sure.

Thanks for your review,
Ido.

#23 lore raw

Re: [PATCH v2 6/6] arm: davinci: DA850: Add wl1271/wlan support

Hi,

to which davinci git repository this is uploaded, i am using
http://gitorious.org/linux-davinci, I cannot find it board-da850-evm.c.

Quoted 1 line

From where to pull this repository.

Quoted 72 lines · Ido Yariv

Hi Sekhar,

Quoted 7 lines · Sekhar

Adding a new kernel parameter requires update to Documentation/kernel-parameters.txt as well.

I am Ccing a couple of folks in case they have ideas on whether there is a better way to pass this information to the kernel. I assume there is no way to detect this from hardware.

Unfortunately, auto-detection of the reference clock is not currently possible. However, it might be a better idea to have the ability to override this value with a wl12xx module parameter instead of a kernel parameter. I'll drop this kernel parameter.

Quoted 5 lines

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1175

Quoted 3 lines
arch/arm/mach-davinci/board-da850-evm.c +3 -0
+static struct davinci_mmc_config da850_mmc_wl12xx_config = {
+   .get_ro         = NULL,
+   .get_cd         = NULL,

You can get rid of these NULL initializers.

Sure.

Quoted 7 lines
Quoted 7 lines
arch/arm/mach-davinci/board-da850-evm.c +7 -0
+   .set_power      = wl12xx_set_power,
+   .wires          = 4,
+   .max_freq       = 25000000,
+   .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE |
+                     MMC_CAP_POWER_OFF_CARD,
+   .version        = MMC_CTLR_VERSION_2,
+};

[...]

Quoted 1 line
Quoted 1 line

+ ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW,

"wl12xx_en");

Quoted 2 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+   if (ret) {
+           pr_err("Error initializing the wl12xx enable gpio: %d\n",

ret);

Quoted 6 lines

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void)

Quoted 6 lines
arch/arm/mach-davinci/board-da850-evm.c +6 -0
+           return;
+   }
+
+   ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq");
+   if (ret) {
+           pr_err("Error initializing the wl12xx irq gpio: %d\n",

ret);

Quoted 7 lines
Quoted 7 lines
arch/arm/mach-davinci/board-da850-evm.c +7 -0
+           gpio_free(DA850_WLAN_EN);
+           return;
+   }
+
+   da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
+   da850_wl12xx_wlan_data.board_ref_clock = da850_wl12xx_fref;
+
Quoted 8 lines

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1235

Quoted 5 lines
arch/arm/mach-davinci/board-da850-evm.c +5 -0
+   ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
+   if (ret) {
+           pr_err("Error setting wl12xx data: %d\n", ret);
+           gpio_free(DA850_WLAN_IRQ);
+           gpio_free(DA850_WLAN_EN);

Why not just use the traditional goto based bail out mechanism? You will avoid the multiple gpio_free() calls.

Sure.

Thanks for your review,
Ido.

_______________________________________________
linux-arm-kernel mailing list linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Signature · 2 lines
Thanks and Regards,
Harish Kumar. V
author
#24 lore raw

PATCH v3 1/1 davinci: Add wl1271/wlan support for AM18x

In reply to Nori, Sekhar

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

Add support for the WLAN capabilities of this expansion board.

---
 arch/arm/mach-davinci/Kconfig           |   10 +++
 arch/arm/mach-davinci/board-da850-evm.c |  114 +++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/Kconfig +10 -0
index c0deaca..32d837d 100644
@@ -192,6 +192,16 @@ config DA850_UI_RMII
 
 endchoice
 
+config DA850_WL12XX
+	bool "AM18x wl1271 daughter board"
+	depends on MACH_DAVINCI_DA850_EVM
+	help
+	  The wl1271 daughter card for AM18x EVMs is a combo wireless
+	  connectivity add-on card, based on the LS Research TiWi module with
+	  Texas Instruments' wl1271 solution.
+	  Say Y if you want to use a wl1271 expansion card connected to the
+	  AM18x EVM.
+
 config GPIO_PCA953X
 	default MACH_DAVINCI_DA850_EVM
 
arch/arm/mach-davinci/board-da850-evm.c +114 -0

138 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#25 lore raw

PATCH v3 1/1 davinci: Add wl1271/wlan support for AM18x

Quoted 72 lines · Ido Yariv

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

Add support for the WLAN capabilities of this expansion board.

---
 arch/arm/mach-davinci/Kconfig           |   10 +++
 arch/arm/mach-davinci/board-da850-evm.c |  114 +++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/Kconfig +10 -0
index c0deaca..32d837d 100644
@@ -192,6 +192,16 @@ config DA850_UI_RMII
 
 endchoice
 
+config DA850_WL12XX
+	bool "AM18x wl1271 daughter board"
+	depends on MACH_DAVINCI_DA850_EVM
+	help
+	  The wl1271 daughter card for AM18x EVMs is a combo wireless
+	  connectivity add-on card, based on the LS Research TiWi module with
+	  Texas Instruments' wl1271 solution.
+	  Say Y if you want to use a wl1271 expansion card connected to the
+	  AM18x EVM.
+
 config GPIO_PCA953X
 	default MACH_DAVINCI_DA850_EVM
 
arch/arm/mach-davinci/board-da850-evm.c +15 -0
index bd53945..d817626 100644
@@ -31,6 +31,8 @@
 #include <linux/input/tps6507x-ts.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/delay.h>
+#include <linux/wl12xx.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -49,6 +51,9 @@
 #define DA850_MMCSD_CD_PIN		GPIO_TO_PIN(4, 0)
 #define DA850_MMCSD_WP_PIN		GPIO_TO_PIN(4, 1)
 
+#define DA850_WLAN_EN			GPIO_TO_PIN(6, 9)
+#define DA850_WLAN_IRQ			GPIO_TO_PIN(6, 10)
+
 #define DA850_MII_MDIO_CLKEN_PIN	GPIO_TO_PIN(2, 6)
 
 static struct mtd_partition da850evm_spiflash_part[] = {
@@ -1117,6 +1122,110 @@ static __init int da850_evm_init_cpufreq(void)
 static __init int da850_evm_init_cpufreq(void) { return 0; }
 #endif
 
+#ifdef CONFIG_DA850_WL12XX
+
+static void wl12xx_set_power(int index, bool power_on)
+{
+	static bool power_state;
+
+	pr_debug("Powering %s wl12xx", power_on ? "on" : "off");
+
+	if (power_on == power_state)
+		return;

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1144

Quoted 10 lines
arch/arm/mach-davinci/board-da850-evm.c +10 -0
+	power_state = power_on;
+
+	if (power_on) {
+		/* Power up sequence required for wl127x devices */
+		gpio_set_value(DA850_WLAN_EN, 1);
+		usleep_range(15000, 15000);
+		gpio_set_value(DA850_WLAN_EN, 0);
+		usleep_range(1000, 1000);
+		gpio_set_value(DA850_WLAN_EN, 1);
+		msleep(70);

Why turn on, then off, and then back on?
Isn't off, then back on sufficient?

Also, why not use regulator API like panda board does?

author
#26 lore raw

PATCH v3 1/1 davinci: Add wl1271/wlan support for AM18x

Hi Troy,

Quoted 11 lines · Troy Kisky

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1144

Quoted 8 lines
arch/arm/mach-davinci/board-da850-evm.c +8 -0
+	if (power_on) {
+		/* Power up sequence required for wl127x devices */
+		gpio_set_value(DA850_WLAN_EN, 1);
+		usleep_range(15000, 15000);
+		gpio_set_value(DA850_WLAN_EN, 0);
+		usleep_range(1000, 1000);
+		gpio_set_value(DA850_WLAN_EN, 1);
+		msleep(70);

Why turn on, then off, and then back on?
Isn't off, then back on sufficient?

Unfortunately, no. This is a required power up sequence for some hardware revisions of the 1271 chip.

Quoted 1 line

Also, why not use regulator API like panda board does?

Unlike omap_hsmmc, davinci's MMC host driver does not toggle any regulators. To keep things simple, a set_power callback function was added to the mmc host as part of this patch series.
I've considered adding regulator support instead, but found it to be a bit over-complicated for this task. In addition, it would require either modifying the fixed regulator or adding a new one in order to support the above power sequence.

Thanks for your review,
Ido.

#27 lore raw

PATCH v3 1/1 davinci: Add wl1271/wlan support for AM18x

Quoted 15 lines · Ido Yariv

Hi Troy,

Quoted 11 lines · Troy Kisky

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1144

Quoted 8 lines
arch/arm/mach-davinci/board-da850-evm.c +8 -0
+	if (power_on) {
+		/* Power up sequence required for wl127x devices */
+		gpio_set_value(DA850_WLAN_EN, 1);
+		usleep_range(15000, 15000);
+		gpio_set_value(DA850_WLAN_EN, 0);
+		usleep_range(1000, 1000);
+		gpio_set_value(DA850_WLAN_EN, 1);
+		msleep(70);

Why turn on, then off, and then back on?
Isn't off, then back on sufficient?

Quoted 2 lines

Unfortunately, no. This is a required power up sequence for some hardware revisions of the 1271 chip.

That's too bad.

Quoted 10 lines
Quoted 2 lines

Also, why not use regulator API like panda board does?

Unlike omap_hsmmc, davinci's MMC host driver does not toggle any regulators. To keep things simple, a set_power callback function was added to the mmc host as part of this patch series.
I've considered adding regulator support instead, but found it to be a bit over-complicated for this task. In addition, it would require either modifying the fixed regulator or adding a new one in order to support the above power sequence.

Yes, that is more effort. I'm fine with your method, but with all the consolidation effort that's being expended currently, it would be nice if all boards could use a common method to power up sdio cards. It might make a device tree implementation for this driver easier too, though I am certainly no expert there.

Quoted 9 lines

Thanks for your review,
Ido.

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

#28 lore raw

PATCH v3 1/1 davinci: Add wl1271/wlan support for AM18x

In reply to Ido Yariv

Hi Ido,

Quoted 9 lines · Ido Yariv

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

Add support for the WLAN capabilities of this expansion board.

Can you please rebase this patch to master branch of my tree[1] and repost. It doesn't apply at the moment.

Also, when you repost, please change the subject to

"ARM: davinci: AM18x: Add wl1271/wlan support"

so that it is consistent with other patches.

Thanks,
Sekhar

[1] git://gitorious.org/linux-davinci/linux-davinci.git

author
#29 lore raw

PATCH v4 1/1 ARM: davinci: AM18x: Add wl1271/wlan support

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

Add support for the WLAN capabilities of this expansion board.

---
 arch/arm/mach-davinci/Kconfig           |   10 +++
 arch/arm/mach-davinci/board-da850-evm.c |  114 +++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+), 0 deletions(-)
arch/arm/mach-davinci/Kconfig +10 -0
index c0deaca..32d837d 100644
@@ -192,6 +192,16 @@ config DA850_UI_RMII
 
 endchoice
 
+config DA850_WL12XX
+	bool "AM18x wl1271 daughter board"
+	depends on MACH_DAVINCI_DA850_EVM
+	help
+	  The wl1271 daughter card for AM18x EVMs is a combo wireless
+	  connectivity add-on card, based on the LS Research TiWi module with
+	  Texas Instruments' wl1271 solution.
+	  Say Y if you want to use a wl1271 expansion card connected to the
+	  AM18x EVM.
+
 config GPIO_PCA953X
 	default MACH_DAVINCI_DA850_EVM
 
arch/arm/mach-davinci/board-da850-evm.c +114 -0

138 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#30 lore raw

PATCH v4 1/1 ARM: davinci: AM18x: Add wl1271/wlan support

Quoted 27 lines · Ido Yariv
(quoted diff) +27 -0
+static __init int da850_wl12xx_init(void)
+{
+ ? ? ? int ret;
+
+ ? ? ? ret = davinci_cfg_reg_list(da850_wl12xx_pins);
+ ? ? ? if (ret) {
+ ? ? ? ? ? ? ? pr_err("wl12xx/mmc mux setup failed: %d\n", ret);
+ ? ? ? ? ? ? ? goto exit;
+ ? ? ? }
+
+ ? ? ? ret = da850_register_mmcsd1(&da850_wl12xx_mmc_config);
+ ? ? ? if (ret) {
+ ? ? ? ? ? ? ? pr_err("wl12xx/mmc registration failed: %d\n", ret);
+ ? ? ? ? ? ? ? goto exit;
+ ? ? ? }
+
+ ? ? ? ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW, "wl12xx_en");
+ ? ? ? if (ret) {
+ ? ? ? ? ? ? ? pr_err("Could not request wl12xx enable gpio: %d\n", ret);
+ ? ? ? ? ? ? ? goto exit;
+ ? ? ? }
+
+ ? ? ? ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq");
+ ? ? ? if (ret) {
+ ? ? ? ? ? ? ? pr_err("Could not request wl12xx irq gpio: %d\n", ret);
+ ? ? ? ? ? ? ? goto free_wlan_en;
+ ? ? ? }

Review

Quoted 10 lines
(quoted diff) +10 -0
+
+ ? ? ? da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
+
+ ? ? ? ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
+ ? ? ? if (ret) {
+ ? ? ? ? ? ? ? pr_err("Could not set wl12xx data: %d\n", ret);
+ ? ? ? ? ? ? ? goto free_wlan_irq;
+ ? ? ? }
+
+ ? ? ? return 0;

Hi Ido,

A quick question for my own understanding. What's the mechanism by which wl12xx is bound with above. I see above wl12xx_set_platform_data but I didn't see something like .name = "wl1271" or dev_name that comes in through platform_device_register. If I look at other board files, I see:

321 #ifdef CONFIG_WL12XX_PLATFORM_DATA
322 {

323                 .name           = "wl1271",
324                 .mmc            = 2,
325                 .caps           = MMC_CAP_4_BIT_DATA |
MMC_CAP_POWER_OFF_CARD,
326                 .gpio_wp        = -EINVAL,
327                 .gpio_cd        = -EINVAL,
328                 .nonremovable   = true,

329 },
330 #endif

and

729 #ifdef CONFIG_WL12XX_PLATFORM_DATA
730 /* WL12xx WLAN Init */
731 if (wl12xx_set_platform_data(&omap3evm_wlan_data))
732 pr_err("error setting wl12xx data\n");
733 platform_device_register(&omap3evm_wlan_regulator);
734 #endif

Thanks,
jayakumar

author
#31 lore raw

PATCH v4 1/1 ARM: davinci: AM18x: Add wl1271/wlan support

Hi Jaya,

Quoted 6 lines · Jaya Kumar

Hi Ido,

A quick question for my own understanding. What's the mechanism by which wl12xx is bound with above. I see above wl12xx_set_platform_data but I didn't see something like .name = "wl1271" or dev_name that comes in through platform_device_register.

The wl12xx module calls wl12xx_get_platform_data, which simply returns the structure set by wl12xx_set_platform_data. This mechanism only supports a single platform data.

Quoted 11 lines

If I look at other board files, I see:

321 #ifdef CONFIG_WL12XX_PLATFORM_DATA
322 {

323                 .name           = "wl1271",
324                 .mmc            = 2,
325                 .caps           = MMC_CAP_4_BIT_DATA |
MMC_CAP_POWER_OFF_CARD,
326                 .gpio_wp        = -EINVAL,
327                 .gpio_cd        = -EINVAL,
328                 .nonremovable   = true,
Quoted 2 lines

329 },
330 #endif

'name' is just a descriptive name of omap2_hsmmc_info. davinci_mmc_config doesn't have such a member.

Quoted 6 lines

729 #ifdef CONFIG_WL12XX_PLATFORM_DATA
730 /* WL12xx WLAN Init */
731 if (wl12xx_set_platform_data(&omap3evm_wlan_data))
732 pr_err("error setting wl12xx data\n");
733 platform_device_register(&omap3evm_wlan_regulator);
734 #endif

Please note that the platform_device_register above is used for registering a regulator device, which is driven by the fixed regulator driver and not by wl12xx. This regulator is controlled by omap's mmc host driver.

Hope this clarifies things,
Ido.

Applied
#32 lore raw

PATCH v4 1/1 ARM: davinci: AM18x: Add wl1271/wlan support

In reply to Ido Yariv
Quoted 9 lines · Ido Yariv

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

Add support for the WLAN capabilities of this expansion board.

Applied, thanks.

Regards,
Sekhar

#33 lore raw

RE: [PATCH v2 6/6] arm: davinci: DA850: Add wl1271/wlan support

In reply to Ido Yariv
Quoted 32 lines · Ido Yariv

The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity add-on card, based on the LS Research TiWi module with Texas Instruments' wl1271 solution.
It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator.

This patch adds support for the WLAN capabilities of this expansion board.

---

arch/arm/mach-davinci/board-da850-evm.c +14 -0
index a7b41bf..2dae1a1 100644
@@ -31,6 +31,8 @@
 
+#ifdef CONFIG_DA850_WL12XX
+
+static int da850_wl12xx_fref = WL12XX_REFCLOCK_38;
+
+static int __init setup_da850_wl12xx_fref(char *fref)
+{
+	if (!strcmp(fref, "19.2"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_19;
+	else if (!strcmp(fref, "26"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_26;
+	else if (!strcmp(fref, "38.4"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_38;
+	else if (!strcmp(fref, "52"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_52;

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1148

Quoted 10 lines
arch/arm/mach-davinci/board-da850-evm.c +10 -0
+	else if (!strcmp(fref, "XTAL26"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_26_XTAL;
+	else if (!strcmp(fref, "XTAL38.4"))
+		da850_wl12xx_fref = WL12XX_REFCLOCK_38_XTAL;
+	else
+		pr_info("da850_wl12xx_fref is invalid. Valid options: "
+			"19.2, 26, 38.4, 52, XTAL26 or XTAL38.4\n");
+	return 0;
+}
+__setup("da850_wl12xx_fref=", setup_da850_wl12xx_fref);

Adding a new kernel parameter requires update to Documentation/kernel-parameters.txt as well.

I am Ccing a couple of folks in case they have ideas on whether there is a better way to pass this information to the kernel. I assume there is no way to detect this from hardware.

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1175

Quoted 3 lines
arch/arm/mach-davinci/board-da850-evm.c +3 -0
+static struct davinci_mmc_config da850_mmc_wl12xx_config = {
+	.get_ro		= NULL,
+	.get_cd		= NULL,

You can get rid of these NULL initializers.

Quoted 37 lines
arch/arm/mach-davinci/board-da850-evm.c +36 -0
+	.set_power	= wl12xx_set_power,
+	.wires		= 4,
+	.max_freq	= 25000000,
+	.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE |
+			  MMC_CAP_POWER_OFF_CARD,
+	.version	= MMC_CTLR_VERSION_2,
+};
 
+static void da850_wl12xx_init(void)
+{
+	int ret;
+
+	ret = davinci_cfg_reg_list(da850_evm_mmc_wl12xx_pins);
+	if (ret) {
+		pr_warning("da850_evm_init: wl12xx/mmc mux setup failed:"
+			   " %d\n", ret);
+		return;
+	}
+
+	ret = da850_register_mmcsd1(&da850_mmc_wl12xx_config);
+	if (ret) {
+		pr_warning("da850_evm_init: wl12xx/mmc registration failed:"
+			   " %d\n", ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW, "wl12xx_en");
+	if (ret) {
+		pr_err("Error initializing the wl12xx enable gpio: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq");
+	if (ret) {
+		pr_err("Error initializing the wl12xx irq gpio: %d\n", ret);
+		gpio_free(DA850_WLAN_EN);
+		return;

arch/arm/mach-davinci/board-da850-evm.c static __init int da850_evm_init_cpufreq(void) · line 1235

Quoted 10 lines
arch/arm/mach-davinci/board-da850-evm.c +10 -0
+	}
+
+	da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
+	da850_wl12xx_wlan_data.board_ref_clock = da850_wl12xx_fref;
+
+	ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
+	if (ret) {
+		pr_err("Error setting wl12xx data: %d\n", ret);
+		gpio_free(DA850_WLAN_IRQ);
+		gpio_free(DA850_WLAN_EN);

Why not just use the traditional goto based bail out mechanism? You will avoid the multiple gpio_free() calls.

Thanks,
Sekhar