diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 284bb508c87b3cf6b404fcebc03c7eb601b42088..df4c06d41678abd6d52e1334a357e85eb61ad643 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -292,7 +292,7 @@ struct wl1251 {
 	bool mac80211_registered;
 
 	struct spi_device *spi;
-	struct wl1251_if_operations *if_ops;
+	const struct wl1251_if_operations *if_ops;
 
 	void (*set_power)(bool enable);
 	int irq;
@@ -404,6 +404,11 @@ struct wl1251 {
 int wl1251_plt_start(struct wl1251 *wl);
 int wl1251_plt_stop(struct wl1251 *wl);
 
+irqreturn_t wl1251_irq(int irq, void *cookie);
+struct ieee80211_hw *wl1251_alloc_hw(void);
+int wl1251_free_hw(struct wl1251 *wl);
+int wl1251_init_ieee80211(struct wl1251 *wl);
+
 #define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
 #define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
 #define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index 2e3171a61b77110c0cb2f17b8db04af72f0e0ce7..91fe16c8d5b70df0d83a740d3d7c335543834b5b 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -2,7 +2,6 @@
 
 #include <linux/module.h>
 #include <linux/crc7.h>
-#include <linux/spi/spi.h>
 
 #include "wl1251.h"
 #include "reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index 2c30c705908e658c623e8b098faab248f5ac9549..dfbf6811976d2f4c5207eb39dde50a44d4109773 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -2,7 +2,6 @@
 
 #include <linux/module.h>
 #include <linux/crc7.h>
-#include <linux/spi/spi.h>
 
 #include "wl1251.h"
 #include "reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 0f30d0a62aa9acc3d87dde6da49f337259fe1ad2..74544e11f69204827cd786cdfba59f54bc05a1e5 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -26,17 +26,15 @@
 #include <linux/firmware.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-#include <linux/spi/spi.h>
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
-#include <linux/spi/wl12xx.h>
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
 #include "reg.h"
 #include "wl1251_ops.h"
 #include "wl1251_io.h"
-#include "wl1251_spi.h"
+#include "wl1251_cmd.h"
 #include "wl1251_event.h"
 #include "wl1251_tx.h"
 #include "wl1251_rx.h"
@@ -59,7 +57,7 @@ static void wl1251_power_on(struct wl1251 *wl)
 	wl->set_power(true);
 }
 
-static irqreturn_t wl1251_irq(int irq, void *cookie)
+irqreturn_t wl1251_irq(int irq, void *cookie)
 {
 	struct wl1251 *wl;
 
@@ -1169,8 +1167,10 @@ static int wl1251_register_hw(struct wl1251 *wl)
 	return 0;
 }
 
-static int wl1251_init_ieee80211(struct wl1251 *wl)
+int wl1251_init_ieee80211(struct wl1251 *wl)
 {
+	int ret;
+
 	/* The tx descriptor buffer and the TKIP space */
 	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
 		+ WL1251_TKIP_IV_SPACE;
@@ -1186,41 +1186,37 @@ static int wl1251_init_ieee80211(struct wl1251 *wl)
 	wl->hw->wiphy->max_scan_ssids = 1;
 	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
 
-	SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
+	ret = wl1251_register_hw(wl);
+	if (ret)
+		goto out;
 
-	return 0;
-}
+	wl1251_debugfs_init(wl);
+	wl1251_notice("initialized");
 
-extern struct wl1251_if_operations wl1251_spi_ops;
+	ret = 0;
+
+out:
+	return ret;
+}
 
 #define WL1251_DEFAULT_CHANNEL 1
-static int __devinit wl1251_probe(struct spi_device *spi)
+struct ieee80211_hw *wl1251_alloc_hw(void)
 {
-	struct wl12xx_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1251 *wl;
-	int ret, i;
+	int i;
 	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
 
-	pdata = spi->dev.platform_data;
-	if (!pdata) {
-		wl1251_error("no platform data");
-		return -ENODEV;
-	}
-
 	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
 	if (!hw) {
 		wl1251_error("could not alloc ieee80211_hw");
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	wl = hw->priv;
 	memset(wl, 0, sizeof(*wl));
 
 	wl->hw = hw;
-	dev_set_drvdata(&spi->dev, wl);
-	wl->spi = spi;
-	wl->if_ops = &wl1251_spi_ops;
 
 	wl->data_in_count = 0;
 
@@ -1268,74 +1264,15 @@ static int __devinit wl1251_probe(struct spi_device *spi)
 	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
 	if (!wl->rx_descriptor) {
 		wl1251_error("could not allocate memory for rx descriptor");
-		ret = -ENOMEM;
-		goto out_free;
+		ieee80211_free_hw(hw);
+		return ERR_PTR(-ENOMEM);
 	}
 
-	/* This is the only SPI value that we need to set here, the rest
-	 * comes from the board-peripherals file */
-	spi->bits_per_word = 32;
-
-	ret = spi_setup(spi);
-	if (ret < 0) {
-		wl1251_error("spi_setup failed");
-		goto out_free;
-	}
-
-	wl->set_power = pdata->set_power;
-	if (!wl->set_power) {
-		wl1251_error("set power function missing in platform data");
-		ret = -ENODEV;
-		goto out_free;
-	}
-
-	wl->irq = spi->irq;
-	if (wl->irq < 0) {
-		wl1251_error("irq missing in platform data");
-		ret = -ENODEV;
-		goto out_free;
-	}
-
-	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
-	if (ret < 0) {
-		wl1251_error("request_irq() failed: %d", ret);
-		goto out_free;
-	}
-
-	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
-	disable_irq(wl->irq);
-
-	ret = wl1251_init_ieee80211(wl);
-	if (ret)
-		goto out_irq;
-
-	ret = wl1251_register_hw(wl);
-	if (ret)
-		goto out_irq;
-
-	wl1251_debugfs_init(wl);
-
-	wl1251_notice("initialized");
-
-	return 0;
-
- out_irq:
-	free_irq(wl->irq, wl);
-
- out_free:
-	kfree(wl->rx_descriptor);
-	wl->rx_descriptor = NULL;
-
-	ieee80211_free_hw(hw);
-
-	return ret;
+	return hw;
 }
 
-static int __devexit wl1251_remove(struct spi_device *spi)
+int wl1251_free_hw(struct wl1251 *wl)
 {
-	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
-
 	ieee80211_unregister_hw(wl->hw);
 
 	wl1251_debugfs_exit(wl);
@@ -1355,44 +1292,3 @@ static int __devexit wl1251_remove(struct spi_device *spi)
 
 	return 0;
 }
-
-
-static struct spi_driver wl1251_spi_driver = {
-	.driver = {
-		/* FIXME: use wl12xx name to not break the user space */
-		.name		= "wl12xx",
-		.bus		= &spi_bus_type,
-		.owner		= THIS_MODULE,
-	},
-
-	.probe		= wl1251_probe,
-	.remove		= __devexit_p(wl1251_remove),
-};
-
-static int __init wl1251_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&wl1251_spi_driver);
-	if (ret < 0) {
-		wl1251_error("failed to register spi driver: %d", ret);
-		goto out;
-	}
-
-out:
-	return ret;
-}
-
-static void __exit wl1251_exit(void)
-{
-	spi_unregister_driver(&wl1251_spi_driver);
-
-	wl1251_notice("unloaded");
-}
-
-module_init(wl1251_init);
-module_exit(wl1251_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
-		"Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index ceb237b4e579f028a77c6a8dfad66df7b2a6dfe5..13e7a726dea2f9a084b5619435cccaa235bd80cb 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -21,9 +21,11 @@
  *
  */
 
+#include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/wl12xx.h>
 
 #include "wl1251.h"
 #include "reg.h"
@@ -55,7 +57,7 @@ static void wl1251_spi_reset(struct wl1251 *wl)
 	wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
 }
 
