Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v2 10/20] omap: zoom: add fixed regulator device for wlan
From: Mark Brown @ 2010-07-21 17:59 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: linux-wireless, linux-mmc, linux-omap, Kalle Valo, Pandita Vikram,
	linux, Nicolas Pitre, Tony Lindgren, Roger Quadros, San Mehat,
	Chikkature Rajashekar Madhusudhan, Luciano Coelho, akpm,
	linux-arm-kernel
In-Reply-To: <1279733634-21974-11-git-send-email-ohad@wizery.com>

On Wed, Jul 21, 2010 at 08:33:44PM +0300, Ohad Ben-Cohen wrote:

> +static struct regulator_consumer_supply zoom_vmmc3_supply = {
> +	.supply		= "vmmc",
> +};

This looks like a misconfiguration on the consumer - I'd strongly expect
the consumer to have a dev_name specified also with the name being in
terms of the consumer device.

^ permalink raw reply

* Re: [PATCH v2 01/20] sdio: add TI + wl1271 ids
From: Marcel Holtmann @ 2010-07-21 17:58 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: linux-wireless, linux-mmc, linux-omap, linux-arm-kernel, linux,
	Chikkature Rajashekar Madhusudhan, Luciano Coelho, akpm,
	San Mehat, Roger Quadros, Tony Lindgren, Nicolas Pitre,
	Pandita Vikram, Kalle Valo
In-Reply-To: <1279733634-21974-2-git-send-email-ohad@wizery.com>

Hi Ohad,

> Add SDIO IDs for TI and for TI's wl1271 wlan device.
> 
> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
> ---
>  include/linux/mmc/sdio_ids.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
> index 33b2ea0..0d313c6 100644
> --- a/include/linux/mmc/sdio_ids.h
> +++ b/include/linux/mmc/sdio_ids.h
> @@ -43,4 +43,7 @@
>  #define SDIO_DEVICE_ID_SIANO_NOVA_A0		0x1100
>  #define SDIO_DEVICE_ID_SIANO_STELLAR 		0x5347
>  
> +#define SDIO_VENDOR_ID_TI			0x0097
> +#define SDIO_DEVICE_ID_TI_WL1271		0x4076
> +

are we still doing this non-sense for no real reason. What is so wrong
with keeping the IDs inside the driver code?

Personally I don't even see a point for these ID defines at all. Just
use the bare numbers in SDIO_DEVICE and put a comment above what kind of
device this is.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH] libertas: convert new uses of __attribute__ ((packed)) to __packed
From: Dan Williams @ 2010-07-21 19:58 UTC (permalink / raw)
  To: John W. Linville
  Cc: linux-wireless, Holger Schurig, Amitkumar Karwar, libertas-dev
In-Reply-To: <1279118223-10219-1-git-send-email-linville@tuxdriver.com>

On Wed, 2010-07-14 at 10:37 -0400, John W. Linville wrote:
> Signed-off-by: John W. Linville <linville@tuxdriver.com>

Looks fine to me.

> ---
>  drivers/net/wireless/libertas/cfg.c  |    6 +++---
>  drivers/net/wireless/libertas/host.h |    6 +++---
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
> index f36cc97..7e07416 100644
> --- a/drivers/net/wireless/libertas/cfg.c
> +++ b/drivers/net/wireless/libertas/cfg.c
> @@ -891,7 +891,7 @@ struct cmd_key_material {
>  
>  	__le16 action;
>  	struct MrvlIEtype_keyParamSet param;
> -} __attribute__ ((packed));
> +} __packed;
>  
>  static int lbs_set_key_material(struct lbs_private *priv,
>  				int key_type,
> @@ -1395,7 +1395,7 @@ struct cmd_monitor_mode {
>  
>  	__le16 action;
>  	__le16 mode;
> -} __attribute__ ((packed));
> +} __packed;
>  
>  static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode)
>  {
> @@ -1450,7 +1450,7 @@ struct cmd_rssi {
>  	__le16 nf;
>  	__le16 avg_snr;
>  	__le16 avg_nf;
> -} __attribute__ ((packed));
> +} __packed;
>  
>  static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise)
>  {
> diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
> index db8e209..43d020c 100644
> --- a/drivers/net/wireless/libertas/host.h
> +++ b/drivers/net/wireless/libertas/host.h
> @@ -398,12 +398,12 @@ struct mrvl_ie_domain_param_set {
>  
>  	u8 countrycode[COUNTRY_CODE_LEN];
>  	struct ieee80211_country_ie_triplet triplet[1];
> -} __attribute__ ((packed));
> +} __packed;
>  
>  struct cmd_ds_802_11d_domain_info {
>  	__le16 action;
>  	struct mrvl_ie_domain_param_set domain;
> -} __attribute__ ((packed));
> +} __packed;
>  
>  struct lbs_802_11d_domain_reg {
>  	/** Country code*/
> @@ -411,7 +411,7 @@ struct lbs_802_11d_domain_reg {
>  	/** No. of triplet*/
>  	u8 no_triplet;
>  	struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D];
> -} __attribute__ ((packed));
> +} __packed;
>  
>  /*
>   * Define data structure for CMD_GET_HW_SPEC



^ permalink raw reply

* Re: [PATCH] rtl8180: improve signal reporting for rtl8185 hardware
From: Pauli Nieminen @ 2010-07-21 17:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <20100721171926.GE2355@tuxdriver.com>

On Wed, Jul 21, 2010 at 8:19 PM, John W. Linville
<linville@tuxdriver.com> wrote:
> On Wed, Jul 21, 2010 at 08:07:56PM +0300, Pauli Nieminen wrote:
>> On Wed, Jul 21, 2010 at 4:33 PM, John W. Linville
>> <linville@tuxdriver.com> wrote:
>> > On Wed, Jul 21, 2010 at 08:08:41AM +0300, Pauli Nieminen wrote:
>> >> On Mon, Jul 19, 2010 at 11:47 PM, John W. Linville
>> >> <linville@tuxdriver.com> wrote:
>> >> > The existing code seemed to be somewhat based on the datasheet, but
>> >> > varied substantially from the vendor-provided driver.  This mirrors the
>> >> > handling of the rtl8185 case from that driver, but still neglects the
>> >> > specifics for the rtl8180 hardware.  Those details are a bit muddled...
>> >> >
>> >> > Signed-off-by: John W. Linville <linville@tuxdriver.com>
>> >> > ---
>> >> >  drivers/net/wireless/rtl818x/rtl8180_dev.c |   11 ++++++++---
>> >> >  1 files changed, 8 insertions(+), 3 deletions(-)
>> >
>> >> I tested this version of patch. Patch didn't apply cleanly for some
>> >> reason even tough when I mnauly typed it diff looks same.
>> >
>> > Please try the v2 version of the patch.  Some "back of the envelope"
>> > math suggests that the v2 version of the patch will give numbers more
>> > to your liking.
>> >
>> > John
>> > --
>> > John W. Linville                Someday the world will need a hero, and you
>> > linville@tuxdriver.com                  might be all we have.  Be ready.
>> >
>>
>> But version 2 doesn't change the fact that driver is going to report
>> same signal strength even tough I know that only one wifi should have
>> 100 % strength and others less than 50 %. There is only one router in
>> same room with me and all others routers are a lot more father away.
>> So driver is either reading wrong bits from hardware or my hardware is
>> broken.
>
> Did you try the patch?  I suspect not.
>
> I can't really decipher what problem you are reporting here with "100 %
> strength and others less than 50 %".  In any case, if you have RTL8185
> hardware then this patch changes the signal calculation to match what
> the Realtek-provided vendor driver does (which doesn't seem to match
> their datasheet, FWIW).  If you have a better source of information
> then I am happy to receive it.
>

I mean that excepted values for signal strength is that single AP has
close 100% signal strength and others should show less than 50%. When
actual result with your 2nd patch is that all APs are reported having
100% signal strength.

Card is old 8180b. I don't have any documentations but I'm just
guessing from values that are coming from hw.
What I see coming from hw it looks signal strength is reported in
flags & 0xfff or flags2 & 0xff. They are only part of those memory
areas that change enough to be field for signal strength.


> If you have RTL8180 (i.e. not RTL8185) hardware then neither version of
> the patch is likely to help you much (beyond avoiding the warning you
> originally reported).  I hope to improve that as well in the future.
>

I understood that patch is only fixing the WARN_ON problem. I don't
really need the signal strength (I have known the strength reporting
bug for quite sometime) so I'm happy with this patch. But I tried to
find if signal strength reporting could be fixed easily same time for
8180 too.

> John
> --
> John W. Linville                Someday the world will need a hero, and you
> linville@tuxdriver.com                  might be all we have.  Be ready.
>

^ permalink raw reply

* [PATCH v2 18/20] mmc: sdio: enable a default power off mode of the card
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add support for an SDIO device to stay powered off even without
the presence of an SDIO function driver. A host should explicitly
ask for it by means of MMC_CAP_DONT_POWER_CARD, and the SDIO
function driver should know it needs to call sdio_claim_power
before accessing the device.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/mmc/core/sdio.c  |   15 +++++++++++++--
 include/linux/mmc/host.h |    1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 5c0fbfa..164353f 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -80,8 +80,9 @@ static int sdio_init_func(struct mmc_card *card, unsigned int fn)
 		return ret;
 
 	/* For each SDIO function initialized, increase the power claim
-	 * reference count of the card */
-	atomic_inc(&card->power_claims);
+	 * reference count of the card, unless explicitly requested not to */
+	if (!(card->host->caps & MMC_CAP_DONT_POWER_CARD))
+		atomic_inc(&card->power_claims);
 
 	return 0;
 
