mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
ath9k_hw: add a new register op for read-mask-write
Reduces the number of calls to register ops. On MIPS this reduces the ath9k_hw binary size from 321k down to 310k Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
f9f84e96f6
commit
845e03c93d
4 changed files with 42 additions and 6 deletions
|
@ -119,6 +119,7 @@ struct ath_ops {
|
||||||
void (*write)(void *, u32 val, u32 reg_offset);
|
void (*write)(void *, u32 val, u32 reg_offset);
|
||||||
void (*enable_write_buffer)(void *);
|
void (*enable_write_buffer)(void *);
|
||||||
void (*write_flush) (void *);
|
void (*write_flush) (void *);
|
||||||
|
u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ath_common;
|
struct ath_common;
|
||||||
|
|
|
@ -430,6 +430,17 @@ static void ath9k_regwrite_flush(void *hw_priv)
|
||||||
mutex_unlock(&priv->wmi->multi_write_mutex);
|
mutex_unlock(&priv->wmi->multi_write_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = ath9k_regread(hw_priv, reg_offset);
|
||||||
|
val &= ~clr;
|
||||||
|
val |= set;
|
||||||
|
ath9k_regwrite(hw_priv, val, reg_offset);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
|
static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
|
||||||
{
|
{
|
||||||
*csz = L1_CACHE_BYTES >> 2;
|
*csz = L1_CACHE_BYTES >> 2;
|
||||||
|
@ -655,6 +666,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
|
||||||
ah->reg_ops.write = ath9k_regwrite;
|
ah->reg_ops.write = ath9k_regwrite;
|
||||||
ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
|
ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
|
||||||
ah->reg_ops.write_flush = ath9k_regwrite_flush;
|
ah->reg_ops.write_flush = ath9k_regwrite_flush;
|
||||||
|
ah->reg_ops.rmw = ath9k_reg_rmw;
|
||||||
priv->ah = ah;
|
priv->ah = ah;
|
||||||
|
|
||||||
common = ath9k_hw_common(ah);
|
common = ath9k_hw_common(ah);
|
||||||
|
|
|
@ -73,6 +73,9 @@
|
||||||
#define REG_READ_MULTI(_ah, _addr, _val, _cnt) \
|
#define REG_READ_MULTI(_ah, _addr, _val, _cnt) \
|
||||||
(_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
|
(_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
|
||||||
|
|
||||||
|
#define REG_RMW(_ah, _reg, _set, _clr) \
|
||||||
|
(_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr))
|
||||||
|
|
||||||
#define ENABLE_REGWRITE_BUFFER(_ah) \
|
#define ENABLE_REGWRITE_BUFFER(_ah) \
|
||||||
do { \
|
do { \
|
||||||
if ((_ah)->reg_ops.enable_write_buffer) \
|
if ((_ah)->reg_ops.enable_write_buffer) \
|
||||||
|
@ -87,17 +90,14 @@
|
||||||
|
|
||||||
#define SM(_v, _f) (((_v) << _f##_S) & _f)
|
#define SM(_v, _f) (((_v) << _f##_S) & _f)
|
||||||
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
|
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
|
||||||
#define REG_RMW(_a, _r, _set, _clr) \
|
|
||||||
REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
|
|
||||||
#define REG_RMW_FIELD(_a, _r, _f, _v) \
|
#define REG_RMW_FIELD(_a, _r, _f, _v) \
|
||||||
REG_WRITE(_a, _r, \
|
REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f))
|
||||||
(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
|
|
||||||
#define REG_READ_FIELD(_a, _r, _f) \
|
#define REG_READ_FIELD(_a, _r, _f) \
|
||||||
(((REG_READ(_a, _r) & _f) >> _f##_S))
|
(((REG_READ(_a, _r) & _f) >> _f##_S))
|
||||||
#define REG_SET_BIT(_a, _r, _f) \
|
#define REG_SET_BIT(_a, _r, _f) \
|
||||||
REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f))
|
REG_RMW(_a, _r, (_f), 0)
|
||||||
#define REG_CLR_BIT(_a, _r, _f) \
|
#define REG_CLR_BIT(_a, _r, _f) \
|
||||||
REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
|
REG_RMW(_a, _r, 0, (_f))
|
||||||
|
|
||||||
#define DO_DELAY(x) do { \
|
#define DO_DELAY(x) do { \
|
||||||
if (((++(x) % 64) == 0) && \
|
if (((++(x) % 64) == 0) && \
|
||||||
|
|
|
@ -196,6 +196,28 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
|
||||||
|
{
|
||||||
|
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||||
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
|
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||||
|
unsigned long uninitialized_var(flags);
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (ah->config.serialize_regmode == SER_REG_MODE_ON)
|
||||||
|
spin_lock_irqsave(&sc->sc_serial_rw, flags);
|
||||||
|
|
||||||
|
val = ioread32(sc->mem + reg_offset);
|
||||||
|
val &= ~clr;
|
||||||
|
val |= set;
|
||||||
|
iowrite32(val, sc->mem + reg_offset);
|
||||||
|
|
||||||
|
if (ah->config.serialize_regmode == SER_REG_MODE_ON)
|
||||||
|
spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
/**************************/
|
/**************************/
|
||||||
|
@ -548,6 +570,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||||
ah->hw_version.subsysid = subsysid;
|
ah->hw_version.subsysid = subsysid;
|
||||||
ah->reg_ops.read = ath9k_ioread32;
|
ah->reg_ops.read = ath9k_ioread32;
|
||||||
ah->reg_ops.write = ath9k_iowrite32;
|
ah->reg_ops.write = ath9k_iowrite32;
|
||||||
|
ah->reg_ops.rmw = ath9k_reg_rmw;
|
||||||
sc->sc_ah = ah;
|
sc->sc_ah = ah;
|
||||||
|
|
||||||
if (!pdata) {
|
if (!pdata) {
|
||||||
|
|
Loading…
Reference in a new issue