Skip to content

Commit

Permalink
iwlagn: simplify the bus architecture
Browse files Browse the repository at this point in the history
Call iwl_probe with a ready iwl_bus struct. This means that the bus layer
assigns the irq, dev and iwl_bus_ops pointers to iwl_bus before giving it to
iwl_probe.

The device specific struct is allocated together with the common iwl_bus struct
by the bus specific layer. The pointer to the aggregate struct is passed to the
upper layer that holds a pointer to iwl_bus instead of an embedded iw_bus.
The private data given to the PCI subsystem is now iwl_bus and not iwl_priv.

Provide bus_* inliners on the way in order  to simplify the syntax.

Rename iwl-pci.h -> iwl-bus.h since it is bus agnostic and represent the
external of the bus layer.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
  • Loading branch information
Emmanuel Grumbach authored and Wey-Yi Guy committed Jul 21, 2011
1 parent 41c5054 commit d593411
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 140 deletions.
31 changes: 12 additions & 19 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
#include "iwl-sta.h"
#include "iwl-agn-calib.h"
#include "iwl-agn.h"
#include "iwl-pci.h"
#include "iwl-bus.h"
#include "iwl-trans.h"

/******************************************************************************
Expand Down Expand Up @@ -580,7 +580,7 @@ static struct attribute_group iwl_attribute_group = {
static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc)
{
if (desc->v_addr)
dma_free_coherent(priv->bus.dev, desc->len,
dma_free_coherent(priv->bus->dev, desc->len,
desc->v_addr, desc->p_addr);
desc->v_addr = NULL;
desc->len = 0;
Expand All @@ -606,7 +606,7 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
return -EINVAL;
}

desc->v_addr = dma_alloc_coherent(priv->bus.dev, len,
desc->v_addr = dma_alloc_coherent(priv->bus->dev, len,
&desc->p_addr, GFP_KERNEL);
if (!desc->v_addr)
return -ENOMEM;
Expand Down Expand Up @@ -660,7 +660,7 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
priv->firmware_name);

return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
priv->bus.dev,
priv->bus->dev,
GFP_KERNEL, priv, iwl_ucode_callback);
}

Expand Down Expand Up @@ -1163,7 +1163,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
if (err)
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);

err = sysfs_create_group(&(priv->bus.dev->kobj),
err = sysfs_create_group(&(priv->bus->dev->kobj),
&iwl_attribute_group);
if (err) {
IWL_ERR(priv, "failed to create sysfs device attributes\n");
Expand All @@ -1187,7 +1187,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
iwl_dealloc_ucode(priv);
out_unbind:
complete(&priv->_agn.firmware_loading_complete);
device_release_driver(priv->bus.dev);
device_release_driver(priv->bus->dev);
release_firmware(ucode_raw);
}

Expand Down Expand Up @@ -3102,8 +3102,7 @@ static void iwl_init_context(struct iwl_priv *priv)
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
struct iwl_cfg *cfg)
int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
{
int err = 0;
struct iwl_priv *priv;
Expand All @@ -3121,17 +3120,12 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
}

priv = hw->priv;

priv->bus.priv = priv;
priv->bus.bus_specific = bus_specific;
priv->bus.ops = bus_ops;
priv->bus.irq = priv->bus.ops->get_irq(&priv->bus);
priv->bus.ops->set_drv_data(&priv->bus, priv);
priv->bus.dev = priv->bus.ops->get_dev(&priv->bus);
priv->bus = bus;
bus_set_drv_data(priv->bus, priv);

/* At this point both hw and priv are allocated. */

SET_IEEE80211_DEV(hw, priv->bus.dev);
SET_IEEE80211_DEV(hw, priv->bus->dev);

IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
priv->cfg = cfg;
Expand All @@ -3154,7 +3148,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
if (iwl_alloc_traffic_mem(priv))
IWL_ERR(priv, "Not enough memory to generate traffic log\n");


/* these spin locks will be used in apm_ops.init and EEPROM access
* we should init now
*/
Expand Down Expand Up @@ -3289,7 +3282,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");

iwl_dbgfs_unregister(priv);
sysfs_remove_group(&priv->bus.dev->kobj,
sysfs_remove_group(&priv->bus->dev->kobj,
&iwl_attribute_group);

/* ieee80211_unregister_hw call wil cause iwl_mac_stop to
Expand Down Expand Up @@ -3339,7 +3332,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)

trans_free(&priv->trans);

priv->bus.ops->set_drv_data(&priv->bus, NULL);
bus_set_drv_data(priv->bus, NULL);

iwl_uninit_drv(priv);

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/iwlwifi/iwl-agn.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,7 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
}
#endif

int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
struct iwl_cfg *cfg);
int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg);
void __devexit iwl_remove(struct iwl_priv * priv);

#endif /* __iwl_agn_h__ */
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,79 @@
#ifndef __iwl_pci_h__
#define __iwl_pci_h__

struct iwl_bus;

/**
* struct iwl_bus_ops - bus specific operations
* @get_pm_support: must returns true if the bus can go to sleep
* @apm_config: will be called during the config of the APM configuration
* @set_drv_data: set the priv pointer to the bus layer
* @get_hw_id: prints the hw_id in the provided buffer
* @write8: write a byte to register at offset ofs
* @write32: write a dword to register at offset ofs
* @wread32: read a dword at register at offset ofs
*/
struct iwl_bus_ops {
bool (*get_pm_support)(struct iwl_bus *bus);
void (*apm_config)(struct iwl_bus *bus);
void (*set_drv_data)(struct iwl_bus *bus, void *drv_data);
void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len);
void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
u32 (*read32)(struct iwl_bus *bus, u32 ofs);
};