@@ -607,6 +608,16 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
 	mmc_release_host(host);
 
 	/*
+	 * If power is not required for this card, power it off.
+	 * The sdio function will need to call sdio_claim_power.
+	 */
+	if (!atomic_read(&card->power_claims)) {
+		pr_info("%s: power is not claimed, releasing\n",
+						mmc_hostname(host));
+		mmc_release_power(host);
+	}
+
+	/*
 	 * First add the card to the driver model...
 	 */
 	err = mmc_add_card(host->card);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 3675d58..756cf38 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -155,6 +155,7 @@ struct mmc_host {
 #define MMC_CAP_DISABLE		(1 << 7)	/* Can the host be disabled */
 #define MMC_CAP_NONREMOVABLE	(1 << 8)	/* Nonremovable e.g. eMMC */
 #define MMC_CAP_WAIT_WHILE_BUSY	(1 << 9)	/* Waits while card is busy */
+#define MMC_CAP_DONT_POWER_CARD	(1 << 10)	/* Keep the card powered off */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 20/20] wireless: wl1271: call SDIO claim/release power API
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

call SDIO claim/release power API to turn the wl1271
power on and off

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/net/wireless/wl12xx/wl1271_sdio.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 5967718..a7e9ace 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -152,11 +152,13 @@ static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
 	 * alive.
 	 */
 	if (enable) {
+		sdio_claim_power(func);
 		sdio_claim_host(func);
 		sdio_enable_func(func);
 	} else {
 		sdio_disable_func(func);
 		sdio_release_host(func);
+		sdio_release_power(func);
 	}
 
 	return 0;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 19/20] omap: zoom: keep the MMC3 wl1271 device powered off
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Keep the MMC3 wl1271 WLAN device powered off until its
SDIO function driver requests otherwise.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/board-zoom-peripherals.c |    1 +
 arch/arm/mach-omap2/hsmmc.c                  |    3 +++
 arch/arm/mach-omap2/hsmmc.h                  |    1 +
 arch/arm/plat-omap/include/plat/mmc.h        |    3 +++
 drivers/mmc/host/omap_hsmmc.c                |    3 +++
 5 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 3230801..3ab9125 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -217,6 +217,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
 		.gpio_wp	= -EINVAL,
 		.gpio_cd	= -EINVAL,
 		.ocr_mask	= MMC_VDD_165_195,
+		.dont_power_card = true,
 		.priv_data	= &omap_zoom_wlan_data,
 	},
 	{}      /* Terminator */
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index f06ddd2..24c4144 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -284,6 +284,9 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 		if (c->vcc_aux_disable_is_sleep)
 			mmc->slots[0].vcc_aux_disable_is_sleep = 1;
 
+		if (c->dont_power_card)
+			mmc->slots[0].dont_power_card = 1;
+
 		mmc->slots[0].priv_data = c->priv_data;
 
 		/* NOTE:  MMC slots should have a Vcc regulator set up.
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 434a3ed..e200786 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -23,6 +23,7 @@ struct omap2_hsmmc_info {
 	int	ocr_mask;	/* temporary HACK */
 	/* Remux (pad configuation) when powering on/off */
 	void (*remux)(struct device *dev, int slot, int power_on);
+	bool	dont_power_card;/* keep card power off at boot (default is n)*/
 	void	*priv_data;	/* private data to SDIO function driver */
 };
 
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 9db1617..d042494 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -140,6 +140,9 @@ struct omap_mmc_platform_data {
 
 		unsigned int ban_openended:1;
 
+		/* keep this card powered off at boot (default is n) */
+		unsigned int dont_power_card:1;
+
 		/* card private data that should be used by function driver */
 		void *priv_data;
 	} slots[OMAP_MMC_MAX_SLOTS];
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4ac548e..4fb6634 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2157,6 +2157,9 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
 	if (mmc_slot(host).nonremovable)
 		mmc->caps |= MMC_CAP_NONREMOVABLE;
 
