* Re: [PATCH] ath10k: Fix crash when using v1 hardware.
From: Ben Greear @ 2013-07-02 23:08 UTC (permalink / raw)
To: ath9k-devel; +Cc: linux-wireless
In-Reply-To: <1372804925-1701-1-git-send-email-greearb@candelatech.com>
Actually, I have no idea what type of hardware this is. It was
suggested earlier to me that this AP had a v1 hardware in it, but
lspci shows this fairly unpromising thing, and the ath10k driver
appears to call 003c the V2 hardware....
05:00.0 Network controller: Atheros Communications Inc. Device 003c (rev ff) (prog-if ff)
!!! Unknown header type 7f
Kernel modules: ath10k_pci
On 07/02/2013 03:42 PM, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> I put a v1 NIC from an TP-LINK AC 1750 AP in
> a 64-bit PC, and the OS crashes on bootup. I'm not
> sure how broken my hardware is (possibly completely non
> functional), but at least with this patch it will no longer
> crash the OS. Not sure it ever got far enough to try,
> but I also do not have firmware for the NIC.
>
> With this patch I get this info on module load:
>
> ath10k_pci 0000:05:00.0: BAR 0: assigned [mem 0xf4400000-0xf45fffff 64bit]
> ath10k_pci 0000:05:00.0: BAR 0: error updating (0xf4400004 != 0xffffffff)
> ath10k_pci 0000:05:00.0: BAR 0: error updating (high 0x000000 != 0xffffffff)
> ath10k_pci 0000:05:00.0: Refused to change power state, currently in D3
> ath10k: MSI-X interrupt handling (8 intrs)
> ath10k: Unable to wakeup target
> ath10k: target takes too long to wake up (awake count 1)
> ath10k: src_ring ffff88020c0d0a00: write_index is out of bounds: 4294967295 nentries_mask: 15.
> ath10k: dest_ring ffff88020db2c000: write_index is out of bounds: 4294967295 nentries_mask: 511.
> ath10k: dest_ring ffff880210d56400: write_index is out of bounds: 4294967295 nentries_mask: 31.
> ath10k: src_ring ffff880210d57600: write_index is out of bounds: 4294967295 nentries_mask: 31.
> ath10k: src_ring ffff88020fe70000: write_index is out of bounds: 4294967295 nentries_mask: 2047.
> ath10k: src_ring ffff880212989b40: write_index is out of bounds: 4294967295 nentries_mask: 1.
> ath10k: dest_ring ffff880212989960: write_index is out of bounds: 4294967295 nentries_mask: 1.
> ath10k: Failed to get pcie state addr: -5
> ath10k: early firmware event indicated
> ------------[ cut here ]------------
> WARNING: at /home/greearb/git/linux.wireless-testing/drivers/net/wireless/ath/ath10k/ce.c:771 ath10k_ce_per_engine_service+0x53/0x1b4 [ath10k_pci]()
> ....
> (it hits the warning case about 5-6 times and then seems to quiesce OK).
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> drivers/net/wireless/ath/ath10k/ce.c | 32 +++++++++++++++++++++++++++++++-
> 1 files changed, 31 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
> index 61a8ac7..56669f8 100644
> --- a/drivers/net/wireless/ath/ath10k/ce.c
> +++ b/drivers/net/wireless/ath/ath10k/ce.c
> @@ -756,13 +756,23 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
> {
> struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
> struct ce_state *ce_state = ar_pci->ce_id_to_state[ce_id];
> - u32 ctrl_addr = ce_state->ctrl_addr;
> + u32 ctrl_addr;
> void *transfer_context;
> u32 buf;
> unsigned int nbytes;
> unsigned int id;
> unsigned int flags;
>
> + /* On v1 hardware at least, setup can fail, causing ce_id_state to
> + * be cleaned up, but this method is still called a few times. Check
> + * for NULL here so we don't crash. Probably a better fix is to stop
> + * the ath10k_pci_ce_tasklet sooner.
> + */
> + if (WARN_ONCE(!ce_state, "ce_id_to_state[%i] is NULL\n", ce_id))
> + return;
> +
> + ctrl_addr = ce_state->ctrl_addr;
> +
> ath10k_pci_wake(ar);
> spin_lock_bh(&ar_pci->ce_lock);
>
> @@ -954,6 +964,16 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
>
> src_ring->write_index =
> ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
> + /* Make sure the value above is sane. Can get 0xFFFFFFFF
> + * on a v1 board.
> + */
> + if (src_ring->write_index > src_ring->nentries_mask) {
> + ath10k_err("src_ring %p: write_index is out of bounds: %u nentries_mask: %u.\n",
> + src_ring, src_ring->write_index,
> + src_ring->nentries_mask);
> + src_ring->write_index = 0;
> + }
> +
> ath10k_pci_sleep(ar);
>
> src_ring->per_transfer_context = (void **)ptr;
> @@ -1037,6 +1057,16 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
> dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
> dest_ring->write_index =
> ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
> + /* Make sure the value above is sane. Can get 0xFFFFFFFF
> + * on a v1 board.
> + */
> + if (dest_ring->write_index > dest_ring->nentries_mask) {
> + ath10k_err("dest_ring %p: write_index is out of bounds: %u nentries_mask: %u.\n",
> + dest_ring, dest_ring->write_index,
> + dest_ring->nentries_mask);
> + dest_ring->write_index = 0;
> + }
> +
> ath10k_pci_sleep(ar);
>
> dest_ring->per_transfer_context = (void **)ptr;
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Updates to wireless-regdb review - vendor namespaces and VHT80
From: Luis R. Rodriguez @ 2013-07-03 0:38 UTC (permalink / raw)
To: linux-wireless, wireless-regdb@lists.infradead.org
Folks,
we have 802.11ac and 802.11ad now and I have a few pending patches
that I'd like to submit but unfortunately the requirements that we
have discussed for accepting patches do not meet the criteria we have
set in the community [0] for all the documentation. Additionally
getting all that documentation has proven quite difficult and at this
point I do not think we can easily get these upstream without making
an exception.
I'd like to propose a middle ground to also address another issue I've
noticed. Vendors can disagree and in order to give vendors a warm
fuzzy on ability to ensure their data is interpreted and provide the
ability to offload down to wireless-regdb even more interpretations
I'd like to propose the idea of embracing vendor namespaces within
wireless-regdb / crda / the kernel. The way I'd envision this is
'/sbin/crda US OUI' is passed upon a regulatory hint and in turn CRDA
will read the namespace for the OUI passed in regulatory.bin. Then at
our wireless summit kumbaya and with the development / enhancements of
intersect.c and union.c (not yet developed) we'd work on generalizing
the data. This would also allow vendors to supply their own rules
without the high bar that we are setting which so far has proven very
difficult to met.
In the meantime, while that gets developed, I'd still like to supply
patches to enable VHT80 for a few countries without hopefully such
high bar for documentation as I cannot get this information.
Let me know if this sounds reasonable.
[0] http://marc.info/?l=linux-wireless&m=128414096127554&w=2
Luis
^ permalink raw reply
* [PATCH] mwifiex: don't ignore SDIO interrupts during shutdown
From: Daniel Drake @ 2013-07-03 1:56 UTC (permalink / raw)
To: bzhao, linville; +Cc: linux-wireless
When the card is being removed, mwifiex_remove_card() immediately sets
surprise_removed to 1. This flag then causes the SDIO interrupt handler
to ignore all interrupts without even acking them.
If there are any async commands ongoing, it is very likely that interrupts
will be received during this time. Since they are not acked (via the MP reg
read in mwifiex_interrupt_status), it becomes an interrupt storm.
This interrupt storm is undesirable and can cause problems for the
bluetooth driver which also operates the 8787 SDIO card.
Make the driver continue to ack interrupts during shutdown to avoid
this. This is harder than it might sound.
We must be careful not to act upon the interrupt, only ack it.
Otherwise, we end up setting int_status to something. And hw_status is
set to MWIFIEX_HW_STATUS_CLOSING for obvious reasons. We would hit the
following infinite loop in mwifiex_main_process:
process_start:
do {
if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
(adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
break;
[...]
} while (true);
if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
goto process_start;
We must also observe that ACKing interrupts involves reading a load
of data into the mp_regs buffer. The driver doesn't do much in the
way of ensuring that interrupts are disabled before freeing buffers
such as mp_regs, but we do need something here to make sure that we
don't get any interrupts after mp_regs is freed.
This whole thing feels rather fragile, but I couldn't see a clean
way to do it, the driver seems a bit disorganised here. I would
welcome a review from the designers.
Signed-off-by: Daniel Drake <dsd@laptop.org>
---
drivers/net/wireless/mwifiex/init.c | 5 +++++
drivers/net/wireless/mwifiex/main.h | 1 +
drivers/net/wireless/mwifiex/sdio.c | 14 ++++++++------
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index caaf4bd..0e656db 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -643,6 +643,11 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
}
}
+ /* Must be done before cleanup_if (in mwifiex_free_adapter) and can't
+ * be done in atomic context. */
+ if (adapter->if_ops.disable_int)
+ adapter->if_ops.disable_int(adapter);
+
spin_lock(&adapter->mwifiex_lock);
if (adapter->if_ops.data_complete) {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 3da73d3..5162e8c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -601,6 +601,7 @@ struct mwifiex_if_ops {
int (*register_dev) (struct mwifiex_adapter *);
void (*unregister_dev) (struct mwifiex_adapter *);
int (*enable_int) (struct mwifiex_adapter *);
+ int (*disable_int) (struct mwifiex_adapter *);
int (*process_int_status) (struct mwifiex_adapter *);
int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
struct mwifiex_tx_param *);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5ee5ed0..25cfc30 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -948,7 +948,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
/*
* This function reads the interrupt status from card.
*/
-static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
+static void mwifiex_process_interrupt(struct mwifiex_adapter *adapter)
{
struct sdio_mmc_card *card = adapter->card;
u8 sdio_ireg;
@@ -961,6 +961,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
return;
}
+ if (adapter->surprise_removed)
+ return;
+
sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
if (sdio_ireg) {
/*
@@ -975,6 +978,8 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
adapter->int_status |= sdio_ireg;
spin_unlock_irqrestore(&adapter->int_lock, flags);
}
+
+ mwifiex_main_process(adapter);
}
/*
@@ -997,14 +1002,10 @@ mwifiex_sdio_interrupt(struct sdio_func *func)
}
adapter = card->adapter;
- if (adapter->surprise_removed)
- return;
-
if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
adapter->ps_state = PS_STATE_AWAKE;
- mwifiex_interrupt_status(adapter);
- mwifiex_main_process(adapter);
+ mwifiex_process_interrupt(adapter);
}
/*
@@ -1957,6 +1958,7 @@ static struct mwifiex_if_ops sdio_ops = {
.register_dev = mwifiex_register_dev,
.unregister_dev = mwifiex_unregister_dev,
.enable_int = mwifiex_sdio_enable_host_int,
+ .disable_int = mwifiex_sdio_disable_host_int,
.process_int_status = mwifiex_process_int_status,
.host_to_card = mwifiex_sdio_host_to_card,
.wakeup = mwifiex_pm_wakeup_card,
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH] brcmfmac: Turn off ARP offloading when configured for AP.
From: Rafał Miłecki @ 2013-07-03 4:54 UTC (permalink / raw)
To: Arend van Spriel
Cc: Greg KH, stable, linux-wireless, Hante Meuleman, John W. Linville
In-Reply-To: <51D33EC2.1090108@broadcom.com>
2013/7/2 Arend van Spriel <arend@broadcom.com>:
> On 06/19/2013 06:52 PM, Greg KH wrote:
>>
>> On Wed, Jun 19, 2013 at 05:51:46PM +0200, Arend van Spriel wrote:
>>>
>>> On 06/19/2013 04:19 PM, Greg KH wrote:
>>>>
>>>> On Wed, Jun 19, 2013 at 09:27:09AM +0200, Arend van Spriel wrote:
>>>>>
>>>>> On 06/06/2013 10:55 AM, Arend van Spriel wrote:
>>>>>>
>>>>>> From: Hante Meuleman <meuleman@broadcom.com>
>>>>>
>>>>>
>>>>> Hi Greg,
>>>>>
>>>>> I noticed your review announcement for v3.9.7 and did not see the
>>>>> change below. I sent it to stable because the original upstream
>>>>> commit did not apply. Did I miss some step in the process?
>>>>
>>>>
>>>> Ah, somehow I missed your patch, sorry about that, I do have it in my
>>>> mbox. What kernel tree(s) do you want it to be applied to? I'll pick
>>>> it up in my next round of releases.
>>>
>>>
>>> Thanks, Greg
>>>
>>> I backported it for the 3.9 tree. It does not apply to 3.8 so I will
>>> have to create another backport if I need it there.
>>
>>
>> 3.8 is long dead and not maintained by me anymore, but thanks.
>
>
> Hi Greg,
>
> Forgot to ask, but it seems like Canonical is maintaining additional stable
> kernel branches. I guess I should contact them for those kernel versions (if
> I care), right?
They track Greg's stables to pick up the patches. Know from my own
experience, I didn't have to ping anyone :)
--
Rafał
^ permalink raw reply
* Re: [PATCH] mac80211/minstrel_ht: fix cck rate sampling
From: Johannes Berg @ 2013-07-03 8:18 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
In-Reply-To: <1372446275-43012-1-git-send-email-nbd@openwrt.org>
On Fri, 2013-06-28 at 21:04 +0200, Felix Fietkau wrote:
> The CCK group needs special treatment to set the right flags and rate
> index. Add this missing check to prevent setting broken rates for tx
> packets.
Applied.
johannes
^ permalink raw reply
* Use of 5GHz frequencies with Wi-Fi Direct
From: Kévin THIERRY @ 2013-07-03 8:37 UTC (permalink / raw)
To: linux-wireless; +Cc: ronan lanoe
Hi,
Is there a way to force the use of 5GHz frequencies with Wi-Fi Direct ?
(Or define the 5GHz frequencies as preferred ?)
I tried to add the freq_list option in wpa_supplicant config file
without success. (I think this option should be set in a network block
but there is no network block for Wi-Fi Direct...)
"freq_list=5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560
5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825"
Thanks,
Kevin
^ permalink raw reply
* Re: [wireless-regdb] Updates to wireless-regdb review - vendor namespaces and VHT80
From: Bjørn Mork @ 2013-07-03 8:58 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, wireless-regdb@lists.infradead.org
In-Reply-To: <CAB=NE6V_PKG2UBSLPRhziUDcFzFi8uOJNiNzoPNaK0oU7rmZuQ@mail.gmail.com>
"Luis R. Rodriguez" <mcgrof@do-not-panic.com> writes:
> In the meantime, while that gets developed, I'd still like to supply
> patches to enable VHT80 for a few countries without hopefully such
> high bar for documentation as I cannot get this information.
I believe VHT80 (and VHT160) is allowed by current regulations in a
large number of countries, and that the current db entries are in fact
wrong by stating any upper channel width limits at all in the 5 GHz
bands.
For example, regulations in most CEPT countries are likely based on
"ECC/DEC/(04)08 on the harmonised use of the 5 GHz frequency bands for
the implementation of Wireless Access Systems including Radio Local
Area Networks (WAS/RLANs)"
or a previous version of that decision. Which is available here:
http://www.erodocdb.dk/Docs/doc98/official/pdf/ECCDEC0408.PDF
Quoting:
"considering
..
e. that the systems covered by this ECC Decision operate typically in a 20 MHz channel bandwidth, other
values for the channel bandwidth are also feasible provided they comply with the relevant maximum mean
e.i.r.p. and the corresponding maximum mean e.i.r.p. density limits;
"
and the continues deciding the mentioned power and power density limits
only, without any specific channelization. This document clearly allows
and anticipates both wider and narrower channels, and so does most
likely the national regualations implementing the decision.
The list of CEPT countries implementating this decision is here:
http://www.erodocdb.dk/doks/implement_doc_adm.aspx?docid=2033
Bjørn
^ permalink raw reply
* Re: Use of 5GHz frequencies with Wi-Fi Direct
From: Gagan Goyal @ 2013-07-03 9:30 UTC (permalink / raw)
To: Kévin THIERRY; +Cc: linux-wireless, ronan lanoe
In-Reply-To: <51D3E2C7.7020605@kaiwen.me>
Hi Kevin,
Plz add the following entries in wpa_supplicant.conf to use freq 5180
as operating ch.
p2p_oper_reg_class=115
p2p_oper_channel=36
country=US
Check, if this solve the requirement.
Cheers
Gagan
On 7/3/13, Kévin THIERRY <kevin.thierry@kaiwen.me> wrote:
> Hi,
>
> Is there a way to force the use of 5GHz frequencies with Wi-Fi Direct ?
> (Or define the 5GHz frequencies as preferred ?)
>
> I tried to add the freq_list option in wpa_supplicant config file
> without success. (I think this option should be set in a network block
> but there is no network block for Wi-Fi Direct...)
> "freq_list=5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560
> 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825"
>
> Thanks,
>
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: Use of 5GHz frequencies with Wi-Fi Direct
From: Gagan Goyal @ 2013-07-03 9:59 UTC (permalink / raw)
To: Kévin THIERRY; +Cc: linux-wireless, ronan lanoe
In-Reply-To: <51D3E2C7.7020605@kaiwen.me>
Hi Kevin,
plz make sure that driver advertise the support for both the bands and
provide all the supported frequencies.
During Supplicant init, supplicant read the driver capabilities and
along with other things the supported band and frequencies are stored.
P2p global data is then initialized with same data.
Cheers
Gagan
On 7/3/13, Kévin THIERRY <kevin.thierry@kaiwen.me> wrote:
> Hi,
>
> Is there a way to force the use of 5GHz frequencies with Wi-Fi Direct ?
> (Or define the 5GHz frequencies as preferred ?)
>
> I tried to add the freq_list option in wpa_supplicant config file
> without success. (I think this option should be set in a network block
> but there is no network block for Wi-Fi Direct...)
> "freq_list=5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560
> 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825"
>
> Thanks,
>
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH v2 0/9] wilink: add device tree support
From: Grazvydas Ignotas @ 2013-07-03 10:13 UTC (permalink / raw)
To: Luciano Coelho
Cc: linux-wireless@vger.kernel.org, Tony Lindgren, nsekhar,
mturquette, mark.rutland, Felipe Balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel@vger.kernel.org,
linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
pavel
In-Reply-To: <1372776948-24840-1-git-send-email-coelho@ti.com>
Hi,
On Tue, Jul 2, 2013 at 5:55 PM, Luciano Coelho <coelho@ti.com> wrote:
> Hi,
>
> This is a follow-up on a previous patch set that had a smaller
> audience. This time, I added the lists and people who were involved
> in the review of the bindings documentation, since most of my changes
> in v2 are coming from discussions there.
>
> This patch series adds device tree support to the wlcore_sdio driver,
> which is used by WiLink6, WiLink7 and WiLink8.
Could you perhaps consider doing device tree conversion for wl1251
too? With the knowledge you have from working on this series, it would
be much easier for you to do it than for someone else, and I don't
have much hope someone will do it at all. It's WiLink series chip
after all. Without this pandora and N900 are going to lose wifi
support after the switch to dt-only kernel.
I can offer you my help testing things on pandora and I'm sure someone
here could try it on N900.
--
Gražvydas
^ permalink raw reply
* Re: [PATCH v2 4/9] wl12xx: use frequency instead of enumerations for pdata clocks
From: Tony Lindgren @ 2013-07-03 11:33 UTC (permalink / raw)
To: Luciano Coelho
Cc: Nishanth Menon, linux-wireless, nsekhar, mturquette, mark.rutland,
balbi, grant.likely, rob.herring, devicetree-discuss, linux-doc,
linux-kernel, linux-omap, linux-arm-kernel
In-Reply-To: <1372796850.21065.93.camel@cumari.coelho.fi>
* Luciano Coelho <coelho@ti.com> [130702 13:33]:
> On Tue, 2013-07-02 at 10:02 -0500, Nishanth Menon wrote:
> > On 17:55-20130702, Luciano Coelho wrote:
> > > Instead of defining an enumeration with the FW specific values for the
> > > different clock rates, use the actual frequency instead. Also add a
> > > boolean to specify whether the clock is XTAL or not.
> > >
> > > Change all board files to reflect this.
> > >
> > > Cc: Tony Lindgren <tony@atomide.com>
> > > Cc: Sekhar Nori <nsekhar@ti.com>
> > > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > > ---
> > > arch/arm/mach-davinci/board-da850-evm.c | 3 +-
> > > arch/arm/mach-omap2/board-4430sdp.c | 5 ++-
> > ^^
> > > arch/arm/mach-omap2/board-omap3evm.c | 3 +-
> > > arch/arm/mach-omap2/board-omap4panda.c | 3 +-
> > ^^
> > Please do not add more platform data to platforms that are DT only.
>
> Ah, I hadn't realized that board_omap4panda.c and board-4430sdp.c had
> been removed in linux-next. I base my tree on wireless-next and it
> doesn't contain these changes yet. I would only have noticed this when
> I rebased my tree once the merge window is closed. ;)
>
> Thanks for pointing out, I'll make sure these changes will not be there
> when I send the pull request.
Please separate out the minimal pdata and arch/arm/mach-omap2 changes int
a immutable branch on v3.11-rc1 that I can also pull in. For v3.12, we're
going to be making more boards device tree only, so these changes may
otherwise cause pointless merge conflicts.
Regards,
Tony
^ permalink raw reply
* [PATCH] mac80211: add per-chain signal information to radiotap
From: Johannes Berg @ 2013-07-03 11:34 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
When per-chain signal information is available, don't add
the antenna field once but instead add a radiotap namespace
for each chain containing the chain/antenna number and the
signal strength on that chain.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/rx.c | 69 +++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 52 insertions(+), 17 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 23dbcfc..c9f2ca4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -87,11 +87,13 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
int len;
/* always present fields */
- len = sizeof(struct ieee80211_radiotap_header) + 9;
+ len = sizeof(struct ieee80211_radiotap_header) + 8;
- /* allocate extra bitmap */
+ /* allocate extra bitmaps */
if (status->vendor_radiotap_len)
len += 4;
+ if (status->chains)
+ len += 4 * hweight8(status->chains);
if (ieee80211_have_rx_timestamp(status)) {
len = ALIGN(len, 8);
@@ -100,6 +102,10 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
len += 1;
+ /* antenna field, if we don't have per-chain info */
+ if (!status->chains)
+ len += 1;
+
/* padding for RX_FLAGS if necessary */
len = ALIGN(len, 2);
@@ -116,6 +122,11 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
len += 12;
}
+ if (status->chains) {
+ /* antenna and antenna signal fields */
+ len += 2 * hweight8(status->chains);
+ }
+
if (status->vendor_radiotap_len) {
if (WARN_ON_ONCE(status->vendor_radiotap_align == 0))
status->vendor_radiotap_align = 1;
@@ -145,8 +156,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_radiotap_header *rthdr;
unsigned char *pos;
+ __le32 *it_present;
+ u32 it_present_val;
u16 rx_flags = 0;
- int mpdulen;
+ int mpdulen, chain;
+ unsigned long chains = status->chains;
mpdulen = skb->len;
if (!(has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)))
@@ -154,25 +168,39 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
memset(rthdr, 0, rtap_len);
+ it_present = &rthdr->it_present;
/* radiotap header, set always present flags */
- rthdr->it_present =
- cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
- (1 << IEEE80211_RADIOTAP_CHANNEL) |
- (1 << IEEE80211_RADIOTAP_ANTENNA) |
- (1 << IEEE80211_RADIOTAP_RX_FLAGS));
rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
+ it_present_val = BIT(IEEE80211_RADIOTAP_FLAGS) |
+ BIT(IEEE80211_RADIOTAP_CHANNEL) |
+ BIT(IEEE80211_RADIOTAP_RX_FLAGS);
+
+ if (!status->chains)
+ it_present_val |= BIT(IEEE80211_RADIOTAP_ANTENNA);
- pos = (unsigned char *)(rthdr + 1);
+ for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
+ it_present_val |=
+ BIT(IEEE80211_RADIOTAP_EXT) |
+ BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE);
+ put_unaligned_le32(it_present_val, it_present);
+ it_present++;
+ it_present_val = BIT(IEEE80211_RADIOTAP_ANTENNA) |
+ BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
+ }
if (status->vendor_radiotap_len) {
- rthdr->it_present |=
- cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) |
- cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT));
- put_unaligned_le32(status->vendor_radiotap_bitmap, pos);
- pos += 4;
+ it_present_val |= BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE) |
+ BIT(IEEE80211_RADIOTAP_EXT);
+ put_unaligned_le32(it_present_val, it_present);
+ it_present++;
+ it_present_val = status->vendor_radiotap_bitmap;
}
+ put_unaligned_le32(it_present_val, it_present);
+
+ pos = (void *)(it_present + 1);
+
/* the order of the following fields is important */
/* IEEE80211_RADIOTAP_TSFT */
@@ -242,9 +270,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
/* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
- /* IEEE80211_RADIOTAP_ANTENNA */
- *pos = status->antenna;
- pos++;
+ if (!status->chains) {
+ /* IEEE80211_RADIOTAP_ANTENNA */
+ *pos = status->antenna;
+ pos++;
+ }
/* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */
@@ -341,6 +371,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos += 2;
}
+ for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
+ *pos++ = status->chain_signal[chain];
+ *pos++ = chain;
+ }
+
if (status->vendor_radiotap_len) {
/* ensure 2 byte alignment for the vendor field as required */
if ((pos - (u8 *)rthdr) & 1)
--
1.8.0
^ permalink raw reply related
* Re: [PATCH v2 4/9] wl12xx: use frequency instead of enumerations for pdata clocks
From: Luciano Coelho @ 2013-07-03 12:14 UTC (permalink / raw)
To: Tony Lindgren
Cc: Nishanth Menon, linux-wireless, nsekhar, mturquette, mark.rutland,
balbi, grant.likely, rob.herring, devicetree-discuss, linux-doc,
linux-kernel, linux-omap, linux-arm-kernel
In-Reply-To: <20130703113334.GY5523@atomide.com>
On Wed, 2013-07-03 at 04:33 -0700, Tony Lindgren wrote:
> * Luciano Coelho <coelho@ti.com> [130702 13:33]:
> > On Tue, 2013-07-02 at 10:02 -0500, Nishanth Menon wrote:
> > > On 17:55-20130702, Luciano Coelho wrote:
> > > > Instead of defining an enumeration with the FW specific values for the
> > > > different clock rates, use the actual frequency instead. Also add a
> > > > boolean to specify whether the clock is XTAL or not.
> > > >
> > > > Change all board files to reflect this.
> > > >
> > > > Cc: Tony Lindgren <tony@atomide.com>
> > > > Cc: Sekhar Nori <nsekhar@ti.com>
> > > > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > > > ---
> > > > arch/arm/mach-davinci/board-da850-evm.c | 3 +-
> > > > arch/arm/mach-omap2/board-4430sdp.c | 5 ++-
> > > ^^
> > > > arch/arm/mach-omap2/board-omap3evm.c | 3 +-
> > > > arch/arm/mach-omap2/board-omap4panda.c | 3 +-
> > > ^^
> > > Please do not add more platform data to platforms that are DT only.
> >
> > Ah, I hadn't realized that board_omap4panda.c and board-4430sdp.c had
> > been removed in linux-next. I base my tree on wireless-next and it
> > doesn't contain these changes yet. I would only have noticed this when
> > I rebased my tree once the merge window is closed. ;)
> >
> > Thanks for pointing out, I'll make sure these changes will not be there
> > when I send the pull request.
>
> Please separate out the minimal pdata and arch/arm/mach-omap2 changes int
> a immutable branch on v3.11-rc1 that I can also pull in. For v3.12, we're
> going to be making more boards device tree only, so these changes may
> otherwise cause pointless merge conflicts.
Okay. I don't want to freeze my work, I'll continue using my
wireless-based tree (which is based on 3.10) for now. When the merge
window closes, I'll reorganize all this before sending pull requests, so
we can avoid conflicts.
Please ignore my changes to board files that will disappear on 3.11 and
keep reviewing the rest. ;)
--
Cheers,
Luca.
^ permalink raw reply
* Re: Use of 5GHz frequencies with Wi-Fi Direct
From: Kévin THIERRY @ 2013-07-03 12:27 UTC (permalink / raw)
To: Gagan Goyal; +Cc: linux-wireless, ronan lanoe
In-Reply-To: <CAChKcEmU9MMrC4gP4Vi3WWENTAC4+rtDK6mxA=5phdsEDxipxQ@mail.gmail.com>
I'm using an Atheros WB222 Wi-Fi card.
$ iw list
[...]
/Frequencies://
//* 5180 MHz [36] (15.0 dBm) (passive scanning, no IBSS)//
//* 5200 MHz [40] (15.0 dBm) (passive scanning, no IBSS)//
//* 5220 MHz [44] (15.0 dBm) (passive scanning, no IBSS)//
//* 5240 MHz [48] (15.0 dBm) (passive scanning, no IBSS)//
//* 5260 MHz [52] (17.0 dBm) (passive scanning, no IBSS, radar detection)//
//* 5280 MHz [56] (15.0 dBm) (passive scanning, no IBSS, radar detection)//
//* 5300 MHz [60] (15.0 dBm) (passive scanning, no IBSS, radar detection)//
//* 5320 MHz [64] (15.0 dBm) (passive scanning, no IBSS, radar detection)//
//* 5500 MHz [100] (disabled)//
//* 5520 MHz [104] (disabled)//
//* 5540 MHz [108] (disabled)//
//* 5560 MHz [112] (disabled)//
//* 5580 MHz [116] (disabled)//
//* 5600 MHz [120] (disabled)//
//* 5620 MHz [124] (disabled)//
//* 5640 MHz [128] (disabled)//
//* 5660 MHz [132] (disabled)//
//* 5680 MHz [136] (disabled)//
//* 5700 MHz [140] (disabled)//
//* 5745 MHz [149] (17.0 dBm) (passive scanning, no IBSS)//
//* 5765 MHz [153] (17.0 dBm) (passive scanning, no IBSS)//
//* 5785 MHz [157] (17.0 dBm) (passive scanning, no IBSS)//
//* 5805 MHz [161] (17.0 dBm) (passive scanning, no IBSS)//
//* 5825 MHz [165] (17.0 dBm) (passive scanning, no IBSS)/
[...]
wpa_supplicant config file :
/ctrl_interface=/var/run/wpa_supplicant//
//ap_scan=1//
//device_name=kevin_PC//
//device_type=1-0050F204-1//
//p2p_oper_reg_class=115//
//p2p_oper_channel=36//
//country=US/
wpa_supplicant debug at start :
/ctrl_interface='/var/run/wpa_supplicant'//
//ap_scan=1//
//device_name='kevin_PC'//
//p2p_oper_reg_class=115//
//p2p_oper_channel=36//
//country='US'//
//nl80211: interface wlan5 in phy phy0//
//rfkill: initial event: idx=0 type=1 op=0 soft=0 hard=0//
//rfkill: initial event: idx=1 type=2 op=0 soft=1 hard=0//
//nl80211: Set mode ifindex 4 iftype 2 (STATION)//
//nl80211: Subscribe to mgmt frames with non-AP handle 0x1e332f0//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=2): 04 0a//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=2): 04 0b//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=2): 04 0c//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=2): 04 0d//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=6): 04 09 50 6f 9a 09//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=5): 7f 50 6f 9a 09//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=1): 06//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=2): 0a 07//
//nl80211: Register frame type=0xd0 nl_handle=0x1e332f0//
//nl80211: Register frame match - hexdump(len=2): 0a 11//
//netlink: Operstate: linkmode=1, operstate=5//
//nl80211: Using driver-based off-channel TX//
//nl80211: TDLS supported//
//nl80211: TDLS external setup//
//nl80211: Use separate P2P group interface (driver advertised support)//
//nl80211: driver param='(null)'//
//nl80211: Regulatory information - country=US//
//nl80211: 2402-2472 @ 40 MHz//
//nl80211: 5170-5250 @ 40 MHz//
//nl80211: 5250-5330 @ 40 MHz//
//nl80211: 5490-5600 @ 40 MHz//
//nl80211: 5650-5710 @ 40 MHz//
//nl80211: 5735-5835 @ 40 MHz//
//nl80211: Added 802.11b mode based on 802.11g information//
//wlan5: Own MAC address: 00:0b:6b:7f:92:56//
//wpa_driver_nl80211_set_key: ifindex=4 alg=0 addr=(nil) key_idx=0
set_tx=0 seq_len=0 key_len=0//
//wpa_driver_nl80211_set_key: ifindex=4 alg=0 addr=(nil) key_idx=1
set_tx=0 seq_len=0 key_len=0//
//wpa_driver_nl80211_set_key: ifindex=4 alg=0 addr=(nil) key_idx=2
set_tx=0 seq_len=0 key_len=0//
//wpa_driver_nl80211_set_key: ifindex=4 alg=0 addr=(nil) key_idx=3
set_tx=0 seq_len=0 key_len=0//
//wlan5: RSN: flushing PMKID list in the driver//
//nl80211: Flush PMKIDs//
//wlan5: State: DISCONNECTED -> INACTIVE//
//WPS: Set UUID for interface wlan5//
//WPS: UUID based on MAC address - hexdump(len=16): 97 71 b0 a8 da ca 57
bf 99 80 01 b3 3f 50 26 de//
//EAPOL: SUPP_PAE entering state DISCONNECTED//
//EAPOL: Supplicant port status: Unauthorized//
//nl80211: Set supplicant port unauthorized for 00:00:00:00:00:00//
//EAPOL: KEY_RX entering state NO_KEY_RECEIVE//
//EAPOL: SUPP_BE entering state INITIALIZE//
//EAP: EAP entering state DISABLED//
//EAPOL: Supplicant port status: Unauthorized//
//nl80211: Set supplicant port unauthorized for 00:00:00:00:00:00//
//EAPOL: Supplicant port status: Unauthorized//
//nl80211: Set supplicant port unauthorized for 00:00:00:00:00:00//
//P2P: Own listen channel: 1//
//P2P: Configured operating channel: 115:36//
//P2P: Add operating class 81//
//P2P: Channels - hexdump(len=12): 01 02 03 04 05 06 07 08 09 0a 0b 0d//
//wlan5: Added interface wlan5//
//wlan5: State: INACTIVE -> DISCONNECTED//
//wpa_driver_nl80211_set_operstate: operstate 0->0 (DORMANT)//
//netlink: Operstate: linkmode=-1, operstate=5//
//random: Got 18/20 bytes from /dev/random//
//RTM_NEWLINK: operstate=0 ifi_flags=0x1003 ([UP])//
//RTM_NEWLINK, IFLA_IFNAME: Interface 'wlan5' added//
//nl80211: if_removed already cleared - ignore event//
//EAPOL: disable timer tick//
//EAPOL: Supplicant port status: Unauthorized//
//nl80211: Set supplicant port unauthorized for 00:00:00:00:00:00//
//random: Got 2/2 bytes from /dev/random//
//nl80211: Ignore event for foreign ifindex 2/
It seems that the 5 GHz channels are added but the 2.4 GHz channels are
still there and used instead of the frequency 5180.
Kévin
Le 03/07/2013 11:59, Gagan Goyal a écrit :
> Hi Kevin,
>
> plz make sure that driver advertise the support for both the bands and
> provide all the supported frequencies.
>
> During Supplicant init, supplicant read the driver capabilities and
> along with other things the supported band and frequencies are stored.
>
> P2p global data is then initialized with same data.
>
> Cheers
>
> Gagan
>
> On 7/3/13, Kévin THIERRY <kevin.thierry@kaiwen.me> wrote:
>> Hi,
>>
>> Is there a way to force the use of 5GHz frequencies with Wi-Fi Direct ?
>> (Or define the 5GHz frequencies as preferred ?)
>>
>> I tried to add the freq_list option in wpa_supplicant config file
>> without success. (I think this option should be set in a network block
>> but there is no network block for Wi-Fi Direct...)
>> "freq_list=5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560
>> 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825"
>>
>> Thanks,
>>
>> Kevin
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
>> in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
^ permalink raw reply
* Re: [PATCH v2 0/9] wilink: add device tree support
From: Luciano Coelho @ 2013-07-03 13:45 UTC (permalink / raw)
To: Grazvydas Ignotas
Cc: linux-wireless@vger.kernel.org, Tony Lindgren, nsekhar,
mturquette, mark.rutland, Felipe Balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel@vger.kernel.org,
linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
pavel
In-Reply-To: <CANOLnOPBHesTiV61zpQ_QS9c7E91K50EnbMnGhvgaViuA_3=Bw@mail.gmail.com>
On Wed, 2013-07-03 at 13:13 +0300, Grazvydas Ignotas wrote:
> Hi,
Hi Gražvydas,
> On Tue, Jul 2, 2013 at 5:55 PM, Luciano Coelho <coelho@ti.com> wrote:
> > Hi,
> >
> > This is a follow-up on a previous patch set that had a smaller
> > audience. This time, I added the lists and people who were involved
> > in the review of the bindings documentation, since most of my changes
> > in v2 are coming from discussions there.
> >
> > This patch series adds device tree support to the wlcore_sdio driver,
> > which is used by WiLink6, WiLink7 and WiLink8.
>
> Could you perhaps consider doing device tree conversion for wl1251
> too? With the knowledge you have from working on this series, it would
> be much easier for you to do it than for someone else, and I don't
> have much hope someone will do it at all. It's WiLink series chip
> after all. Without this pandora and N900 are going to lose wifi
> support after the switch to dt-only kernel.
Unfortunately I don't have much time to work on wl1251. I think it
wouldn't be too difficult to do though, so patches are welcome. ;)
Maybe you could try to make this change and I could support you if
needed?
> I can offer you my help testing things on pandora and I'm sure someone
> here could try it on N900.
I could try it on the N900, if it is still bootable easily with the
mainline. ;)
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH v3 0/8] wilink: add device tree support
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
Hi,
This patch series adds device tree support to the wlcore_sdio driver,
which is used by WiLink6, WiLink7 and WiLink8.
The first patches do some clean-up to make the data needed in the
wilink device tree node smaller. The remaining patches implement the
actual device tree node parsing in wlcore_sdio.
I still need to figure out how to add the information about whether
the clocks are XTAL or not. I'll send it in a separate patche set.
The DTS file changes will be sent separately, since they need to go
via different trees.
The bindings documentation patch will also be updated and sent
separately, once the XTAL issue is solved.
Changes in v3:
* Remove irq_flags from pdata and handle them in the board files.
This caused the "wlcore: use irq_flags in pdata instead of hiding it
behind a quirk" (now 2/8) to be changed considerably, so I removed
the Acked-by from Tony. I also added calls to gpio_request_one()
for the WiLink IRQ GPIO that were missing in the board files (thanks
Felipe);
* Added "const" to the frequency tables in patch 4/8 (thanks Felipe);
* Squashed patch 5/9 into the new 2/8;
* Added comment about the sdio_set_drvdata() call move in 7/8 (thanks
Felipe);
* I'm still modifying the panda and 4430sdp board files that are going
to be removed in 3.11. Please ignore the changes I made there, I
just wanted to make sure they still work with my current tree. Once
the 3.11 merge window close, I'll do the relevant merges before I
send pull requests (thanks Tony and Nishant).
Please review.
--
Cheers,
Luca.
Luciano Coelho (8):
wl1251: split wl251 platform data to a separate structure
wlcore: set irq_flags in the board files instead of hiding behind a
quirk
wlcore: remove pwr_in_suspend from platform data
wl12xx: use frequency instead of enumerations for pdata clocks
wlcore: add initial device tree support to the sdio module
wlcore: sdio: add wilink clock providers
wlcore: sdio: get clocks from device tree
wlcore/wl12xx: check if we got correct clock data from DT
arch/arm/mach-davinci/board-da850-evm.c | 11 ++-
arch/arm/mach-omap2/board-4430sdp.c | 23 ++++-
arch/arm/mach-omap2/board-omap3evm.c | 22 ++++-
arch/arm/mach-omap2/board-omap3pandora.c | 4 +-
arch/arm/mach-omap2/board-omap4panda.c | 39 +++++++--
arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +-
arch/arm/mach-omap2/board-zoom-peripherals.c | 33 ++++++-
drivers/net/wireless/ti/wilink_platform_data.c | 37 ++++++--
drivers/net/wireless/ti/wl1251/sdio.c | 12 +--
drivers/net/wireless/ti/wl1251/spi.c | 2 +-
drivers/net/wireless/ti/wl12xx/main.c | 77 ++++++++++++++--
drivers/net/wireless/ti/wl12xx/wl12xx.h | 28 ++++++
drivers/net/wireless/ti/wlcore/debugfs.c | 2 +-
drivers/net/wireless/ti/wlcore/main.c | 26 +++---
drivers/net/wireless/ti/wlcore/sdio.c | 112 ++++++++++++++++++++++--
drivers/net/wireless/ti/wlcore/wlcore.h | 5 +-
drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 +
include/linux/wl12xx.h | 52 +++++------
18 files changed, 398 insertions(+), 90 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH v3 1/8] wl1251: split wl251 platform data to a separate structure
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
Move the wl1251 part of the wl12xx platform data structure into a new
structure specifically for wl1251. Change the platform data built-in
block and board files accordingly.
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-omap3pandora.c | 4 +--
arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +-
drivers/net/wireless/ti/wilink_platform_data.c | 37 ++++++++++++++++++++----
drivers/net/wireless/ti/wl1251/sdio.c | 12 ++++----
drivers/net/wireless/ti/wl1251/spi.c | 2 +-
include/linux/wl12xx.h | 22 +++++++++++++-
6 files changed, 62 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 28133d5..bf06d95 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -540,7 +540,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
static void __init pandora_wl1251_init(void)
{
- struct wl12xx_platform_data pandora_wl1251_pdata;
+ struct wl1251_platform_data pandora_wl1251_pdata;
int ret;
memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
@@ -554,7 +554,7 @@ static void __init pandora_wl1251_init(void)
goto fail_irq;
pandora_wl1251_pdata.use_eeprom = true;
- ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+ ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
if (ret < 0)
goto fail_irq;
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 18ca61e..733f3f2 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -80,7 +80,7 @@ enum {
RX51_SPI_MIPID, /* LCD panel */
};
-static struct wl12xx_platform_data wl1251_pdata;
+static struct wl1251_platform_data wl1251_pdata;
static struct tsc2005_platform_data tsc2005_pdata;
#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e958..a92bd3e 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
#include <linux/err.h>
#include <linux/wl12xx.h>
-static struct wl12xx_platform_data *platform_data;
+static struct wl12xx_platform_data *wl12xx_platform_data;
int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
{
- if (platform_data)
+ if (wl12xx_platform_data)
return -EBUSY;
if (!data)
return -EINVAL;
- platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
- if (!platform_data)
+ wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!wl12xx_platform_data)
return -ENOMEM;
return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
struct wl12xx_platform_data *wl12xx_get_platform_data(void)
{
- if (!platform_data)
+ if (!wl12xx_platform_data)
return ERR_PTR(-ENODEV);
- return platform_data;
+ return wl12xx_platform_data;
}
EXPORT_SYMBOL(wl12xx_get_platform_data);
+
+static struct wl1251_platform_data *wl1251_platform_data;
+
+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+ if (wl1251_platform_data)
+ return -EBUSY;
+ if (!data)
+ return -EINVAL;
+
+ wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!wl1251_platform_data)
+ return -ENOMEM;
+
+ return 0;
+}
+
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+ if (!wl1251_platform_data)
+ return ERR_PTR(-ENODEV);
+
+ return wl1251_platform_data;
+}
+EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c..b75a37a 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
struct wl1251 *wl;
struct ieee80211_hw *hw;
struct wl1251_sdio *wl_sdio;
- const struct wl12xx_platform_data *wl12xx_board_data;
+ const struct wl1251_platform_data *wl1251_board_data;
hw = wl1251_alloc_hw();
if (IS_ERR(hw))
@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio_func *func,
wl->if_priv = wl_sdio;
wl->if_ops = &wl1251_sdio_ops;
- wl12xx_board_data = wl12xx_get_platform_data();
- if (!IS_ERR(wl12xx_board_data)) {
- wl->set_power = wl12xx_board_data->set_power;
- wl->irq = wl12xx_board_data->irq;
- wl->use_eeprom = wl12xx_board_data->use_eeprom;
+ wl1251_board_data = wl1251_get_platform_data();
+ if (!IS_ERR(wl1251_board_data)) {
+ wl->set_power = wl1251_board_data->set_power;
+ wl->irq = wl1251_board_data->irq;
+ wl->use_eeprom = wl1251_board_data->use_eeprom;
}
if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index c7dc6fe..6bbbfe6 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -238,7 +238,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
static int wl1251_spi_probe(struct spi_device *spi)
{
- struct wl12xx_platform_data *pdata;
+ struct wl1251_platform_data *pdata;
struct ieee80211_hw *hw;
struct wl1251 *wl;
int ret;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index a54fe82..b516b4f 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -48,11 +48,15 @@ enum {
WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
};
-struct wl12xx_platform_data {
+struct wl1251_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;
+};
+
+struct wl12xx_platform_data {
+ int irq;
int board_ref_clock;
int board_tcxo_clock;
unsigned long platform_quirks;
@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+int wl1251_set_platform_data(const struct wl1251_platform_data *data);
+
+struct wl1251_platform_data *wl1251_get_platform_data(void);
+
#else
static inline
@@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
return ERR_PTR(-ENODATA);
}
+static inline
+int wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+ return -ENOSYS;
+}
+
+static inline
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+ return ERR_PTR(-ENODATA);
+}
+
#endif
#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 2/8] wlcore: set irq_flags in the board files instead of hiding behind a quirk
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
The platform_quirk element in the platform data was used to change the
way the IRQ is triggered. When set, the EDGE_IRQ quirk would change
the irqflags used and treat edge trigger differently from the rest.
Instead of hiding this irq flag setting behind the quirk, have the
board files set the flags during initialization. This will be more
meaningful than driver-specific quirks when we switch to DT.
Additionally, fix missing gpio_request() calls in the boarding files
(so that setting the flags actually works).
Cc: Tony Lindgren <tony@atomide.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
arch/arm/mach-davinci/board-da850-evm.c | 8 +++++-
arch/arm/mach-omap2/board-4430sdp.c | 18 +++++++++++++
arch/arm/mach-omap2/board-omap3evm.c | 19 ++++++++++++++
arch/arm/mach-omap2/board-omap4panda.c | 36 +++++++++++++++++++++-----
arch/arm/mach-omap2/board-zoom-peripherals.c | 30 ++++++++++++++++++---
drivers/net/wireless/ti/wlcore/debugfs.c | 2 +-
drivers/net/wireless/ti/wlcore/main.c | 24 ++++++++++-------
drivers/net/wireless/ti/wlcore/wlcore.h | 5 ++--
include/linux/wl12xx.h | 4 ---
9 files changed, 118 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 8a24b6c..544b6fa 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1378,7 +1378,6 @@ static const short da850_wl12xx_pins[] __initconst = {
static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
.irq = -1,
.board_ref_clock = WL12XX_REFCLOCK_38,
- .platform_quirks = WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
};
static __init int da850_wl12xx_init(void)
@@ -1409,6 +1408,13 @@ static __init int da850_wl12xx_init(void)
goto free_wlan_en;
}
+ ret = irq_set_irq_type(gpio_to_irq(DA850_WLAN_IRQ),
+ IRQ_TYPE_EDGE_RISING);
+ if (ret) {
+ pr_err("Could not set wl12xx irq type: %d\n", ret);
+ goto free;
+ }
+
da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 56a9a4f..953f620 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -703,12 +703,30 @@ static void __init omap4_sdp4430_wifi_init(void)
omap4_sdp4430_wifi_mux_init();
omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
+
+ ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
+ if (ret) {
+ pr_err("error requesting wl12xx gpio: %d\n", ret);
+ goto out;
+ }
+
+ ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
+ if (ret) {
+ pr_err("error setting wl12xx irq type: %d\n", ret);
+ goto free;
+ }
+
ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
if (ret)
pr_err("Error setting wl12xx data: %d\n", ret);
+
ret = platform_device_register(&omap_vwlan_device);
if (ret)
pr_err("Error registering wl12xx device: %d\n", ret);
+out:
+ return;
+free:
+ gpio_free(GPIO_WIFI_IRQ);
}
static void __init omap_4430sdp_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index f76d0de..8abce3cd 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -612,12 +612,31 @@ static void __init omap3_evm_wl12xx_init(void)
/* WL12xx WLAN Init */
omap3evm_wlan_data.irq = gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO);
+
+ ret = gpio_request_one(OMAP3EVM_WLAN_IRQ_GPIO, GPIOF_IN,
+ "OMAP3EVM_WLAN_IRQ_GPIO");
+ if (ret) {
+ pr_err("error requesting wl12xx gpio: %d\n", ret);
+ goto out;
+ }
+
+ ret = irq_set_irq_type(gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO),
+ IRQ_TYPE_LEVEL_HIGH);
+ if (ret) {
+ pr_err("error setting wl12xx irq type: %d\n", ret);
+ goto free;
+ }
+
ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
if (ret)
pr_err("error setting wl12xx data: %d\n", ret);
ret = platform_device_register(&omap3evm_wlan_regulator);
if (ret)
pr_err("error registering wl12xx device: %d\n", ret);
+out:
+ return;
+free:
+ gpio_free(OMAP3EVM_WLAN_IRQ_GPIO);
#endif
}
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1e2c75e..5b33626 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -413,20 +413,44 @@ static void omap4_panda_init_rev(void)
}
}
+static void __init omap4_panda_wilink_init(void)
+{
+ int ret;
+
+ omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
+
+ ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
+ if (ret) {
+ pr_err("error requesting wl12xx gpio: %d\n", ret);
+ goto out;
+ }
+
+ ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
+ if (ret) {
+ pr_err("error setting wl12xx irq type: %d\n", ret);
+ goto free;
+ }
+
+ ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
+ if (ret) {
+ pr_err("error setting wl12xx data: %d\n", ret);
+ goto free;
+ }
+out:
+ return;
+free:
+ gpio_free(GPIO_WIFI_IRQ);
+}
+
static void __init omap4_panda_init(void)
{
int package = OMAP_PACKAGE_CBS;
- int ret;
if (omap_rev() == OMAP4430_REV_ES1_0)
package = OMAP_PACKAGE_CBL;
omap4_mux_init(board_mux, NULL, package);
- omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
- ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
- if (ret)
- pr_err("error setting wl12xx data: %d\n", ret);
-
+ omap4_panda_wilink_init();
omap4_panda_init_rev();
omap4_panda_i2c_init();
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index a90375d..4f84cf9 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -339,16 +339,40 @@ static void enable_board_wakeup_source(void)
OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
}
-void __init zoom_peripherals_init(void)
+static void __init zoom_wilink_init(void)
{
int ret;
omap_zoom_wlan_data.irq = gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO);
- ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
- if (ret)
+ ret = gpio_request_one(OMAP_ZOOM_WLAN_IRQ_GPIO, GPIOF_IN,
+ "OMAP_ZOOM_WLAN_IRQ_GPIO");
+ if (ret) {
+ pr_err("error requesting wl12xx gpio: %d\n", ret);
+ goto out;
+ }
+
+ ret = irq_set_irq_type(gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO),
+ IRQ_TYPE_LEVEL_HIGH);
+ if (ret) {
+ pr_err("error setting wl12xx irq type: %d\n", ret);
+ goto free;
+ }
+
+ ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
+ if (ret) {
pr_err("error setting wl12xx data: %d\n", ret);
+ goto free;
+ }
+out:
+ return;
+free:
+ gpio_free(OMAP_ZOOM_WLAN_IRQ_GPIO);
+}
+void __init zoom_peripherals_init(void)
+{
+ zoom_wilink_init();
omap_hsmmc_init(mmc);
omap_i2c_init();
pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup));
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index c3e1f79..5eff663 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -486,7 +486,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
DRIVER_STATE_PRINT_HEX(irq);
/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
DRIVER_STATE_PRINT_HEX(hw_pg_ver);
- DRIVER_STATE_PRINT_HEX(platform_quirks);
+ DRIVER_STATE_PRINT_HEX(irq_flags);
DRIVER_STATE_PRINT_HEX(chip.id);
DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b8db55c..7b5d0cc 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -27,6 +27,7 @@
#include <linux/vmalloc.h>
#include <linux/wl12xx.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include "wlcore.h"
#include "debug.h"
@@ -516,7 +517,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
* In case edge triggered interrupt must be used, we cannot iterate
* more than once without introducing race conditions with the hardirq.
*/
- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+ if (wl->irq_flags & IRQF_TRIGGER_RISING)
loopcount = 1;
wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -5765,7 +5766,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
wl->ap_ps_map = 0;
wl->ap_fw_ps_map = 0;
wl->quirks = 0;
- wl->platform_quirks = 0;
wl->system_hlid = WL12XX_SYSTEM_HLID;
wl->active_sta_count = 0;
wl->active_link_count = 0;
@@ -5900,8 +5900,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
struct wl1271 *wl = context;
struct platform_device *pdev = wl->pdev;
struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
- struct wl12xx_platform_data *pdata = pdev_data->pdata;
- unsigned long irqflags;
+ struct irq_data *irq_data;
int ret;
if (fw) {
@@ -5928,16 +5927,21 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
wlcore_adjust_conf(wl);
wl->irq = platform_get_irq(pdev, 0);
- wl->platform_quirks = pdata->platform_quirks;
wl->if_ops = pdev_data->if_ops;
- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
- irqflags = IRQF_TRIGGER_RISING;
- else
- irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+ irq_data = irq_get_irq_data(wl->irq);
+ if (!irq_data) {
+ wl1271_error("couldn't get irq data for irq %d\n", wl->irq);
+ ret = -EINVAL;
+ goto out_free_nvs;
+ }
+
+ wl->irq_flags = irqd_get_trigger_type(irq_data);
+ /* Since we don't use the primary handler, we must set ONESHOT */
+ wl->irq_flags |= IRQF_ONESHOT;
ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
- irqflags, pdev->name, wl);
+ wl->irq_flags, pdev->name, wl);
if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret);
goto out_free_nvs;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0034979..8306bde 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -185,6 +185,8 @@ struct wl1271 {
int irq;
+ int irq_flags;
+
spinlock_t wl_lock;
enum wlcore_state state;
@@ -384,9 +386,6 @@ struct wl1271 {
/* Quirks of specific hardware revisions */
unsigned int quirks;
- /* Platform limitations */
- unsigned int platform_quirks;
-
/* number of currently active RX BA sessions */
int ba_rx_session_count;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index b516b4f..1bfcd19 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -59,13 +59,9 @@ struct wl12xx_platform_data {
int irq;
int board_ref_clock;
int board_tcxo_clock;
- unsigned long platform_quirks;
bool pwr_in_suspend;
};
-/* Platform does not support level trigger interrupts */
-#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
-
#ifdef CONFIG_WILINK_PLATFORM_DATA
int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 5/8] wlcore: add initial device tree support to the sdio module
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
If platform data is not available, try to get the required information
from the device tree. Register an OF match table and parse the
appropriate device tree nodes.
Parse interrupt property only, for now.
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
drivers/net/wireless/ti/wlcore/sdio.c | 69 ++++++++++++++++++++++++++++++---
1 file changed, 63 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 4c7e8ac..9370d7e 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -30,7 +30,7 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
-#include <linux/gpio.h>
+#include <linux/of_irq.h>
#include <linux/wl12xx.h>
#include <linux/pm_runtime.h>
#include <linux/printk.h>
@@ -214,6 +214,43 @@ static struct wl1271_if_operations sdio_ops = {
.set_block_size = wl1271_sdio_set_block_size,
};
+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
+{
+ struct wl12xx_platform_data *pdata;
+ struct device_node *np = dev->of_node;
+
+ if (!np) {
+ np = of_find_matching_node(NULL, dev->driver->of_match_table);
+ if (!np) {
+ dev_notice(dev, "device tree node not available\n");
+ pdata = ERR_PTR(-ENODEV);
+ goto out;
+ }
+ }
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(dev, "can't allocate platform data\n");
+ pdata = ERR_PTR(-ENODEV);
+ goto out;
+ }
+
+ pdata->irq = irq_of_parse_and_map(np, 0);
+ if (pdata->irq < 0) {
+ dev_err(dev, "can't get interrupt gpio from the device tree\n");
+ goto out_free;
+ }
+
+ goto out;
+
+out_free:
+ kfree(pdata);
+ pdata = ERR_PTR(-ENODEV);
+
+out:
+ return pdata;
+}
+
static int wl1271_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -248,11 +285,22 @@ static int wl1271_probe(struct sdio_func *func,
/* Use block mode for transferring over one block size of data */
func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+ /* The pdata allocated here is freed when the device is freed,
+ * so we don't need an additional out label to free it in case
+ * of error further on.
+ */
+
+ /* Try to get legacy platform data from the board file */
pdev_data->pdata = wl12xx_get_platform_data();
if (IS_ERR(pdev_data->pdata)) {
- ret = PTR_ERR(pdev_data->pdata);
- dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
- goto out_free_glue;
+ dev_info(&func->dev,
+ "legacy platform data not found, trying device tree\n");
+
+ pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
+ if (IS_ERR(pdev_data->pdata)) {
+ dev_err(&func->dev, "can't get platform data\n");
+ goto out_free_glue;
+ }
}
/* if sdio can keep power while host is suspended, enable wow */
@@ -386,16 +434,25 @@ static const struct dev_pm_ops wl1271_sdio_pm_ops = {
};
#endif
+static const struct of_device_id wlcore_sdio_of_match_table[] = {
+ { .compatible = "ti,wilink6" },
+ { .compatible = "ti,wilink7" },
+ { .compatible = "ti,wilink8" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
+
static struct sdio_driver wl1271_sdio_driver = {
.name = "wl1271_sdio",
.id_table = wl1271_devices,
.probe = wl1271_probe,
.remove = wl1271_remove,
-#ifdef CONFIG_PM
.drv = {
+#ifdef CONFIG_PM
.pm = &wl1271_sdio_pm_ops,
- },
#endif
+ .of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
+ },
};
static int __init wl1271_init(void)
--
1.7.10.4
^ permalink raw reply related
* WL1273: Firmware initialization problem
From: José Miguel Gonçalves @ 2013-07-03 13:53 UTC (permalink / raw)
To: linux-wireless
Hi,
I'm integrating a WL1273 based module (Jorjin's WG7350) in a S3C2416 based
platform running kernel 3.9.8.
I've managed to configure my kernel platform data and set the wl127x calibration
file and I'm now able to set the wlan0 interface up, what is shown in the
following log;
[root ~]$ modprobe wlcore debug_level=0x40004
[root ~]$ modprobe wlcore_sdio
[ 53.670000] wake enabled for irq 54
[ 53.905000] wlcore: PG Ver major = 1 minor = 0, MAC is not present
[ 53.905000] wlcore: chip id 0x4030111 (1271 PG20)
[ 53.910000] wlcore: base address: oui deadbe nic ef0000
[ 54.085000] wlcore: loaded
[root ~]$ ifconfig wlan0 up
[ 66.160000] wlcore: booting firmware ti-connectivity/wl127x-fw-5-sr.bin
[ 66.315000] wlcore: pause1 0xf05
[ 66.315000] wlcore: clk2 0x0
[ 66.315000] wlcore: soft reset bootdata 0x0
[ 66.325000] wlcore: nvs burst write 0x30546c: 0xbeef0000
[ 66.325000] wlcore: nvs burst write 0x305470: 0xdead
[ 66.330000] wlcore: ACX_EEPROMLESS_IND_REG
[ 66.335000] wlcore: chip id 0x4030111
[ 66.335000] wlcore: firmware chunks to be uploaded: 6
[ 66.340000] wlcore: chunk 5 addr 0x0 len 196544
[ 66.350000] wlcore: starting firmware upload
[ 66.350000] wlcore: fw_data_len 196544 chunk_size 16384
[ 66.360000] wlcore: uploading fw chunk 0xc4b8700c to 0x0
[ 66.365000] wlcore: uploading fw chunk 0xc4b8b00c to 0x4000
[ 66.370000] wlcore: uploading fw chunk 0xc4b8f00c to 0x8000
[ 66.375000] wlcore: uploading fw chunk 0xc4b9300c to 0xc000
[ 66.380000] wlcore: uploading fw chunk 0xc4b9700c to 0x10000
[ 66.385000] wlcore: uploading fw chunk 0xc4b9b00c to 0x14000
[ 66.390000] wlcore: uploading fw chunk 0xc4b9f00c to 0x18000
[ 66.400000] wlcore: uploading fw chunk 0xc4ba300c to 0x1c000
[ 66.405000] wlcore: uploading fw chunk 0xc4ba700c to 0x20000
[ 66.405000] wlcore: uploading fw chunk 0xc4bab00c to 0x24000
[ 66.415000] wlcore: uploading fw chunk 0xc4baf00c to 0x28000
[ 66.420000] wlcore: uploading fw last chunk (16320 B) 0xc4bb300c to 0x2c000
[ 66.425000] wlcore: chunk 4 addr 0x20000000 len 41944
[ 66.430000] wlcore: starting firmware upload
[ 66.435000] wlcore: fw_data_len 41944 chunk_size 16384
[ 66.440000] wlcore: uploading fw chunk 0xc4bb6fd4 to 0x20000000
[ 66.450000] wlcore: uploading fw chunk 0xc4bbafd4 to 0x20004000
[ 66.450000] wlcore: uploading fw last chunk (9176 B) 0xc4bbefd4 to 0x20008000
[ 66.460000] wlcore: chunk 3 addr 0x40000 len 448
[ 66.460000] wlcore: starting firmware upload
[ 66.465000] wlcore: fw_data_len 448 chunk_size 16384
[ 66.475000] wlcore: uploading fw last chunk (448 B) 0xc4bc13b4 to 0x40000
[ 66.480000] wlcore: chunk 2 addr 0x40be0 len 29412
[ 66.485000] wlcore: starting firmware upload
[ 66.485000] wlcore: fw_data_len 29412 chunk_size 16384
[ 66.500000] wlcore: uploading fw chunk 0xc4bc157c to 0x40be0
[ 66.505000] wlcore: uploading fw last chunk (13028 B) 0xc4bc557c to 0x44be0
[ 66.510000] wlcore: chunk 1 addr 0x312000 len 8092
[ 66.515000] wlcore: starting firmware upload
[ 66.520000] wlcore: fw_data_len 8092 chunk_size 16384
[ 66.525000] wlcore: uploading fw last chunk (8092 B) 0xc4bc8868 to 0x312000
[ 66.530000] wlcore: chunk 0 addr 0x316000 len 3784
[ 66.535000] wlcore: starting firmware upload
[ 66.540000] wlcore: fw_data_len 3784 chunk_size 16384
[ 66.545000] wlcore: uploading fw last chunk (3784 B) 0xc4bca80c to 0x316000
[ 66.555000] wlcore: chip id after firmware boot: 0x4030111
[ 66.620000] wlcore: rx start cmd channel 1
[ 66.620000] wlcore: tx start cmd channel 1
[ 66.630000] wlcore: firmware booted (Rev 6.3.10.0.133)
The problem that I have is if I try to restart the wlan0 interface the wl127x
firmware seems not to reinitialize, as you can see here;
[root ~]$ ifconfig wlan0 down
[ 80.765000] wlcore: down
[root ~]$ ifconfig wlan0 up
[ 87.585000] wlcore: pause1 0x40f75
[ 87.585000] wlcore: clk2 0x80316a38
[ 87.590000] wlcore: soft reset bootdata 0x0
[ 87.595000] wlcore: nvs burst write 0x30546c: 0xbeef0000
[ 87.600000] wlcore: nvs burst write 0x305470: 0xdead
[ 87.605000] wlcore: ACX_EEPROMLESS_IND_REG
[ 87.605000] wlcore: chip id 0x4030111
[ 87.615000] wlcore: firmware chunks to be uploaded: 6
[ 87.615000] wlcore: chunk 5 addr 0x0 len 196544
[ 87.620000] wlcore: starting firmware upload
[ 87.625000] wlcore: fw_data_len 196544 chunk_size 16384
[ 87.630000] wlcore: uploading fw chunk 0xc4b8700c to 0x0
[ 87.640000] wlcore: uploading fw chunk 0xc4b8b00c to 0x4000
[ 87.640000] wlcore: uploading fw chunk 0xc4b8f00c to 0x8000
[ 87.650000] wlcore: uploading fw chunk 0xc4b9300c to 0xc000
[ 87.655000] wlcore: uploading fw chunk 0xc4b9700c to 0x10000
[ 87.660000] wlcore: uploading fw chunk 0xc4b9b00c to 0x14000
[ 87.665000] wlcore: uploading fw chunk 0xc4b9f00c to 0x18000
[ 87.670000] wlcore: uploading fw chunk 0xc4ba300c to 0x1c000
[ 87.675000] wlcore: uploading fw chunk 0xc4ba700c to 0x20000
[ 87.680000] wlcore: uploading fw chunk 0xc4bab00c to 0x24000
[ 87.685000] wlcore: uploading fw chunk 0xc4baf00c to 0x28000
[ 87.690000] wlcore: uploading fw last chunk (16320 B) 0xc4bb300c to 0x2c000
[ 87.700000] wlcore: chunk 4 addr 0x20000000 len 41944
[ 87.700000] wlcore: starting firmware upload
[ 87.705000] wlcore: fw_data_len 41944 chunk_size 16384
[ 87.715000] wlcore: uploading fw chunk 0xc4bb6fd4 to 0x20000000
[ 87.720000] wlcore: uploading fw chunk 0xc4bbafd4 to 0x20004000
[ 87.725000] wlcore: uploading fw last chunk (9176 B) 0xc4bbefd4 to 0x20008000
[ 87.735000] wlcore: chunk 3 addr 0x40000 len 448
[ 87.735000] wlcore: starting firmware upload
[ 87.740000] wlcore: fw_data_len 448 chunk_size 16384
[ 87.750000] wlcore: uploading fw last chunk (448 B) 0xc4bc13b4 to 0x40000
[ 87.750000] wlcore: chunk 2 addr 0x40be0 len 29412
[ 87.755000] wlcore: starting firmware upload
[ 87.765000] wlcore: fw_data_len 29412 chunk_size 16384
[ 87.765000] wlcore: uploading fw chunk 0xc4bc157c to 0x40be0
[ 87.775000] wlcore: uploading fw last chunk (13028 B) 0xc4bc557c to 0x44be0
[ 87.780000] wlcore: chunk 1 addr 0x312000 len 8092
[ 87.780000] wlcore: starting firmware upload
[ 87.790000] wlcore: fw_data_len 8092 chunk_size 16384
[ 87.790000] wlcore: uploading fw last chunk (8092 B) 0xc4bc8868 to 0x312000
[ 87.795000] wlcore: chunk 0 addr 0x316000 len 3784
[ 87.800000] wlcore: starting firmware upload
[ 87.800000] wlcore: fw_data_len 3784 chunk_size 16384
[ 87.810000] wlcore: uploading fw last chunk (3784 B) 0xc4bca80c to 0x316000
[ 87.815000] wlcore: chip id after firmware boot: 0x4030111
[ 91.105000] wlcore: ERROR timeout waiting for the hardware to complete
initialization
[ 91.385000] wlcore: pause1 0x40f75
[ 91.385000] wlcore: clk2 0x80316a38
[ 91.390000] wlcore: soft reset bootdata 0x0
[ 91.390000] wlcore: nvs burst write 0x30546c: 0xbeef0000
[ 91.400000] wlcore: nvs burst write 0x305470: 0xdead
[ 91.405000] wlcore: ACX_EEPROMLESS_IND_REG
[ 91.405000] wlcore: chip id 0x4030111
[ 91.415000] wlcore: firmware chunks to be uploaded: 6
[ 91.415000] wlcore: chunk 5 addr 0x0 len 196544
[ 91.420000] wlcore: starting firmware upload
[ 91.425000] wlcore: fw_data_len 196544 chunk_size 16384
[ 91.430000] wlcore: uploading fw chunk 0xc4b8700c to 0x0
[ 91.435000] wlcore: uploading fw chunk 0xc4b8b00c to 0x4000
[ 91.440000] wlcore: uploading fw chunk 0xc4b8f00c to 0x8000
[ 91.450000] wlcore: uploading fw chunk 0xc4b9300c to 0xc000
[ 91.455000] wlcore: uploading fw chunk 0xc4b9700c to 0x10000
[ 91.460000] wlcore: uploading fw chunk 0xc4b9b00c to 0x14000
[ 91.465000] wlcore: uploading fw chunk 0xc4b9f00c to 0x18000
[ 91.470000] wlcore: uploading fw chunk 0xc4ba300c to 0x1c000
[ 91.475000] wlcore: uploading fw chunk 0xc4ba700c to 0x20000
[ 91.480000] wlcore: uploading fw chunk 0xc4bab00c to 0x24000
[ 91.485000] wlcore: uploading fw chunk 0xc4baf00c to 0x28000
[ 91.495000] wlcore: uploading fw last chunk (16320 B) 0xc4bb300c to 0x2c000
[ 91.500000] wlcore: chunk 4 addr 0x20000000 len 41944
[ 91.500000] wlcore: starting firmware upload
[ 91.505000] wlcore: fw_data_len 41944 chunk_size 16384
[ 91.515000] wlcore: uploading fw chunk 0xc4bb6fd4 to 0x20000000
[ 91.525000] wlcore: uploading fw chunk 0xc4bbafd4 to 0x20004000
[ 91.525000] wlcore: uploading fw last chunk (9176 B) 0xc4bbefd4 to 0x20008000
[ 91.535000] wlcore: chunk 3 addr 0x40000 len 448
[ 91.535000] wlcore: starting firmware upload
[ 91.540000] wlcore: fw_data_len 448 chunk_size 16384
[ 91.550000] wlcore: uploading fw last chunk (448 B) 0xc4bc13b4 to 0x40000
[ 91.550000] wlcore: chunk 2 addr 0x40be0 len 29412
[ 91.560000] wlcore: starting firmware upload
[ 91.560000] wlcore: fw_data_len 29412 chunk_size 16384
[ 91.575000] wlcore: uploading fw chunk 0xc4bc157c to 0x40be0
[ 91.580000] wlcore: uploading fw last chunk (13028 B) 0xc4bc557c to 0x44be0
[ 91.585000] wlcore: chunk 1 addr 0x312000 len 8092
[ 91.590000] wlcore: starting firmware upload
[ 91.595000] wlcore: fw_data_len 8092 chunk_size 16384
[ 91.600000] wlcore: uploading fw last chunk (8092 B) 0xc4bc8868 to 0x312000
[ 91.605000] wlcore: chunk 0 addr 0x316000 len 3784
[ 91.610000] wlcore: starting firmware upload
[ 91.615000] wlcore: fw_data_len 3784 chunk_size 16384
[ 91.620000] wlcore: uploading fw last chunk (3784 B) 0xc4bca80c to 0x316000
[ 91.630000] wlcore: chip id after firmware boot: 0x4030111
[ 94.910000] wlcore: ERROR timeout waiting for the hardware to complete
initialization
[ 95.190000] wlcore: pause1 0x40f75
[ 95.190000] wlcore: clk2 0x80316a38
[ 95.195000] wlcore: soft reset bootdata 0x0
[ 95.195000] wlcore: nvs burst write 0x30546c: 0xbeef0000
[ 95.205000] wlcore: nvs burst write 0x305470: 0xdead
[ 95.210000] wlcore: ACX_EEPROMLESS_IND_REG
[ 95.210000] wlcore: chip id 0x4030111
[ 95.220000] wlcore: firmware chunks to be uploaded: 6
[ 95.220000] wlcore: chunk 5 addr 0x0 len 196544
[ 95.225000] wlcore: starting firmware upload
[ 95.235000] wlcore: fw_data_len 196544 chunk_size 16384
[ 95.235000] wlcore: uploading fw chunk 0xc4b8700c to 0x0
[ 95.245000] wlcore: uploading fw chunk 0xc4b8b00c to 0x4000
[ 95.245000] wlcore: uploading fw chunk 0xc4b8f00c to 0x8000
[ 95.255000] wlcore: uploading fw chunk 0xc4b9300c to 0xc000
[ 95.260000] wlcore: uploading fw chunk 0xc4b9700c to 0x10000
[ 95.265000] wlcore: uploading fw chunk 0xc4b9b00c to 0x14000
[ 95.270000] wlcore: uploading fw chunk 0xc4b9f00c to 0x18000
[ 95.275000] wlcore: uploading fw chunk 0xc4ba300c to 0x1c000
[ 95.280000] wlcore: uploading fw chunk 0xc4ba700c to 0x20000
[ 95.285000] wlcore: uploading fw chunk 0xc4bab00c to 0x24000
[ 95.290000] wlcore: uploading fw chunk 0xc4baf00c to 0x28000
[ 95.295000] wlcore: uploading fw last chunk (16320 B) 0xc4bb300c to 0x2c000
[ 95.305000] wlcore: chunk 4 addr 0x20000000 len 41944
[ 95.305000] wlcore: starting firmware upload
[ 95.310000] wlcore: fw_data_len 41944 chunk_size 16384
[ 95.320000] wlcore: uploading fw chunk 0xc4bb6fd4 to 0x20000000
[ 95.325000] wlcore: uploading fw chunk 0xc4bbafd4 to 0x20004000
[ 95.330000] wlcore: uploading fw last chunk (9176 B) 0xc4bbefd4 to 0x20008000
[ 95.340000] wlcore: chunk 3 addr 0x40000 len 448
[ 95.340000] wlcore: starting firmware upload
[ 95.345000] wlcore: fw_data_len 448 chunk_size 16384
[ 95.350000] wlcore: uploading fw last chunk (448 B) 0xc4bc13b4 to 0x40000
[ 95.355000] wlcore: chunk 2 addr 0x40be0 len 29412
[ 95.360000] wlcore: starting firmware upload
[ 95.365000] wlcore: fw_data_len 29412 chunk_size 16384
[ 95.375000] wlcore: uploading fw chunk 0xc4bc157c to 0x40be0
[ 95.375000] wlcore: uploading fw last chunk (13028 B) 0xc4bc557c to 0x44be0
[ 95.385000] wlcore: chunk 1 addr 0x312000 len 8092
[ 95.385000] wlcore: starting firmware upload
[ 95.390000] wlcore: fw_data_len 8092 chunk_size 16384
[ 95.400000] wlcore: uploading fw last chunk (8092 B) 0xc4bc8868 to 0x312000
[ 95.405000] wlcore: chunk 0 addr 0x316000 len 3784
[ 95.405000] wlcore: starting firmware upload
[ 95.410000] wlcore: fw_data_len 3784 chunk_size 16384
[ 95.420000] wlcore: uploading fw last chunk (3784 B) 0xc4bca80c to 0x316000
[ 95.430000] wlcore: chip id after firmware boot: 0x4030111
[ 98.710000] wlcore: ERROR timeout waiting for the hardware to complete
initialization
[ 98.715000] wlcore: ERROR firmware boot failed despite 3 retries
ifconfig: SIOCSIFFLAGS: Input/output error
Even If I reboot my kernel and reload the modules the error persist! Only if I
power down/up my board I can initialize the network interface again.
Any hints on what could be wrong?
Best regards,
José Gonçalves
^ permalink raw reply
* [PATCH v3 3/8] wlcore: remove pwr_in_suspend from platform data
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
The pwr_in_suspend flag depends on the MMC settings which can be
retrieved from the SDIO subsystem, so it doesn't need to be part of
the platform data structure. Move it to the platform device data that
is passed from SDIO to wlcore.
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
drivers/net/wireless/ti/wlcore/main.c | 2 +-
drivers/net/wireless/ti/wlcore/sdio.c | 2 +-
drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 +
include/linux/wl12xx.h | 1 -
4 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 7b5d0cc..aada037 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5952,7 +5952,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
if (!ret) {
wl->irq_wake_enabled = true;
device_init_wakeup(wl->dev, 1);
- if (pdata->pwr_in_suspend)
+ if (pdev_data->pwr_in_suspend)
wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
}
#endif
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 29ef249..4c7e8ac 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func *func,
dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
if (mmcflags & MMC_PM_KEEP_POWER)
- pdev_data->pdata->pwr_in_suspend = true;
+ pdev_data->pwr_in_suspend = true;
sdio_set_drvdata(func, glue);
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index e5e1464..f2c4227 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -209,6 +209,7 @@ struct wl1271_if_operations {
struct wlcore_platdev_data {
struct wl12xx_platform_data *pdata;
struct wl1271_if_operations *if_ops;
+ bool pwr_in_suspend;
};
#define MAX_NUM_KEYS 14
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 1bfcd19..ab90b1c 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -59,7 +59,6 @@ struct wl12xx_platform_data {
int irq;
int board_ref_clock;
int board_tcxo_clock;
- bool pwr_in_suspend;
};
#ifdef CONFIG_WILINK_PLATFORM_DATA
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 8/8] wlcore/wl12xx: check if we got correct clock data from DT
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
The fref and the tcxo clocks settings are optional in some platforms.
WiLink8 doesn't need either, so we don't check the values. WiLink 6
only needs the fref clock, so we check that it is valid or return with
an error. WiLink7 needs both clocks, if either is not available we
return with an error.
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
drivers/net/wireless/ti/wl12xx/main.c | 20 +++++++++++++++++---
drivers/net/wireless/ti/wlcore/sdio.c | 4 ----
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 216c2fd..1be0b51 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -927,6 +927,11 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
u16 sys_clk_cfg;
int ret;
+ if ((priv->ref_clock < 0) || (priv->tcxo_clock < 0)) {
+ wl1271_error("Missing fref and/or tcxo clock settings\n");
+ return -EINVAL;
+ }
+
/* For XTAL-only modes, FREF will be used after switching from TCXO */
if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
@@ -976,6 +981,11 @@ static int wl127x_boot_clk(struct wl1271 *wl)
u32 clk;
int ret;
+ if (priv->ref_clock < 0) {
+ wl1271_error("Missing fref clock settings\n");
+ return -EINVAL;
+ }
+
if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
@@ -1757,7 +1767,7 @@ static int wl12xx_setup(struct wl1271 *wl)
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
wl12xx_conf_init(wl);
- if (!fref_param) {
+ if (!fref_param && (pdata->ref_clock_freq > 0)) {
priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
pdata->ref_clock_freq,
pdata->ref_clock_xtal);
@@ -1768,6 +1778,8 @@ static int wl12xx_setup(struct wl1271 *wl)
return priv->ref_clock;
}
+ } else if (!fref_param) {
+ priv->ref_clock = -EINVAL;
} else {
if (!strcmp(fref_param, "19.2"))
priv->ref_clock = WL12XX_REFCLOCK_19;
@@ -1785,7 +1797,7 @@ static int wl12xx_setup(struct wl1271 *wl)
wl1271_error("Invalid fref parameter %s", fref_param);
}
- if (!tcxo_param) {
+ if (!fref_param && (pdata->tcxo_clock_freq > 0)) {
priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
pdata->tcxo_clock_freq,
true);
@@ -1795,7 +1807,9 @@ static int wl12xx_setup(struct wl1271 *wl)
return priv->tcxo_clock;
}
- } else {
+ } else if (!fref_param) {
+ priv->tcxo_clock = -EINVAL;
+ }else {
if (!strcmp(tcxo_param, "19.2"))
priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
else if (!strcmp(tcxo_param, "26"))
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 60fce49..c76eb66 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -252,20 +252,16 @@ static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
of_fixed_clk_setup(clock_node);
- /* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
glue->refclock = of_clk_get_by_name(np, "refclock");
if (IS_ERR(glue->refclock)) {
- dev_err(dev, "couldn't find refclock on the device tree\n");
glue->refclock = NULL;
} else {
clk_prepare_enable(glue->refclock);
pdata->ref_clock_freq = clk_get_rate(glue->refclock);
}
- /* TODO: make sure we have this when needed (ie. for WL7) */
glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
if (IS_ERR(glue->tcxoclock)) {
- dev_err(dev, "couldn't find tcxoclock on the device tree\n");
glue->tcxoclock = NULL;
} else {
clk_prepare_enable(glue->tcxoclock);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 4/8] wl12xx: use frequency instead of enumerations for pdata clocks
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
Instead of defining an enumeration with the FW specific values for the
different clock rates, use the actual frequency instead. Also add a
boolean to specify whether the clock is XTAL or not.
Change all board files to reflect this.
Cc: Tony Lindgren <tony@atomide.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
arch/arm/mach-davinci/board-da850-evm.c | 3 +-
arch/arm/mach-omap2/board-4430sdp.c | 5 ++-
arch/arm/mach-omap2/board-omap3evm.c | 3 +-
arch/arm/mach-omap2/board-omap4panda.c | 3 +-
arch/arm/mach-omap2/board-zoom-peripherals.c | 3 +-
drivers/net/wireless/ti/wl12xx/main.c | 57 +++++++++++++++++++++++++-
drivers/net/wireless/ti/wl12xx/wl12xx.h | 28 +++++++++++++
include/linux/wl12xx.h | 27 ++----------
8 files changed, 97 insertions(+), 32 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 544b6fa..eddced8 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1377,7 +1377,8 @@ static const short da850_wl12xx_pins[] __initconst = {
static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
.irq = -1,
- .board_ref_clock = WL12XX_REFCLOCK_38,
+ .ref_clock_freq = 38400000,
+ .ref_clock_xtal = false,
};
static __init int da850_wl12xx_init(void)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 953f620..0d3cb10 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -693,8 +693,9 @@ static void __init omap4_sdp4430_wifi_mux_init(void)
}
static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
- .board_ref_clock = WL12XX_REFCLOCK_26,
- .board_tcxo_clock = WL12XX_TCXOCLOCK_26,
+ .ref_clock_freq = 26000000,
+ .ref_clock_xtal = false,
+ .tcxo_clock_freq = 26000000,
};
static void __init omap4_sdp4430_wifi_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 8abce3cd..8f953ed 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -458,7 +458,8 @@ static struct platform_device omap3evm_wlan_regulator = {
};
struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
- .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
+ .ref_clock_freq = 38400000,
+ .ref_clock_xtal = false,
};
#endif
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 5b33626..b90fd4c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -230,7 +230,8 @@ static struct platform_device omap_vwlan_device = {
};
static struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
- .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
+ .ref_clock_freq = 38400000,
+ .ref_clock_xtal = false,
};
static struct twl6040_codec_data twl6040_codec = {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 4f84cf9..83a9a36 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -244,7 +244,8 @@ static struct platform_device *zoom_devices[] __initdata = {
};
static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
- .board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
+ .ref_clock_freq = 26000000,
+ .ref_clock_xtal = false,
};
static struct omap2_hsmmc_info mmc[] = {
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 1c627da..216c2fd 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1701,6 +1701,42 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
},
};
+static const struct wl12xx_clock wl12xx_refclock_table[] = {
+ { 19200000, false, WL12XX_REFCLOCK_19 },
+ { 26000000, false, WL12XX_REFCLOCK_26 },
+ { 26000000, true, WL12XX_REFCLOCK_26_XTAL },
+ { 38400000, false, WL12XX_REFCLOCK_38 },
+ { 38400000, true, WL12XX_REFCLOCK_38_XTAL },
+ { 52000000, false, WL12XX_REFCLOCK_52 },
+ { 0, false, 0 }
+};
+
+static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
+ { 16368000, true, WL12XX_TCXOCLOCK_16_368 },
+ { 16800000, true, WL12XX_TCXOCLOCK_16_8 },
+ { 19200000, true, WL12XX_TCXOCLOCK_19_2 },
+ { 26000000, true, WL12XX_TCXOCLOCK_26 },
+ { 32736000, true, WL12XX_TCXOCLOCK_32_736 },
+ { 33600000, true, WL12XX_TCXOCLOCK_33_6 },
+ { 38400000, true, WL12XX_TCXOCLOCK_38_4 },
+ { 52000000, true, WL12XX_TCXOCLOCK_52 },
+ { 0, false, 0 }
+};
+
+static int wl12xx_get_clock_idx(struct wl12xx_clock *table, u32 freq, bool xtal)
+{
+ int i = 0;
+
+ while(table[i].freq != 0) {
+ if ((table[i].freq == freq) &&
+ (table[i].xtal == xtal))
+ return table[i].hw_idx;
+ i++;
+ };
+
+ return -EINVAL;
+}
+
static int wl12xx_setup(struct wl1271 *wl)
{
struct wl12xx_priv *priv = wl->priv;
@@ -1722,7 +1758,16 @@ static int wl12xx_setup(struct wl1271 *wl)
wl12xx_conf_init(wl);
if (!fref_param) {
- priv->ref_clock = pdata->board_ref_clock;
+ priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
+ pdata->ref_clock_freq,
+ pdata->ref_clock_xtal);
+ if (priv->ref_clock < 0) {
+ wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
+ pdata->ref_clock_freq,
+ pdata->ref_clock_xtal ? "XTAL" : "not XTAL");
+
+ return priv->ref_clock;
+ }
} else {
if (!strcmp(fref_param, "19.2"))
priv->ref_clock = WL12XX_REFCLOCK_19;
@@ -1741,7 +1786,15 @@ static int wl12xx_setup(struct wl1271 *wl)
}
if (!tcxo_param) {
- priv->tcxo_clock = pdata->board_tcxo_clock;
+ priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
+ pdata->tcxo_clock_freq,
+ true);
+ if (priv->tcxo_clock < 0) {
+ wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
+ pdata->tcxo_clock_freq);
+
+ return priv->tcxo_clock;
+ }
} else {
if (!strcmp(tcxo_param, "19.2"))
priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index 9e5484a..05f631b 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -79,4 +79,32 @@ struct wl12xx_priv {
struct wl127x_rx_mem_pool_addr *rx_mem_addr;
};
+/* Reference clock values */
+enum {
+ WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
+ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
+ WL12XX_REFCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
+ WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
+};
+
+/* TCXO clock values */
+enum {
+ WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */
+ WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */
+ WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */
+ WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */
+ WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */
+ WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
+};
+
+struct wl12xx_clock {
+ u32 freq;
+ bool xtal;
+ u8 hw_idx;
+};
+
#endif /* __WL12XX_PRIV_H__ */
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index ab90b1c..11491ad 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -26,28 +26,6 @@
#include <linux/err.h>
-/* Reference clock values */
-enum {
- WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
- WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
- WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
- WL12XX_REFCLOCK_52 = 3, /* 52 MHz */
- WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
- WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
-};
-
-/* TCXO clock values */
-enum {
- WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */
- WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */
- WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */
- WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */
- WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */
- WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */
- WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */
- WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
-};
-
struct wl1251_platform_data {
void (*set_power)(bool enable);
/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
@@ -57,8 +35,9 @@ struct wl1251_platform_data {
struct wl12xx_platform_data {
int irq;
- int board_ref_clock;
- int board_tcxo_clock;
+ int ref_clock_freq; /* in Hertz */
+ bool ref_clock_xtal; /* specify whether the clock is XTAL or not */
+ int tcxo_clock_freq; /* in Hertz, tcxo is always XTAL */
};
#ifdef CONFIG_WILINK_PLATFORM_DATA
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 6/8] wlcore: sdio: add wilink clock providers
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
Add refclock and tcxoclock as clock providers in WiLink. These clocks
are not accesible outside the WiLink module, but they are registered
in the clock framework anyway. Only the WiLink chip consumes these
clocks.
In theory, the WiLink chip could be connected to external clocks
instead of using these internal clocks, so make the clock consumer
code generic enough. If external clocks are used, then the internal
clock device tree nodes are not necessary, but the external ones must
be specified.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
drivers/net/wireless/ti/wlcore/sdio.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 9370d7e..980bf3d 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -34,6 +34,7 @@
#include <linux/wl12xx.h>
#include <linux/pm_runtime.h>
#include <linux/printk.h>
+#include <linux/clk-provider.h>
#include "wlcore.h"
#include "wl12xx_80211.h"
@@ -214,10 +215,15 @@ static struct wl1271_if_operations sdio_ops = {
.set_block_size = wl1271_sdio_set_block_size,
};
+static const struct of_device_id wlcore_sdio_of_clk_match_table[] = {
+ { .compatible = "ti,wilink-clock" },
+};
+
static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
{
struct wl12xx_platform_data *pdata;
struct device_node *np = dev->of_node;
+ struct device_node *clock_node;
if (!np) {
np = of_find_matching_node(NULL, dev->driver->of_match_table);
@@ -241,6 +247,9 @@ static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
goto out_free;
}
+ for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+ of_fixed_clk_setup(clock_node);
+
goto out;
out_free:
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 7/8] wlcore: sdio: get clocks from device tree
From: Luciano Coelho @ 2013-07-03 14:03 UTC (permalink / raw)
To: linux-wireless, tony, nsekhar
Cc: mturquette, mark.rutland, balbi, grant.likely, rob.herring,
devicetree-discuss, linux-doc, linux-kernel, linux-omap,
linux-arm-kernel, coelho, nm
In-Reply-To: <1372860209-3504-1-git-send-email-coelho@ti.com>
Read the clock nodes from the device tree and use them to set the
frequency for the refclock and the tcxo clock.
Also, call sdio_set_drvdata() earlier, so the glue is already set in
the driver data when we call wlcore_get_pdata_from_of() and we don't
need to pass it as a parameter.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
drivers/net/wireless/ti/wlcore/sdio.c | 36 +++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 980bf3d..60fce49 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -53,6 +53,7 @@ static bool dump = false;
struct wl12xx_sdio_glue {
struct device *dev;
struct platform_device *core;
+ struct clk *refclock, *tcxoclock;
};
static const struct sdio_device_id wl1271_devices[] = {
@@ -224,6 +225,7 @@ static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
struct wl12xx_platform_data *pdata;
struct device_node *np = dev->of_node;
struct device_node *clock_node;
+ struct wl12xx_sdio_glue *glue = sdio_get_drvdata(dev_to_sdio_func(dev));
if (!np) {
np = of_find_matching_node(NULL, dev->driver->of_match_table);
@@ -250,6 +252,26 @@ static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
of_fixed_clk_setup(clock_node);
+ /* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+ glue->refclock = of_clk_get_by_name(np, "refclock");
+ if (IS_ERR(glue->refclock)) {
+ dev_err(dev, "couldn't find refclock on the device tree\n");
+ glue->refclock = NULL;
+ } else {
+ clk_prepare_enable(glue->refclock);
+ pdata->ref_clock_freq = clk_get_rate(glue->refclock);
+ }
+
+ /* TODO: make sure we have this when needed (ie. for WL7) */
+ glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
+ if (IS_ERR(glue->tcxoclock)) {
+ dev_err(dev, "couldn't find tcxoclock on the device tree\n");
+ glue->tcxoclock = NULL;
+ } else {
+ clk_prepare_enable(glue->tcxoclock);
+ pdata->ref_clock_freq = clk_get_rate(glue->tcxoclock);
+ }
+
goto out;
out_free:
@@ -294,6 +316,8 @@ static int wl1271_probe(struct sdio_func *func,
/* Use block mode for transferring over one block size of data */
func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+ sdio_set_drvdata(func, glue);
+
/* The pdata allocated here is freed when the device is freed,
* so we don't need an additional out label to free it in case
* of error further on.
@@ -319,8 +343,6 @@ static int wl1271_probe(struct sdio_func *func,
if (mmcflags & MMC_PM_KEEP_POWER)
pdev_data->pwr_in_suspend = true;
- sdio_set_drvdata(func, glue);
-
/* Tell PM core that we don't need the card to be powered now */
pm_runtime_put_noidle(&func->dev);
@@ -387,6 +409,16 @@ static void wl1271_remove(struct sdio_func *func)
{
struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
+ if (glue->refclock) {
+ clk_disable_unprepare(glue->refclock);
+ clk_put(glue->refclock);
+ }
+
+ if (glue->tcxoclock) {
+ clk_disable_unprepare(glue->tcxoclock);
+ clk_put(glue->tcxoclock);
+ }
+
/* Undo decrement done above in wl1271_probe */
pm_runtime_get_noresume(&func->dev);
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox