kernel-ark/include/linux/wl12xx.h
Ido Yariv 341b7cde6c wl12xx: Handle platforms without level trigger interrupts
Some platforms are incapable of triggering on level interrupts. Add a
platform quirks member in the platform data structure, as well as an
edge interrupt quirk which can be set on such platforms.

When the interrupt is requested with IRQF_TRIGGER_RISING, IRQF_ONESHOT
cannot be used, as we might miss interrupts that occur after the FW
status is cleared and before the threaded interrupt handler exits.

Moreover, when IRQF_ONESHOT is not set, iterating more than once in the
threaded interrupt handler introduces a few race conditions between this
handler and the hardirq handler. Currently this is worked around by
limiting the loop to one iteration only. This workaround has an impact
on performance. To remove to this restriction, the race conditions will
need to be addressed.

Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
2011-04-19 16:49:20 +03:00

79 lines
2.1 KiB
C

/*
* This file is part of wl12xx
*
* Copyright (C) 2009 Nokia Corporation
*
* Contact: Luciano Coelho <luciano.coelho@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#ifndef _LINUX_WL12XX_H
#define _LINUX_WL12XX_H
/* 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_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;
int board_ref_clock;
int board_tcxo_clock;
unsigned long platform_quirks;
};
/* Platform does not support level trigger interrupts */
#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
#ifdef CONFIG_WL12XX_PLATFORM_DATA
int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
#else
static inline
int wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
{
return -ENOSYS;
}
#endif
const struct wl12xx_platform_data *wl12xx_get_platform_data(void);
#endif