+	if (mmc_slot(host).dont_power_card)
+		mmc->caps |= MMC_CAP_DONT_POWER_CARD;
+
 	mmc_set_embedded_data(mmc, mmc_slot(host).priv_data);
 
 	omap_hsmmc_conf_bus_power(host);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 17/20] mmc: sdio: relocate sdio_set_block_size call
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

To support probing of SDIO function driver while the device
is powered off, we need to relocate the sdio_set_block_size call
from the bus probe to an earlier point where we know the device
is still powered. In addition, we want the block size set also
when cards are resumed.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/mmc/core/sdio.c     |   14 +++++++++++++-
 drivers/mmc/core/sdio_bus.c |    9 ---------
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 79e6fa1..5c0fbfa 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -73,6 +73,12 @@ static int sdio_init_func(struct mmc_card *card, unsigned int fn)
 
 	card->sdio_func[fn - 1] = func;
 
+	/* Set the default block size so the driver is sure it's something
+	 * sensible. */
+	ret = sdio_set_block_size(func, 0);
+	if (ret)
+		return ret;
+
 	/* For each SDIO function initialized, increase the power claim
 	 * reference count of the card */
 	atomic_inc(&card->power_claims);
@@ -510,7 +516,13 @@ static int mmc_sdio_resume(struct mmc_host *host)
 		if (func && sdio_func_present(func) && func->dev.driver) {
 			const struct dev_pm_ops *pmops = func->dev.driver->pm;
 
-			if (pmops && pmops->resume)
+			/* Set the default block size so the driver is sure
+			 * it's something sensible. */
+			mmc_claim_host(host);
+			err = sdio_set_block_size(func, 0);
+			mmc_release_host(host);
+
+			if (!err && pmops && pmops->resume)
 				err = pmops->resume(&func->dev);
 		}
 	}
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 4a890dc..87269f6 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -119,20 +119,11 @@ static int sdio_bus_probe(struct device *dev)
 	struct sdio_driver *drv = to_sdio_driver(dev->driver);
 	struct sdio_func *func = dev_to_sdio_func(dev);
 	const struct sdio_device_id *id;
-	int ret;
 
 	id = sdio_match_device(func, drv);
 	if (!id)
 		return -ENODEV;
 
-	/* Set the default block size so the driver is sure it's something
-	 * sensible. */
-	sdio_claim_host(func);
-	ret = sdio_set_block_size(func, 0);
-	sdio_release_host(func);
-	if (ret)
-		return ret;
-
 	return drv->probe(func, id);
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 16/20] mmc: introduce API to control the card's power
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Introduce the sdio_claim_power/sdio_release_power API
(with correspoding mmc_claim_power/mmc_release_power)
that controls the power of the card. A reference count
scheme is employed, to allow SDIO function voting.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/mmc/core/bus.c        |    3 ++
 drivers/mmc/core/core.c       |   50 +++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/core/sdio.c       |    5 ++++
 drivers/mmc/core/sdio_io.c    |   50 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/card.h      |    2 +
 include/linux/mmc/host.h      |    2 +
 include/linux/mmc/sdio_func.h |    3 ++
 7 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 49d9dca..33151d5 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -17,6 +17,7 @@
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
+#include <asm/atomic.h>
 
 #include "core.h"
 #include "sdio_cis.h"
@@ -207,6 +208,8 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type)
 
 	card->host = host;
 
+	atomic_set(&card->power_claims, 0);
+
 	device_initialize(&card->dev);
 
 	card->dev.parent = mmc_classdev(host);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 569e94d..ca5e3bf 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1334,6 +1334,56 @@ EXPORT_SYMBOL(mmc_resume_host);
 
 #endif
 
+/**
+ *	mmc_release_power - remove power from the card
+ *	@host: mmc host
+ */
+int mmc_release_power(struct mmc_host *host)
+{
+	int err = 0;
+
+	mmc_bus_get(host);
+	if (host->bus_ops && !host->bus_dead) {
+		if (host->bus_ops->suspend)
+			err = host->bus_ops->suspend(host);
+			/* it's ok not to have a suspend handler */
+			err = err == -ENOSYS ? 0 : err;
+	}
+	mmc_bus_put(host);
+
+	if (!err)
+		mmc_power_off(host);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mmc_release_power);
+
+/*
+ *	mmc_claim_power - power up card
+ *	@host: mmc host
+ */
+int mmc_claim_power(struct mmc_host *host)
+{
+	int err = 0;
+
+	mmc_bus_get(host);
+
+	mmc_power_up(host);
+	mmc_select_voltage(host, host->ocr);
+
+	BUG_ON(!host->bus_ops->resume);
+	err = host->bus_ops->resume(host);
+	if (err) {
+		printk(KERN_WARNING "%s: error %d during resume "
+					    "(card was removed?)\n",
+					    mmc_hostname(host), err);
+	}
+	mmc_bus_put(host);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mmc_claim_power);
+
 static int __init mmc_init(void)
 {
 	int ret;
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 37739f5..79e6fa1 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -15,6 +15,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
+#include <asm/atomic.h>
 
 #include "core.h"
 #include "bus.h"
@@ -72,6 +73,10 @@ static int sdio_init_func(struct mmc_card *card, unsigned int fn)
 
 	card->sdio_func[fn - 1] = func;
 
+	/* For each SDIO function initialized, increase the power claim
+	 * reference count of the card */
+	atomic_inc(&card->power_claims);
+
 	return 0;
 
 fail:
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 0f687cd..28ebc16 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -17,6 +17,56 @@
 #include "sdio_ops.h"
 
 /**
+ *	sdio_release_power - allow to release power of a certain SDIO function
+ *	@func: SDIO function that is accessed
+ *
+ *	Indicate to the core SDIO layer that we're not requiring that the
+ *	function remain powered.  If all functions for the card are in the
+ *	same "no power" state, then the host controller can remove power from
+ *	the card.  Note: the function driver must preserve hardware states if
+ *	necessary.
+ */
+int sdio_release_power(struct sdio_func *func)
+{
+	int ret = 0;
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	if (atomic_dec_and_test(&func->card->power_claims))
+		ret = mmc_release_power(func->card->host);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_release_power);
+
+/*
+ *	sdio_claim_power - request power for a certain SDIO function
+ *	@func: SDIO function that is accessed
+ *
+ *	Indicate to the core SDIO layer that we want power back for this
+ *	SDIO function.  The power may or may not actually have been removed
+ *	since last call to sdio_release_power(), so the function driver must
+ *	not assume any preserved state at the hardware level and re-perform
+ *	all the necessary hardware config.  This function returns 0 when
+ *	power is actually restored, or some error code if this cannot be
+ *	achieved.  One error reason might be that the card is no longer
+ *	available on the bus (was removed while powered down and card
+ *	detection didn't trigger yet).
+ */
+int sdio_claim_power(struct sdio_func *func)
+{
+	int ret = 0;
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	if (atomic_inc_return(&func->card->power_claims) == 1)
+		ret = mmc_claim_power(func->card->host);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_claim_power);
+
+/**
  *	sdio_claim_host - exclusively claim a bus for a certain SDIO function
  *	@func: SDIO function that will be accessed
  *
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index d02d2c6..4073b43 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -11,6 +11,7 @@
 #define LINUX_MMC_CARD_H
 
 #include <linux/mmc/core.h>
+#include <asm/atomic.h>
 
 struct mmc_cid {
 	unsigned int		manfid;
@@ -120,6 +121,7 @@ struct mmc_card {
 	struct sdio_func_tuple	*tuples;	/* unknown common tuples */
 
 	struct dentry		*debugfs_root;
+	atomic_t		power_claims;	/* ref count of power requests */
 };
 
 #define mmc_card_mmc(c)		((c)->type == MMC_TYPE_MMC)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 80db597..3675d58 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -234,6 +234,8 @@ static inline void *mmc_priv(struct mmc_host *host)
 
 extern int mmc_suspend_host(struct mmc_host *);
 extern int mmc_resume_host(struct mmc_host *);
