aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-09-21 15:49:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-09-21 15:49:14 -0400
commitb618f6f885579a6237e5bf4582fa6167972ddef4 (patch)
treeb11508178570b98ce9cb2d76ecebd046a6f0e77c /drivers/net/wireless/wl12xx
parent462fb2af9788a82a534f8184abfde31574e1cfa0 (diff)
parent6e5c2b4e8addfaab8ef54dedaf7b607e1585c35b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: arch/arm/mach-omap2/board-omap3pandora.c drivers/net/wireless/ath/ath5k/base.c
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig5
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_sdio.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c11
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c58
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_platform_data.c28
12 files changed, 103 insertions, 36 deletions
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 2f98058be451..4a8bb25c1739 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -74,4 +74,7 @@ config WL1271_SDIO
74 If you choose to build a module, it'll be called 74 If you choose to build a module, it'll be called
75 wl1271_sdio. Say N if unsure. 75 wl1271_sdio. Say N if unsure.
76 76
77 77config WL12XX_PLATFORM_DATA
78 bool
79 depends on WL1271_SDIO != n
80 default y
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index c0b68b0a9aa8..74ba9ced5393 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -24,7 +24,7 @@
24#include <linux/mmc/sdio_func.h> 24#include <linux/mmc/sdio_func.h>
25#include <linux/mmc/sdio_ids.h> 25#include <linux/mmc/sdio_ids.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/spi/wl12xx.h> 27#include <linux/wl12xx.h>
28#include <linux/irq.h> 28#include <linux/irq.h>
29 29
30#include "wl1251.h" 30#include "wl1251.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 334ded9881c0..320de79667a6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -24,7 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/crc7.h> 25#include <linux/crc7.h>
26#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
27#include <linux/spi/wl12xx.h> 27#include <linux/wl12xx.h>
28 28
29#include "wl1251.h" 29#include "wl1251.h"
30#include "wl1251_reg.h" 30#include "wl1251_reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index dd3cee6ea5bb..4134f4495b95 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -313,7 +313,7 @@ struct wl1271_if_operations {
313 bool fixed); 313 bool fixed);
314 void (*reset)(struct wl1271 *wl); 314 void (*reset)(struct wl1271 *wl);
315 void (*init)(struct wl1271 *wl); 315 void (*init)(struct wl1271 *wl);
316 void (*power)(struct wl1271 *wl, bool enable); 316 int (*power)(struct wl1271 *wl, bool enable);
317 struct device* (*dev)(struct wl1271 *wl); 317 struct device* (*dev)(struct wl1271 *wl);
318 void (*enable_irq)(struct wl1271 *wl); 318 void (*enable_irq)(struct wl1271 *wl);
319 void (*disable_irq)(struct wl1271 *wl); 319 void (*disable_irq)(struct wl1271 *wl);
@@ -330,6 +330,7 @@ struct wl1271 {
330 330
331 void (*set_power)(bool enable); 331 void (*set_power)(bool enable);
332 int irq; 332 int irq;
333 int ref_clock;
333 334
334 spinlock_t wl_lock; 335 spinlock_t wl_lock;
335 336
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index f36430b0336d..fc21db810812 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -457,17 +457,20 @@ int wl1271_boot(struct wl1271 *wl)
457{ 457{
458 int ret = 0; 458 int ret = 0;
459 u32 tmp, clk, pause; 459 u32 tmp, clk, pause;
460 int ref_clock = wl->ref_clock;
460 461
461 wl1271_boot_hw_version(wl); 462 wl1271_boot_hw_version(wl);
462 463
463 if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4) 464 if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4)
464 /* ref clk: 19.2/38.4/38.4-XTAL */ 465 /* ref clk: 19.2/38.4/38.4-XTAL */
465 clk = 0x3; 466 clk = 0x3;
466 else if (REF_CLOCK == 1 || REF_CLOCK == 3) 467 else if (ref_clock == 1 || ref_clock == 3)
467 /* ref clk: 26/52 */ 468 /* ref clk: 26/52 */
468 clk = 0x5; 469 clk = 0x5;
470 else
471 return -EINVAL;
469 472
470 if (REF_CLOCK != 0) { 473 if (ref_clock != 0) {
471 u16 val; 474 u16 val;
472 /* Set clock type (open drain) */ 475 /* Set clock type (open drain) */
473 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); 476 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -516,7 +519,7 @@ int wl1271_boot(struct wl1271 *wl)
516 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); 519 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
517 520
518 /* 2 */ 521 /* 2 */
519 clk |= (REF_CLOCK << 1) << 4; 522 clk |= (ref_clock << 1) << 4;
520 wl1271_write32(wl, DRPW_SCRATCH_START, clk); 523 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
521 524
522 wl1271_set_partition(wl, &part_table[PART_WORK]); 525 wl1271_set_partition(wl, &part_table[PART_WORK]);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index f829699d597e..f73b0b15a280 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -46,7 +46,6 @@ struct wl1271_static_data {
46/* delay between retries */ 46/* delay between retries */
47#define INIT_LOOP_DELAY 50 47#define INIT_LOOP_DELAY 50
48 48
49#define REF_CLOCK 2
50#define WU_COUNTER_PAUSE_VAL 0x3FF 49#define WU_COUNTER_PAUSE_VAL 0x3FF
51#define WELP_ARM_COMMAND_VAL 0x4 50#define WELP_ARM_COMMAND_VAL 0x4
52 51
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index bc806c74c63a..c1f92e65ded0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -144,10 +144,13 @@ static inline void wl1271_power_off(struct wl1271 *wl)
144 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 144 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
145} 145}
146 146
147static inline void wl1271_power_on(struct wl1271 *wl) 147static inline int wl1271_power_on(struct wl1271 *wl)
148{ 148{
149 wl->if_ops->power(wl, true); 149 int ret = wl->if_ops->power(wl, true);
150 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 150 if (ret == 0)
151 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
152
153 return ret;
151} 154}
152 155
153 156
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 8e55cf8d509d..776cd7c41148 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -621,7 +621,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
621 int ret = 0; 621 int ret = 0;
622 622
623 msleep(WL1271_PRE_POWER_ON_SLEEP); 623 msleep(WL1271_PRE_POWER_ON_SLEEP);
624 wl1271_power_on(wl); 624 ret = wl1271_power_on(wl);
625 if (ret < 0)
626 goto out;
625 msleep(WL1271_POWER_ON_SLEEP); 627 msleep(WL1271_POWER_ON_SLEEP);
626 wl1271_io_reset(wl); 628 wl1271_io_reset(wl);
627 wl1271_io_init(wl); 629 wl1271_io_init(wl);
@@ -1632,7 +1634,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1632 if (ret < 0) 1634 if (ret < 0)
1633 goto out; 1635 goto out;
1634 1636
1635 if ((changed && BSS_CHANGED_BEACON_INT) && 1637 if ((changed & BSS_CHANGED_BEACON_INT) &&
1636 (wl->bss_type == BSS_TYPE_IBSS)) { 1638 (wl->bss_type == BSS_TYPE_IBSS)) {
1637 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d", 1639 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d",
1638 bss_conf->beacon_int); 1640 bss_conf->beacon_int);
@@ -1641,7 +1643,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1641 do_join = true; 1643 do_join = true;
1642 } 1644 }
1643 1645
1644 if ((changed && BSS_CHANGED_BEACON) && 1646 if ((changed & BSS_CHANGED_BEACON) &&
1645 (wl->bss_type == BSS_TYPE_IBSS)) { 1647 (wl->bss_type == BSS_TYPE_IBSS)) {
1646 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1648 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1647 1649
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 019aa79cd9df..94da5dd7723c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -76,7 +76,6 @@ static void wl1271_rx_status(struct wl1271 *wl,
76 76
77static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) 77static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
78{ 78{
79 struct ieee80211_rx_status rx_status;
80 struct wl1271_rx_descriptor *desc; 79 struct wl1271_rx_descriptor *desc;
81 struct sk_buff *skb; 80 struct sk_buff *skb;
82 u16 *fc; 81 u16 *fc;
@@ -109,14 +108,13 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
109 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) 108 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
110 beacon = 1; 109 beacon = 1;
111 110
112 wl1271_rx_status(wl, desc, &rx_status, beacon); 111 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
113 112
114 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, 113 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
115 beacon ? "beacon" : ""); 114 beacon ? "beacon" : "");
116 115
117 skb_trim(skb, skb->len - desc->pad_len); 116 skb_trim(skb, skb->len - desc->pad_len);
118 117
119 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
120 ieee80211_rx_ni(wl->hw, skb); 118 ieee80211_rx_ni(wl->hw, skb);
121} 119}
122 120
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 7059b5cccf0f..f2f04663627c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -29,14 +29,12 @@
29#include <linux/mmc/sdio_ids.h> 29#include <linux/mmc/sdio_ids.h>
30#include <linux/mmc/card.h> 30#include <linux/mmc/card.h>
31#include <linux/gpio.h> 31#include <linux/gpio.h>
32#include <linux/wl12xx.h>
32 33
33#include "wl1271.h" 34#include "wl1271.h"
34#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
35#include "wl1271_io.h" 36#include "wl1271_io.h"
36 37
37
38#define RX71_WL1271_IRQ_GPIO 42
39
40#ifndef SDIO_VENDOR_ID_TI 38#ifndef SDIO_VENDOR_ID_TI
41#define SDIO_VENDOR_ID_TI 0x0097 39#define SDIO_VENDOR_ID_TI 0x0097
42#endif 40#endif
@@ -107,6 +105,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
107 int ret; 105 int ret;
108 struct sdio_func *func = wl_to_func(wl); 106 struct sdio_func *func = wl_to_func(wl);
109 107
108 sdio_claim_host(func);
109
110 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 110 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
111 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 111 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
112 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", 112 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
@@ -122,9 +122,10 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); 122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
123 } 123 }
124 124
125 sdio_release_host(func);
126
125 if (ret) 127 if (ret)
126 wl1271_error("sdio read failed (%d)", ret); 128 wl1271_error("sdio read failed (%d)", ret);
127
128} 129}
129 130
130static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, 131static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
@@ -133,6 +134,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
133 int ret; 134 int ret;
134 struct sdio_func *func = wl_to_func(wl); 135 struct sdio_func *func = wl_to_func(wl);
135 136
137 sdio_claim_host(func);
138
136 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 139 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
137 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 140 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
138 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", 141 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
@@ -147,26 +150,45 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
147 else 150 else
148 ret = sdio_memcpy_toio(func, addr, buf, len); 151 ret = sdio_memcpy_toio(func, addr, buf, len);
149 } 152 }
153
154 sdio_release_host(func);
155
150 if (ret) 156 if (ret)
151 wl1271_error("sdio write failed (%d)", ret); 157 wl1271_error("sdio write failed (%d)", ret);
158}
159
160static int wl1271_sdio_power_on(struct wl1271 *wl)
161{
162 struct sdio_func *func = wl_to_func(wl);
163
164 sdio_claim_host(func);
165 sdio_enable_func(func);
166 sdio_release_host(func);
152 167
168 return 0;
153} 169}
154 170
155static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) 171static int wl1271_sdio_power_off(struct wl1271 *wl)
156{ 172{
157 struct sdio_func *func = wl_to_func(wl); 173 struct sdio_func *func = wl_to_func(wl);
158 174
175 sdio_claim_host(func);
176 sdio_disable_func(func);
177 sdio_release_host(func);
178
179 return 0;
180}
181
182static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
183{
159 /* Let the SDIO stack handle wlan_enable control, so we 184 /* Let the SDIO stack handle wlan_enable control, so we
160 * keep host claimed while wlan is in use to keep wl1271 185 * keep host claimed while wlan is in use to keep wl1271
161 * alive. 186 * alive.
162 */ 187 */
163 if (enable) { 188 if (enable)
164 sdio_claim_host(func); 189 return wl1271_sdio_power_on(wl);
165 sdio_enable_func(func); 190 else
166 } else { 191 return wl1271_sdio_power_off(wl);
167 sdio_disable_func(func);
168 sdio_release_host(func);
169 }
170} 192}
171 193
172static struct wl1271_if_operations sdio_ops = { 194static struct wl1271_if_operations sdio_ops = {
@@ -184,6 +206,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
184 const struct sdio_device_id *id) 206 const struct sdio_device_id *id)
185{ 207{
186 struct ieee80211_hw *hw; 208 struct ieee80211_hw *hw;
209 const struct wl12xx_platform_data *wlan_data;
187 struct wl1271 *wl; 210 struct wl1271 *wl;
188 int ret; 211 int ret;
189 212
@@ -203,13 +226,16 @@ static int __devinit wl1271_probe(struct sdio_func *func,
203 /* Grab access to FN0 for ELP reg. */ 226 /* Grab access to FN0 for ELP reg. */
204 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; 227 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
205 228
206 wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO); 229 wlan_data = wl12xx_get_platform_data();
207 if (wl->irq < 0) { 230 if (IS_ERR(wlan_data)) {
208 ret = wl->irq; 231 ret = PTR_ERR(wlan_data);
209 wl1271_error("could not get irq!"); 232 wl1271_error("missing wlan platform data: %d", ret);
210 goto out_free; 233 goto out_free;
211 } 234 }
212 235
236 wl->irq = wlan_data->irq;
237 wl->ref_clock = wlan_data->board_ref_clock;
238
213 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); 239 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
214 if (ret < 0) { 240 if (ret < 0) {
215 wl1271_error("request_irq() failed: %d", ret); 241 wl1271_error("request_irq() failed: %d", ret);
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 4cb99c541e2a..ced0a9e2c7e1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -25,7 +25,7 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/wl12xx.h> 28#include <linux/wl12xx.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31#include "wl1271.h" 31#include "wl1271.h"
@@ -312,10 +312,12 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
312 return IRQ_HANDLED; 312 return IRQ_HANDLED;
313} 313}
314 314
315static void wl1271_spi_set_power(struct wl1271 *wl, bool enable) 315static int wl1271_spi_set_power(struct wl1271 *wl, bool enable)
316{ 316{
317 if (wl->set_power) 317 if (wl->set_power)
318 wl->set_power(enable); 318 wl->set_power(enable);
319
320 return 0;
319} 321}
320 322
321static struct wl1271_if_operations spi_ops = { 323static struct wl1271_if_operations spi_ops = {
@@ -370,6 +372,8 @@ static int __devinit wl1271_probe(struct spi_device *spi)
370 goto out_free; 372 goto out_free;
371 } 373 }
372 374
375 wl->ref_clock = pdata->board_ref_clock;
376
373 wl->irq = spi->irq; 377 wl->irq = spi->irq;
374 if (wl->irq < 0) { 378 if (wl->irq < 0) {
375 wl1271_error("irq missing in platform data"); 379 wl1271_error("irq missing in platform data");
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
new file mode 100644
index 000000000000..973b11060a8f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
@@ -0,0 +1,28 @@
1#include <linux/module.h>
2#include <linux/err.h>
3#include <linux/wl12xx.h>
4
5static const struct wl12xx_platform_data *platform_data;
6
7int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
8{
9 if (platform_data)
10 return -EBUSY;
11 if (!data)
12 return -EINVAL;
13
14 platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
15 if (!platform_data)
16 return -ENOMEM;
17
18 return 0;
19}
20
21const struct wl12xx_platform_data *wl12xx_get_platform_data(void)
22{
23 if (!platform_data)
24 return ERR_PTR(-ENODEV);
25
26 return platform_data;
27}
28EXPORT_SYMBOL(wl12xx_get_platform_data);