-static void wl1251_spi_init(struct wl1251 *wl)
+static void wl1251_spi_wake(struct wl1251 *wl)
 {
 	u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
 	struct spi_transfer t;
@@ -112,7 +114,7 @@ static void wl1251_spi_init(struct wl1251 *wl)
 static void wl1251_spi_reset_wake(struct wl1251 *wl)
 {
 	wl1251_spi_reset(wl);
-	wl1251_spi_init(wl);
+	wl1251_spi_wake(wl);
 }
 
 static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
@@ -191,3 +193,122 @@ const struct wl1251_if_operations wl1251_spi_ops = {
 	.write = wl1251_spi_write,
 	.reset = wl1251_spi_reset_wake,
 };
+
+static int __devinit wl1251_spi_probe(struct spi_device *spi)
+{
+	struct wl12xx_platform_data *pdata;
+	struct ieee80211_hw *hw;
+	struct wl1251 *wl;
+	int ret;
+
+	pdata = spi->dev.platform_data;
+	if (!pdata) {
+		wl1251_error("no platform data");
+		return -ENODEV;
+	}
+
+	hw = wl1251_alloc_hw();
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	wl = hw->priv;
+
+	SET_IEEE80211_DEV(hw, &spi->dev);
+	dev_set_drvdata(&spi->dev, wl);
+	wl->spi = spi;
+	wl->if_ops = &wl1251_spi_ops;
+
+	/* This is the only SPI value that we need to set here, the rest
+	 * comes from the board-peripherals file */
+	spi->bits_per_word = 32;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		wl1251_error("spi_setup failed");
+		goto out_free;
+	}
+
+	wl->set_power = pdata->set_power;
+	if (!wl->set_power) {
+		wl1251_error("set power function missing in platform data");
+		return -ENODEV;
+	}
+
+	wl->irq = spi->irq;
+	if (wl->irq < 0) {
+		wl1251_error("irq missing in platform data");
+		return -ENODEV;
+	}
+
+	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
+	if (ret < 0) {
+		wl1251_error("request_irq() failed: %d", ret);
+		goto out_free;
+	}
+
+	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+	disable_irq(wl->irq);
+
+	ret = wl1251_init_ieee80211(wl);
+	if (ret)
+		goto out_irq;
+
+	return 0;
+
+ out_irq:
+	free_irq(wl->irq, wl);
+
+ out_free:
+	ieee80211_free_hw(hw);
+
+	return ret;
+}
+
+static int __devexit wl1251_spi_remove(struct spi_device *spi)
+{
+	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
+
+	wl1251_free_hw(wl);
+
+	return 0;
+}
+
+static struct spi_driver wl1251_spi_driver = {
+	.driver = {
+		.name		= "wl12xx",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= wl1251_spi_probe,
+	.remove		= __devexit_p(wl1251_spi_remove),
+};
+
+static int __init wl1251_spi_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&wl1251_spi_driver);
+	if (ret < 0) {
+		wl1251_error("failed to register spi driver: %d", ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit wl1251_spi_exit(void)
+{
+	spi_unregister_driver(&wl1251_spi_driver);
+
+	wl1251_notice("unloaded");
+}
+
+module_init(wl1251_spi_init);
+module_exit(wl1251_spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>");
+MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index 7ddc9a346304f93db31f9313131e7b40241e153e..f20bab61fd635b75ef99daccd93f8899f052486a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -27,7 +27,6 @@
 
 #include "wl1251.h"
 #include "reg.h"
-#include "wl1251_spi.h"
 #include "wl1251_tx.h"
 #include "wl1251_ps.h"
 #include "wl1251_io.h"