+extern int mmc_release_power(struct mmc_host *);
+extern int mmc_claim_power(struct mmc_host *);
 
 extern void mmc_power_save_host(struct mmc_host *host);
 extern void mmc_power_restore_host(struct mmc_host *host);
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index 31baaf8..e77b676 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -116,6 +116,9 @@ extern void sdio_unregister_driver(struct sdio_driver *);
 /*
  * SDIO I/O operations
  */
+int sdio_claim_power(struct sdio_func *func);
+int sdio_release_power(struct sdio_func *func);
+
 extern void sdio_claim_host(struct sdio_func *func);
 extern void sdio_release_host(struct sdio_func *func);
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 15/20] mmc: sdio: verify existence of resume handler
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Before invoking a card's resume handler, verify one exists.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/mmc/core/sdio.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 645f173..37739f5 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -504,7 +504,9 @@ static int mmc_sdio_resume(struct mmc_host *host)
 		struct sdio_func *func = host->card->sdio_func[i];
 		if (func && sdio_func_present(func) && func->dev.driver) {
 			const struct dev_pm_ops *pmops = func->dev.driver->pm;
-			err = pmops->resume(&func->dev);
+
+			if (pmops && pmops->resume)
+				err = pmops->resume(&func->dev);
 		}
 	}
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 14/20] mmc: sdio: fully reconfigure oldcard on resume
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

On resume, let mmc_sdio_init_card go all the way, instead
of skipping the reconfiguration of the card's speed and width.

This is needed to ensure cards wake up with their clock
reconfigured (otherwise it's kept low).

This patch also removes the explicit bus width reconfiguration
on resume, since now this is part of mmc_sdio_init_card.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/mmc/core/sdio.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index b9dee28..645f173 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -344,7 +344,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
 			goto err;
 		}
 		card = oldcard;
-		return 0;
 	}
 
 	/*
@@ -487,9 +486,6 @@ static int mmc_sdio_resume(struct mmc_host *host)
 	mmc_claim_host(host);
 	err = mmc_sdio_init_card(host, host->ocr, host->card,
 				 (host->pm_flags & MMC_PM_KEEP_POWER));
-	if (!err)
-		/* We may have switched to 1-bit mode during suspend. */
-		err = sdio_enable_wide(host->card);
 	if (!err && host->sdio_irqs)
 		mmc_signal_sdio_irq(host);
 	mmc_release_host(host);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 13/20] omap: zoom: add mmc3/wl1271 device support
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add MMC3 support on ZOOM, which has the wl1271 device hardwired to.

The wl1271 is a 4-wire, 1.8V, embedded SDIO WLAN device with an
external IRQ line, and power-controlled by a GPIO-based fixed regulator.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/board-zoom-peripherals.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 2fc0f4a..3230801 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -17,6 +17,8 @@
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
+#include <linux/mmc/host.h>
+#include <linux/wl12xx.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -29,6 +31,7 @@
 #include "hsmmc.h"
 
 #define OMAP_ZOOM_WLAN_PMENA_GPIO	(101)
+#define OMAP_ZOOM_WLAN_IRQ_GPIO		(162)
 
 /* Zoom2 has Qwerty keyboard*/
 static int board_keymap[] = {
@@ -184,6 +187,12 @@ static struct platform_device omap_vwlan_device = {
 	},
 };
 
+struct wl12xx_platform_data omap_zoom_wlan_data = {
+	.irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
+	/* ZOOM ref clock is 26 MHz */
+	.board_ref_clock = 1,
+};
+
 static struct omap2_hsmmc_info mmc[] __initdata = {
 	{
 		.name		= "external",
@@ -201,6 +210,15 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
 		.nonremovable	= true,
 		.power_saving	= true,
 	},
+	{
+		.name		= "wl1271",
+		.mmc		= 3,
+		.wires		= 4,
+		.gpio_wp	= -EINVAL,
+		.gpio_cd	= -EINVAL,
+		.ocr_mask	= MMC_VDD_165_195,
+		.priv_data	= &omap_zoom_wlan_data,
+	},
 	{}      /* Terminator */
 };
 
@@ -217,6 +235,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
 	zoom_vmmc1_supply.dev = mmc[0].dev;
 	zoom_vsim_supply.dev = mmc[0].dev;
 	zoom_vmmc2_supply.dev = mmc[1].dev;
+	zoom_vmmc3_supply.dev = mmc[2].dev;
 
 	return 0;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 12/20] omap: hsmmc: allow board-specific settings of private mmc data
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Allow board-specific settings of private mmc data, in order to
allow embedded SDIO devices to communicate board-specific parameters
to the SDIO function driver (e.g., the external IRQ line of the wl1271).

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/hsmmc.c           |    2 ++
 arch/arm/mach-omap2/hsmmc.h           |    1 +
 arch/arm/plat-omap/include/plat/mmc.h |    2 ++
 drivers/mmc/host/omap_hsmmc.c         |    2 ++
 4 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 5d3d789..f06ddd2 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -284,6 +284,8 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 		if (c->vcc_aux_disable_is_sleep)
 			mmc->slots[0].vcc_aux_disable_is_sleep = 1;
 
