Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5934110 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Wey-Yi Guy
Browse files

iwlagn: simplify the bus architecture



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: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent 41c50542
Loading
Loading
Loading
Loading
+12 −19
Original line number Diff line number Diff line
@@ -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"

/******************************************************************************
@@ -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;
@@ -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;
@@ -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);
}

@@ -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");
@@ -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);
}

@@ -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;
@@ -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;
@@ -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
	 */
@@ -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
@@ -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);

+1 −2
Original line number Diff line number Diff line
@@ -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__ */
+73 −0
Original line number Diff line number Diff line
@@ -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);

+2 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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)
+4 −4
Original line number Diff line number Diff line
@@ -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 {									\
Loading