struct iwl_bus {
/* Common data to all buses */

/*TODO: priv should be void * */
struct iwl_priv *priv; /* driver's context */
struct device *dev;
struct iwl_bus_ops *ops;

unsigned int irq;

/* pointer to bus specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
char bus_specific[0] __attribute__((__aligned__(sizeof(void *))));
};

static inline bool bus_get_pm_support(struct iwl_bus *bus)
{
return bus->ops->get_pm_support(bus);
}

static inline void bus_apm_config(struct iwl_bus *bus)
{
bus->ops->apm_config(bus);
}

static inline void bus_set_drv_data(struct iwl_bus *bus, void *drv_data)
{
bus->ops->set_drv_data(bus, drv_data);
}

static inline void bus_get_hw_id(struct iwl_bus *bus, char buf[], int buf_len)
{
bus->ops->get_hw_id(bus, buf, buf_len);
}

static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val)
{
bus->ops->write8(bus, ofs, val);
}

static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val)
{
bus->ops->write32(bus, ofs, val);
}

static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs)
{
return bus->ops->read32(bus, ofs);
}

int __must_check iwl_pci_register_driver(void);
void iwl_pci_unregister_driver(void);

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
char buf[32];
priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf));
bus_get_hw_id(priv->bus, buf, sizeof(buf));
IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
"Please send your %s to maintainer.\n", buf);
priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
Expand Down Expand Up @@ -1012,7 +1012,7 @@ int iwl_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);

priv->bus.ops->apm_config(&priv->bus);
bus_apm_config(priv->bus);

/* Configure analog phase-lock-loop before activating to D0A */
if (priv->cfg->base_params->pll_cfg_val)
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/wireless/iwlwifi/iwl-debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
struct iwl_priv;
extern u32 iwl_debug_level;

#define IWL_ERR(p, f, a...) dev_err(p->bus.ops->get_dev(&p->bus), f, ## a)
#define IWL_WARN(p, f, a...) dev_warn(p->bus.ops->get_dev(&p->bus), f, ## a)
#define IWL_INFO(p, f, a...) dev_info(p->bus.ops->get_dev(&p->bus), f, ## a)
#define IWL_CRIT(p, f, a...) dev_crit(p->bus.ops->get_dev(&p->bus), f, ## a)
#define IWL_ERR(p, f, a...) dev_err(p->bus->dev, f, ## a)
#define IWL_WARN(p, f, a...) dev_warn(p->bus->dev, f, ## a)
#define IWL_INFO(p, f, a...) dev_info(p->bus->dev, f, ## a)
#define IWL_CRIT(p, f, a...) dev_crit(p->bus->dev, f, ## a)

#define iwl_print_hex_error(priv, p, len) \
do { \
Expand Down
41 changes: 2 additions & 39 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "iwl-power.h"
#include "iwl-agn-rs.h"
#include "iwl-agn-tt.h"
#include "iwl-bus.h"
#include "iwl-trans.h"

#define DRV_NAME "iwlagn"
Expand Down Expand Up @@ -1193,44 +1194,6 @@ struct iwl_testmode_trace {
};
#endif

struct iwl_bus;

/**
* struct iwl_bus_ops - bus specific operations
* @get_pm_support: must returns true if the bus can go to sleep
* @apm_config: will be called during the config of the APM configuration
* @set_drv_data: set the priv pointer to the bus layer
* @get_dev: returns the device struct
* @get_irq: returns the irq number
* @get_hw_id: prints the hw_id in the provided buffer
* @write8: write a byte to register at offset ofs
* @write32: write a dword to register at offset ofs
* @wread32: read a dword at register at offset ofs
*/
struct iwl_bus_ops {
bool (*get_pm_support)(struct iwl_bus *bus);
void (*apm_config)(struct iwl_bus *bus);
void (*set_drv_data)(struct iwl_bus *bus, void *priv);
struct device *(*get_dev)(const struct iwl_bus *bus);
unsigned int (*get_irq)(const struct iwl_bus *bus);
void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len);
void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
u32 (*read32)(struct iwl_bus *bus, u32 ofs);
};

struct iwl_bus {
/* pointer to bus specific struct */
void *bus_specific;

/* Common data to all buses */
struct iwl_priv *priv; /* driver's context */
struct device *dev;
struct iwl_bus_ops *ops;
unsigned int irq;
};

/* uCode ownership */
#define IWL_OWNERSHIP_DRIVER 0
#define IWL_OWNERSHIP_TM 1
Expand Down Expand Up @@ -1302,7 +1265,7 @@ struct iwl_priv {
spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;

struct iwl_bus bus; /* bus specific data */
struct iwl_bus *bus; /* bus specific data */
struct iwl_trans trans;

/* microcode/device supports multiple contexts */
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,23 @@
#include "iwl-dev.h"
#include "iwl-debug.h"
#include "iwl-devtrace.h"
#include "iwl-bus.h"

static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
{
trace_iwlwifi_dev_iowrite8(priv, ofs, val);
priv->bus.ops->write8(&priv->bus, ofs, val);
bus_write8(priv->bus, ofs, val);
}

static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
{
trace_iwlwifi_dev_iowrite32(priv, ofs, val);
priv->bus.ops->write32(&priv->bus, ofs, val);
bus_write32(priv->bus, ofs, val);
}

static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
{
u32 val = priv->bus.ops->read32(&priv->bus, ofs);
u32 val = bus_read32(priv->bus, ofs);
trace_iwlwifi_dev_ioread32(priv, ofs, val);
return val;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-led.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ void iwl_leds_init(struct iwl_priv *priv)
break;
}

ret = led_classdev_register(priv->bus.dev,
ret = led_classdev_register(priv->bus->dev,
&priv->led);
if (ret) {
kfree(priv->led.name);
Expand Down
Loading

0 comments on commit d593411

Please sign in to comment.