+		mmc->slots[0].priv_data = c->priv_data;
+
 		/* NOTE:  MMC slots should have a Vcc regulator set up.
 		 * This may be from a TWL4030-family chip, another
 		 * controllable regulator, or a fixed supply.
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 36f0ba8..434a3ed 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -23,6 +23,7 @@ struct omap2_hsmmc_info {
 	int	ocr_mask;	/* temporary HACK */
 	/* Remux (pad configuation) when powering on/off */
 	void (*remux)(struct device *dev, int slot, int power_on);
+	void	*priv_data;	/* private data to SDIO function driver */
 };
 
 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index c835f1e..9db1617 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -140,6 +140,8 @@ struct omap_mmc_platform_data {
 
 		unsigned int ban_openended:1;
 
+		/* card private data that should be used by function driver */
+		void *priv_data;
 	} slots[OMAP_MMC_MAX_SLOTS];
 };
 
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4c5a669..4ac548e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2157,6 +2157,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
 	if (mmc_slot(host).nonremovable)
 		mmc->caps |= MMC_CAP_NONREMOVABLE;
 
+	mmc_set_embedded_data(mmc, mmc_slot(host).priv_data);
+
 	omap_hsmmc_conf_bus_power(host);
 
 	/* Select DMA lines */
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 11/20] omap: hsmmc: support mmc3 regulator power control
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Prepare for mmc3 regulator power control by splitting the power
control functions of mmc2 and mmc3, and expecting mmc3 to have
a single, dedicated, regulator support.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/hsmmc.c   |   10 ++++--
 drivers/mmc/host/omap_hsmmc.c |   67 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 1ef54b0..5d3d789 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -174,7 +174,7 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
 	}
 }
 
-static void hsmmc23_before_set_reg(struct device *dev, int slot,
+static void hsmmc2_before_set_reg(struct device *dev, int slot,
 				   int power_on, int vdd)
 {
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
@@ -325,14 +325,16 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 				c->transceiver = 1;
 			if (c->transceiver && c->wires > 4)
 				c->wires = 4;
-			/* FALLTHROUGH */
-		case 3:
 			if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
 				/* off-chip level shifting, or none */
-				mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
+				mmc->slots[0].before_set_reg = hsmmc2_before_set_reg;
 				mmc->slots[0].after_set_reg = NULL;
 			}
 			break;
+		case 3:
+			mmc->slots[0].before_set_reg = NULL;
+			mmc->slots[0].after_set_reg = NULL;
+			break;
 		default:
 			pr_err("MMC%d configuration not supported!\n", c->mmc);
 			kfree(mmc);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b032828..4c5a669 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -258,7 +258,7 @@ static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on,
 	return ret;
 }
 
-static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on,
+static int omap_hsmmc_2_set_power(struct device *dev, int slot, int power_on,
 				   int vdd)
 {
 	struct omap_hsmmc_host *host =
@@ -309,6 +309,31 @@ static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on,
 	return ret;
 }
 
+static int omap_hsmmc_3_set_power(struct device *dev, int slot, int power_on,
+				   int vdd)
+{
+	struct omap_hsmmc_host *host =
+		platform_get_drvdata(to_platform_device(dev));
+	int ret = 0;
+
+	if (power_on) {
+		ret = mmc_regulator_set_ocr(host->vcc, vdd);
+		/* Enable interface voltage rail, if needed */
+		if (ret == 0 && host->vcc) {
+			ret = regulator_enable(host->vcc);
+			if (ret < 0)
+				ret = mmc_regulator_set_ocr(host->vcc, 0);
+		}
+	} else {
+		if (host->vcc)
+			ret = regulator_disable(host->vcc);
+		if (ret == 0)
+			ret = mmc_regulator_set_ocr(host->vcc, 0);
+	}
+
+	return ret;
+}
+
 static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep,
 				  int vdd, int cardsleep)
 {
@@ -319,7 +344,7 @@ static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep,
 	return regulator_set_mode(host->vcc, mode);
 }
 
-static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep,
+static int omap_hsmmc_2_set_sleep(struct device *dev, int slot, int sleep,
 				   int vdd, int cardsleep)
 {
 	struct omap_hsmmc_host *host =
@@ -358,6 +383,31 @@ static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep,
 		return regulator_enable(host->vcc_aux);
 }
 
+static int omap_hsmmc_3_set_sleep(struct device *dev, int slot, int sleep,
+				   int vdd, int cardsleep)
+{
+	struct omap_hsmmc_host *host =
+		platform_get_drvdata(to_platform_device(dev));
+	int err = 0;
+
+	/*
+	 * If we don't see a Vcc regulator, assume it's a fixed
+	 * voltage always-on regulator.
+	 */
+	if (!host->vcc)
+		return 0;
+
+	if (cardsleep) {
+		/* VCC can be turned off if card is asleep */
+		if (sleep)
+			err = mmc_regulator_set_ocr(host->vcc, 0);
+		else
+			err = mmc_regulator_set_ocr(host->vcc, vdd);
+	}
+
+	return err;
+}
+
 static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
 	struct regulator *reg;
@@ -370,10 +420,13 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 		mmc_slot(host).set_sleep = omap_hsmmc_1_set_sleep;
 		break;
 	case OMAP_MMC2_DEVID:
-	case OMAP_MMC3_DEVID:
 		/* Off-chip level shifting, or none */
-		mmc_slot(host).set_power = omap_hsmmc_23_set_power;
-		mmc_slot(host).set_sleep = omap_hsmmc_23_set_sleep;
+		mmc_slot(host).set_power = omap_hsmmc_2_set_power;
+		mmc_slot(host).set_sleep = omap_hsmmc_2_set_sleep;
+		break;
+	case OMAP_MMC3_DEVID:
+		mmc_slot(host).set_power = omap_hsmmc_3_set_power;
+		mmc_slot(host).set_sleep = omap_hsmmc_3_set_sleep;
 		break;
 	default:
 		pr_err("MMC%d configuration not supported!\n", host->id);
@@ -386,9 +439,9 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 		/*
 		* HACK: until fixed.c regulator is usable,
 		* we don't require a main regulator
-		* for MMC2 or MMC3
+		* for MMC2
 		*/
-		if (host->id == OMAP_MMC1_DEVID) {
+		if (host->id != OMAP_MMC2_DEVID) {
 			ret = PTR_ERR(reg);
 			goto err;
 		}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 10/20] omap: zoom: add fixed regulator device for wlan
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add a fixed regulator vmmc device to enable power control
of the wl1271 wlan device.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/board-zoom-peripherals.c |   34 ++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 6b39849..2fc0f4a 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -16,6 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -27,6 +28,8 @@
 #include "mux.h"
 #include "hsmmc.h"
 
+#define OMAP_ZOOM_WLAN_PMENA_GPIO	(101)
+
 /* Zoom2 has Qwerty keyboard*/
 static int board_keymap[] = {
 	KEY(0, 0, KEY_E),
@@ -106,6 +109,10 @@ static struct regulator_consumer_supply zoom_vmmc2_supply = {
 	.supply		= "vmmc",
 };
 
+static struct regulator_consumer_supply zoom_vmmc3_supply = {
+	.supply		= "vmmc",
+};
+
 /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
 static struct regulator_init_data zoom_vmmc1 = {
 	.constraints = {
@@ -151,6 +158,32 @@ static struct regulator_init_data zoom_vsim = {
 	.consumer_supplies      = &zoom_vsim_supply,
 };
 
+static struct regulator_init_data zoom_vmmc3 = {
+	.constraints = {
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = 1,
+	.consumer_supplies = &zoom_vmmc3_supply,
+};
+
+static struct fixed_voltage_config zoom_vwlan = {
+	.supply_name = "vwl1271",
+	.microvolts = 1800000, /* 1.8V */
+	.gpio = OMAP_ZOOM_WLAN_PMENA_GPIO,
+	.startup_delay = 70000, /* 70msec */
+	.enable_high = 1,
+	.enabled_at_boot = 0,
+	.init_data = &zoom_vmmc3,
+};
+
+static struct platform_device omap_vwlan_device = {
+	.name		= "reg-fixed-voltage",
+	.id		= 1,
+	.dev = {
+		.platform_data = &zoom_vwlan,
+	},
+};
+
 static struct omap2_hsmmc_info mmc[] __initdata = {
 	{
 		.name		= "external",
@@ -280,6 +313,7 @@ static void enable_board_wakeup_source(void)
 void __init zoom_peripherals_init(void)
 {
 	omap_i2c_init();
+	platform_device_register(&omap_vwlan_device);
 	usb_musb_init(&musb_board_data);
 	enable_board_wakeup_source();
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 09/20] wireless: wl1271: make ref_clock configurable by board
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

The wl1271 device is using a reference clock that may change
between board to board.

Make the ref_clock parameter configurable by the board
files that set up the device, instead of having a hard coded
value in the driver source itself.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/net/wireless/wl12xx/wl1271.h      |    1 +
 drivers/net/wireless/wl12xx/wl1271_boot.c |    9 +++++----
 drivers/net/wireless/wl12xx/wl1271_boot.h |    1 -
 drivers/net/wireless/wl12xx/wl1271_sdio.c |    7 ++++---
 drivers/net/wireless/wl12xx/wl1271_spi.c  |    2 ++
 include/linux/wl12xx.h                    |    1 +
 6 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index a21cdb2..595f1a8 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -357,6 +357,7 @@ struct wl1271 {
 
 	void (*set_power)(bool enable);
 	int irq;
+	int ref_clock;
 
 	spinlock_t wl_lock;
 
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 1a36d8a..d3f0521 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -455,17 +455,18 @@ int wl1271_boot(struct wl1271 *wl)
 {
 	int ret = 0;
 	u32 tmp, clk, pause;
+	int ref_clock = wl->ref_clock;
 
 	wl1271_boot_hw_version(wl);
 
-	if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
+	if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4)
 		/* ref clk: 19.2/38.4/38.4-XTAL */
 		clk = 0x3;
-	else if (REF_CLOCK == 1 || REF_CLOCK == 3)
+	else if (ref_clock == 1 || ref_clock == 3)
 		/* ref clk: 26/52 */
 		clk = 0x5;
 
-	if (REF_CLOCK != 0) {
+	if (ref_clock != 0) {
 		u16 val;
 		/* Set clock type (open drain) */
 		val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -514,7 +515,7 @@ int wl1271_boot(struct wl1271 *wl)
 	wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
 
 	/* 2 */
-	clk |= (REF_CLOCK << 1) << 4;
+	clk |= (ref_clock << 1) << 4;
 	wl1271_write32(wl, DRPW_SCRATCH_START, clk);
 
 	wl1271_set_partition(wl, &part_table[PART_WORK]);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index f829699..f73b0b1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -46,7 +46,6 @@ struct wl1271_static_data {
 /* delay between retries */
 #define INIT_LOOP_DELAY 50
 
-#define REF_CLOCK            2
 #define WU_COUNTER_PAUSE_VAL 0x3FF
 #define WELP_ARM_COMMAND_VAL 0x4
 
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 75901a6..5967718 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -198,11 +198,12 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
 	wlan_data = mmc_get_embedded_data(func->card->host);
-	if (wlan_data && wlan_data->irq)
+	if (wlan_data) {
 		wl->irq = wlan_data->irq;
-	else {
+		wl->ref_clock = wlan_data->board_ref_clock;
+	} else {
 		ret = -EINVAL;
-		wl1271_error("could not get irq!");
+		wl1271_error("missing wlan data (needed for irq/ref_clk)!");
 		goto out_free;
 	}
 
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 85a167f..501b8b4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -373,6 +373,8 @@ static int __devinit wl1271_probe(struct spi_device *spi)
 		goto out_free;
 	}
 
+	wl->ref_clock = pdata->board_ref_clock;
+
 	wl->irq = spi->irq;
 	if (wl->irq < 0) {
 		wl1271_error("irq missing in platform data");
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 137ac89..ef6eed9 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -29,6 +29,7 @@ struct wl12xx_platform_data {
 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
 	int irq;
 	bool use_eeprom;
+	int board_ref_clock;
 };
 
 #endif
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 08/20] wireless: wl1271: take irq info from private board data
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Remove the hard coded irq information, and instead take
the irq information from the board private data
which is supplied by the sdio function.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/net/wireless/wl12xx/wl1271_sdio.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 571c6b9..75901a6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -28,15 +28,14 @@
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/wl12xx.h>
 #include <plat/gpio.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
 #include "wl1271_io.h"
 
-
-#define RX71_WL1271_IRQ_GPIO		42
-
 static const struct sdio_device_id wl1271_devices[] = {
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
 	{}
@@ -178,6 +177,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 				  const struct sdio_device_id *id)
 {
 	struct ieee80211_hw *hw;
+	struct wl12xx_platform_data *wlan_data;
 	struct wl1271 *wl;
 	int ret;
 
@@ -197,9 +197,11 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 	/* Grab access to FN0 for ELP reg. */
 	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
-	wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO);
-	if (wl->irq < 0) {
-		ret = wl->irq;
+	wlan_data = mmc_get_embedded_data(func->card->host);
+	if (wlan_data && wlan_data->irq)
+		wl->irq = wlan_data->irq;
+	else {
+		ret = -EINVAL;
 		wl1271_error("could not get irq!");
 		goto out_free;
 	}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 07/20] wireless: wl1271: support return value for the set power func
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Make it possible for the set power method to indicate a
success/failure return value. This is needed to support
more complex power on/off operations such as bringing up
(and down) sdio functions.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/net/wireless/wl12xx/wl1271.h      |    2 +-
 drivers/net/wireless/wl12xx/wl1271_io.h   |    8 +++++---
 drivers/net/wireless/wl12xx/wl1271_main.c |    4 +++-
 drivers/net/wireless/wl12xx/wl1271_sdio.c |    4 +++-
 drivers/net/wireless/wl12xx/wl1271_spi.c  |    4 +++-
 5 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 6f1b6b5..a21cdb2 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -340,7 +340,7 @@ struct wl1271_if_operations {
 		     bool fixed);
 	void (*reset)(struct wl1271 *wl);
 	void (*init)(struct wl1271 *wl);
-	void (*power)(struct wl1271 *wl, bool enable);
+	int (*power)(struct wl1271 *wl, bool enable);
 	struct device* (*dev)(struct wl1271 *wl);
 	void (*enable_irq)(struct wl1271 *wl);
 	void (*disable_irq)(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index bc806c7..4a5b92c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -144,10 +144,12 @@ static inline void wl1271_power_off(struct wl1271 *wl)
 	clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 }
 
-static inline void wl1271_power_on(struct wl1271 *wl)
+static inline int wl1271_power_on(struct wl1271 *wl)
 {
-	wl->if_ops->power(wl, true);
-	set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+	int ret = wl->if_ops->power(wl, true);
+	if (ret == 0)
+		set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+	return ret;
 }
 
 
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index b7d9137..6bd748e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -620,7 +620,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
 	int ret = 0;
 
 	msleep(WL1271_PRE_POWER_ON_SLEEP);
-	wl1271_power_on(wl);
+	ret = wl1271_power_on(wl);
+	if (ret < 0)
+		goto out;
 	msleep(WL1271_POWER_ON_SLEEP);
 	wl1271_io_reset(wl);
 	wl1271_io_init(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 9903ae9..571c6b9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -144,7 +144,7 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
 
 }
 
-static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
 {
 	struct sdio_func *func = wl_to_func(wl);
 
@@ -159,6 +159,8 @@ static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
 		sdio_disable_func(func);
 		sdio_release_host(func);
 	}
+
+	return 0;
 }
 
 static struct wl1271_if_operations sdio_ops = {
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index e866049..85a167f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -313,10 +313,12 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
 	return IRQ_HANDLED;
 }
 
-static void wl1271_spi_set_power(struct wl1271 *wl, bool enable)
+static int wl1271_spi_set_power(struct wl1271 *wl, bool enable)
 {
 	if (wl->set_power)
 		wl->set_power(enable);
+
+	return 0;
 }
 
 static struct wl1271_if_operations spi_ops = {
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 06/20] wireless: wl1271: make wl12xx.h common to both spi and sdio
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Move wl12xx.h outside of the spi-specific location,
so it can be shared with both spi and sdio solutions.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/net/wireless/wl12xx/wl1251_sdio.c |    2 +-
 drivers/net/wireless/wl12xx/wl1251_spi.c  |    2 +-
 drivers/net/wireless/wl12xx/wl1271_spi.c  |    2 +-
 include/linux/spi/wl12xx.h                |   34 -----------------------------
 include/linux/wl12xx.h                    |   34 +++++++++++++++++++++++++++++
 5 files changed, 37 insertions(+), 37 deletions(-)
 delete mode 100644 include/linux/spi/wl12xx.h
 create mode 100644 include/linux/wl12xx.h

diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index c561332..416d5aa 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -24,7 +24,7 @@
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
 #include <linux/platform_device.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
 #include <linux/irq.h>
 
 #include "wl1251.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index e814742..4847b6a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -26,7 +26,7 @@
 #include <linux/slab.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
 
 #include "wl1251.h"
 #include "wl1251_reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 5189b81..e866049 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -25,7 +25,7 @@
 #include <linux/module.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
 #include <linux/slab.h>
 
 #include "wl1271.h"
diff --git a/include/linux/spi/wl12xx.h b/include/linux/spi/wl12xx.h
deleted file mode 100644
index a223ecb..0000000
--- a/include/linux/spi/wl12xx.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _LINUX_SPI_WL12XX_H
-#define _LINUX_SPI_WL12XX_H
-
-struct wl12xx_platform_data {
-	void (*set_power)(bool enable);
-	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
-	int irq;
-	bool use_eeprom;
-};
-
-#endif
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
new file mode 100644
index 0000000..137ac89
--- /dev/null
+++ b/include/linux/wl12xx.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _LINUX_WL12XX_H
+#define _LINUX_WL12XX_H
+
+struct wl12xx_platform_data {
+	void (*set_power)(bool enable);
+	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
+	int irq;
+	bool use_eeprom;
+};
+
+#endif
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 05/20] omap zoom3: wlan board muxing
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add board muxing to support the wlan wl1271 chip that is
hardwired to mmc2 (third mmc controller) on the ZOOM3.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/board-zoom3.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index 3314704..7d17046 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -46,6 +46,19 @@ static void __init omap_zoom_init_irq(void)
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+	/* WLAN IRQ - GPIO 162 */
+	OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+	/* WLAN POWER ENABLE - GPIO 101 */
+	OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+	/* WLAN SDIO: MMC3 CMD */
+	OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+	/* WLAN SDIO: MMC3 CLK */
+	OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	/* WLAN SDIO: MMC3 DAT[0-3] */
+	OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 04/20] omap zoom2: wlan board muxing
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add board muxing to support the wlan wl1271 chip that is
hardwired to mmc2 (third mmc controller) on the ZOOM2.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/board-zoom2.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 803ef14..1520a2c 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -71,6 +71,19 @@ static struct twl4030_platform_data zoom2_twldata = {
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+	/* WLAN IRQ - GPIO 162 */
+	OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+	/* WLAN POWER ENABLE - GPIO 101 */
+	OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+	/* WLAN SDIO: MMC3 CMD */
+	OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+	/* WLAN SDIO: MMC3 CLK */
+	OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	/* WLAN SDIO: MMC3 DAT[0-3] */
+	OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+	OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 03/20] mmc: support embedded data field in mmc_host
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add support to set/get mmc_host private embedded
data.

This is needed to allow software to dynamically
create (and remove) SDIO functions which represents
embedded SDIO devices.

Typically, it will be used to set the context of
a driver that is creating a new SDIO function
(and would then expect to be able to get that context
back upon creation of the new sdio func).

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 include/linux/mmc/host.h |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index f65913c..80db597 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -209,6 +209,8 @@ struct mmc_host {
 	struct led_trigger	*led;		/* activity led */
 #endif
 
+	void			*embedded_data;
+
 	struct dentry		*debugfs_root;
 
 	unsigned long		private[0] ____cacheline_aligned;
@@ -264,5 +266,15 @@ static inline void mmc_set_disable_delay(struct mmc_host *host,
 	host->disable_delay = disable_delay;
 }
 
+static inline void *mmc_get_embedded_data(struct mmc_host *host)
+{
+	return host->embedded_data;
+}
+
+static inline void mmc_set_embedded_data(struct mmc_host *host, void *data)
+{
+	host->embedded_data = data;
+}
+
 #endif
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 02/20] wireless: wl1271: remove SDIO IDs from driver
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Remove SDIO IDs from the driver code since now it is
included in linux/mmc/sdio_ids.h.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/net/wireless/wl12xx/wl1271_sdio.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index d3d6f30..9903ae9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -37,14 +37,6 @@
 
 #define RX71_WL1271_IRQ_GPIO		42
 
-#ifndef SDIO_VENDOR_ID_TI
-#define SDIO_VENDOR_ID_TI		0x0097
-#endif
-
-#ifndef SDIO_DEVICE_ID_TI_WL1271
-#define SDIO_DEVICE_ID_TI_WL1271	0x4076
-#endif
-
 static const struct sdio_device_id wl1271_devices[] = {
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
 	{}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 01/20] sdio: add TI + wl1271 ids
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen
In-Reply-To: <1279733634-21974-1-git-send-email-ohad@wizery.com>

Add SDIO IDs for TI and for TI's wl1271 wlan device.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 include/linux/mmc/sdio_ids.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 33b2ea0..0d313c6 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -43,4 +43,7 @@
 #define SDIO_DEVICE_ID_SIANO_NOVA_A0		0x1100
 #define SDIO_DEVICE_ID_SIANO_STELLAR 		0x5347
 
+#define SDIO_VENDOR_ID_TI			0x0097
+#define SDIO_DEVICE_ID_TI_WL1271		0x4076
+
 #endif
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Ohad Ben-Cohen @ 2010-07-21 17:33 UTC (permalink / raw)
  To: linux-wireless, linux-mmc, linux-omap
  Cc: linux-arm-kernel, linux, Chikkature Rajashekar Madhusudhan,
	Luciano Coelho, akpm, San Mehat, Roger Quadros, Tony Lindgren,
	Nicolas Pitre, Pandita Vikram, Kalle Valo, Ohad Ben-Cohen

This patch series adds native support for wl1271 on ZOOM.

Changes since v1:

- introduce a fixed regulator device to control the power of wl1271
- allow to propagate private board-specific data to SDIO function drivers
- allow SDIO function driver to control the card's power via new API
- make it possible to keep the card's power down (without depending
  on an explicit SDIO function driver power-down request)

Thanks to these changes, we no longer need a separate platform
device (carrying e.g. the external irq information of the device),
and no longer need to emulate virtual card detect events.

The two "board muxing" pathces were already taken by Tony, and
are resent here just to make it easier for people to use/test these pathces.

The changes to the MMC core really needs careful review; there still
might be some pitfalls that haven't been covered. E.g., one thing
we plan to look at next is their bahvior together with SDIO Suspend/Resume.

Special thanks to Roger Quadros and Nicolas Pitre for their extensive
review and helpful suggestions.

The patches are based on 2.6.35-rc5, and were tested on ZOOM3.

Thanks,

Ohad Ben-Cohen (20):
  sdio: add TI + wl1271 ids
  wireless: wl1271: remove SDIO IDs from driver
  mmc: support embedded data field in mmc_host
  omap zoom2: wlan board muxing
  omap zoom3: wlan board muxing
  wireless: wl1271: make wl12xx.h common to both spi and sdio
  wireless: wl1271: support return value for the set power func
  wireless: wl1271: take irq info from private board data
  wireless: wl1271: make ref_clock configurable by board
  omap: zoom: add fixed regulator device for wlan
  omap: hsmmc: support mmc3 regulator power control
  omap: hsmmc: allow board-specific settings of private mmc data
  omap: zoom: add mmc3/wl1271 device support
  mmc: sdio: fully reconfigure oldcard on resume
  mmc: sdio: verify existence of resume handler
  mmc: introduce API to control the card's power
  mmc: sdio: relocate sdio_set_block_size call
  mmc: sdio: enable a default power off mode of the card
  omap: zoom: keep the MMC3 wl1271 device powered off
  wireless: wl1271: call SDIO claim/release power API

 arch/arm/mach-omap2/board-zoom-peripherals.c |   54 +++++++++++++++++++
 arch/arm/mach-omap2/board-zoom2.c            |   13 +++++
 arch/arm/mach-omap2/board-zoom3.c            |   13 +++++
 arch/arm/mach-omap2/hsmmc.c                  |   15 ++++--
 arch/arm/mach-omap2/hsmmc.h                  |    2 +
 arch/arm/plat-omap/include/plat/mmc.h        |    5 ++
 drivers/mmc/core/bus.c                       |    3 +
 drivers/mmc/core/core.c                      |   50 ++++++++++++++++++
 drivers/mmc/core/sdio.c                      |   36 +++++++++++--
 drivers/mmc/core/sdio_bus.c                  |    9 ---
 drivers/mmc/core/sdio_io.c                   |   50 ++++++++++++++++++
 drivers/mmc/host/omap_hsmmc.c                |   72 +++++++++++++++++++++++---
 drivers/net/wireless/wl12xx/wl1251_sdio.c    |    2 +-
 drivers/net/wireless/wl12xx/wl1251_spi.c     |    2 +-
 drivers/net/wireless/wl12xx/wl1271.h         |    3 +-
 drivers/net/wireless/wl12xx/wl1271_boot.c    |    9 ++--
 drivers/net/wireless/wl12xx/wl1271_boot.h    |    1 -
 drivers/net/wireless/wl12xx/wl1271_io.h      |    8 ++-
 drivers/net/wireless/wl12xx/wl1271_main.c    |    4 +-
 drivers/net/wireless/wl12xx/wl1271_sdio.c    |   31 +++++------
 drivers/net/wireless/wl12xx/wl1271_spi.c     |    8 ++-
 include/linux/mmc/card.h                     |    2 +
 include/linux/mmc/host.h                     |   15 +++++
 include/linux/mmc/sdio_func.h                |    3 +
 include/linux/mmc/sdio_ids.h                 |    3 +
 include/linux/spi/wl12xx.h                   |   34 ------------
 include/linux/wl12xx.h                       |   35 ++++++++++++
 27 files changed, 393 insertions(+), 89 deletions(-)
 delete mode 100644 include/linux/spi/wl12xx.h
 create mode 100644 include/linux/wl12xx.h


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox