diff options
author | Albert Herranz <albert_herranz@yahoo.es> | 2009-09-10 13:34:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-09-23 11:35:43 -0400 |
commit | 3dbba8e281552da640080f08a0f127d48456669f (patch) | |
tree | 111f1db7448c7e3214e02e6d09d7e8f285727188 /drivers/net | |
parent | a78b3bb2f3ab9afcf78dbcff18fd7bf900c7c27e (diff) |
b43: Add Soft-MAC SDIO device support
This adds support for Soft-MAC SDIO devices to b43.
The driver still lacks some fixes for SDIO devices, so it's currently
marked as BROKEN.
Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/b43/Kconfig | 21 | ||||
-rw-r--r-- | drivers/net/wireless/b43/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 76 | ||||
-rw-r--r-- | drivers/net/wireless/b43/sdio.c | 197 | ||||
-rw-r--r-- | drivers/net/wireless/b43/sdio.h | 45 |
5 files changed, 324 insertions, 16 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 83e38134accb..4fc2ce429c72 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -61,11 +61,28 @@ config B43_PCMCIA | |||
61 | 61 | ||
62 | If unsure, say N. | 62 | If unsure, say N. |
63 | 63 | ||
64 | config B43_SDIO | ||
65 | bool "Broadcom 43xx SDIO device support (EXPERIMENTAL)" | ||
66 | depends on B43 && SSB_SDIOHOST_POSSIBLE && EXPERIMENTAL && BROKEN | ||
67 | select SSB_SDIOHOST | ||
68 | ---help--- | ||
69 | Broadcom 43xx device support for Soft-MAC SDIO devices. | ||
70 | |||
71 | With this config option you can drive Soft-MAC b43 cards with a | ||
72 | Secure Digital I/O interface. | ||
73 | This includes the WLAN daughter card found on the Nintendo Wii | ||
74 | video game console. | ||
75 | Note that this does not support Broadcom 43xx Full-MAC devices. | ||
76 | |||
77 | It's safe to select Y here, even if you don't have a B43 SDIO device. | ||
78 | |||
79 | If unsure, say N. | ||
80 | |||
64 | # Data transfers to the device via PIO | 81 | # Data transfers to the device via PIO |
65 | # This is only needed on PCMCIA devices. All others can do DMA properly. | 82 | # This is only needed on PCMCIA and SDIO devices. All others can do DMA properly. |
66 | config B43_PIO | 83 | config B43_PIO |
67 | bool | 84 | bool |
68 | depends on B43 && (B43_PCMCIA || B43_FORCE_PIO) | 85 | depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO) |
69 | select SSB_BLOCKIO | 86 | select SSB_BLOCKIO |
70 | default y | 87 | default y |
71 | 88 | ||
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index da379f4b0c3a..84772a2542dc 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -16,6 +16,7 @@ b43-$(CONFIG_B43_PIO) += pio.o | |||
16 | b43-y += rfkill.o | 16 | b43-y += rfkill.o |
17 | b43-$(CONFIG_B43_LEDS) += leds.o | 17 | b43-$(CONFIG_B43_LEDS) += leds.o |
18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o | 18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o |
19 | b43-$(CONFIG_B43_SDIO) += sdio.o | ||
19 | b43-$(CONFIG_B43_DEBUG) += debugfs.o | 20 | b43-$(CONFIG_B43_DEBUG) += debugfs.o |
20 | 21 | ||
21 | obj-$(CONFIG_B43) += b43.o | 22 | obj-$(CONFIG_B43) += b43.o |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 2984a915f8b1..950a838757c4 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -8,6 +8,9 @@ | |||
8 | Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> | 8 | Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> |
9 | Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> | 9 | Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> |
10 | 10 | ||
11 | SDIO support | ||
12 | Copyright (c) 2009 Albert Herranz <albert_herranz@yahoo.es> | ||
13 | |||
11 | Some parts of the code in this file are derived from the ipw2200 | 14 | Some parts of the code in this file are derived from the ipw2200 |
12 | driver Copyright(c) 2003 - 2004 Intel Corporation. | 15 | driver Copyright(c) 2003 - 2004 Intel Corporation. |
13 | 16 | ||
@@ -53,6 +56,8 @@ | |||
53 | #include "xmit.h" | 56 | #include "xmit.h" |
54 | #include "lo.h" | 57 | #include "lo.h" |
55 | #include "pcmcia.h" | 58 | #include "pcmcia.h" |
59 | #include "sdio.h" | ||
60 | #include <linux/mmc/sdio_func.h> | ||
56 | 61 | ||
57 | MODULE_DESCRIPTION("Broadcom B43 wireless driver"); | 62 | MODULE_DESCRIPTION("Broadcom B43 wireless driver"); |
58 | MODULE_AUTHOR("Martin Langer"); | 63 | MODULE_AUTHOR("Martin Langer"); |
@@ -1587,7 +1592,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) | |||
1587 | mutex_lock(&wl->mutex); | 1592 | mutex_lock(&wl->mutex); |
1588 | dev = wl->current_dev; | 1593 | dev = wl->current_dev; |
1589 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { | 1594 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { |
1590 | if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) { | 1595 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { |
1591 | /* wl->mutex is enough. */ | 1596 | /* wl->mutex is enough. */ |
1592 | b43_do_beacon_update_trigger_work(dev); | 1597 | b43_do_beacon_update_trigger_work(dev); |
1593 | mmiowb(); | 1598 | mmiowb(); |
@@ -1905,6 +1910,27 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id) | |||
1905 | return ret; | 1910 | return ret; |
1906 | } | 1911 | } |
1907 | 1912 | ||
1913 | /* SDIO interrupt handler. This runs in process context. */ | ||
1914 | static void b43_sdio_interrupt_handler(struct b43_wldev *dev) | ||
1915 | { | ||
1916 | struct b43_wl *wl = dev->wl; | ||
1917 | struct sdio_func *func = dev->dev->bus->host_sdio; | ||
1918 | irqreturn_t ret; | ||
1919 | |||
1920 | if (unlikely(b43_status(dev) < B43_STAT_STARTED)) | ||
1921 | return; | ||
1922 | |||
1923 | mutex_lock(&wl->mutex); | ||
1924 | sdio_release_host(func); | ||
1925 | |||
1926 | ret = b43_do_interrupt(dev); | ||
1927 | if (ret == IRQ_WAKE_THREAD) | ||
1928 | b43_do_interrupt_thread(dev); | ||
1929 | |||
1930 | sdio_claim_host(func); | ||
1931 | mutex_unlock(&wl->mutex); | ||
1932 | } | ||
1933 | |||
1908 | void b43_do_release_fw(struct b43_firmware_file *fw) | 1934 | void b43_do_release_fw(struct b43_firmware_file *fw) |
1909 | { | 1935 | { |
1910 | release_firmware(fw->data); | 1936 | release_firmware(fw->data); |
@@ -3824,7 +3850,7 @@ redo: | |||
3824 | 3850 | ||
3825 | /* Disable interrupts on the device. */ | 3851 | /* Disable interrupts on the device. */ |
3826 | b43_set_status(dev, B43_STAT_INITIALIZED); | 3852 | b43_set_status(dev, B43_STAT_INITIALIZED); |
3827 | if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) { | 3853 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { |
3828 | /* wl->mutex is locked. That is enough. */ | 3854 | /* wl->mutex is locked. That is enough. */ |
3829 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); | 3855 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); |
3830 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ | 3856 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ |
@@ -3854,7 +3880,10 @@ redo: | |||
3854 | dev_kfree_skb(skb_dequeue(&wl->tx_queue)); | 3880 | dev_kfree_skb(skb_dequeue(&wl->tx_queue)); |
3855 | 3881 | ||
3856 | b43_mac_suspend(dev); | 3882 | b43_mac_suspend(dev); |
3857 | free_irq(dev->dev->irq, dev); | 3883 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) |
3884 | b43_sdio_free_irq(dev); | ||
3885 | else | ||
3886 | free_irq(dev->dev->irq, dev); | ||
3858 | b43_leds_exit(dev); | 3887 | b43_leds_exit(dev); |
3859 | b43dbg(wl, "Wireless interface stopped\n"); | 3888 | b43dbg(wl, "Wireless interface stopped\n"); |
3860 | 3889 | ||
@@ -3869,12 +3898,20 @@ static int b43_wireless_core_start(struct b43_wldev *dev) | |||
3869 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); | 3898 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); |
3870 | 3899 | ||
3871 | drain_txstatus_queue(dev); | 3900 | drain_txstatus_queue(dev); |
3872 | err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, | 3901 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { |
3873 | b43_interrupt_thread_handler, | 3902 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); |
3874 | IRQF_SHARED, KBUILD_MODNAME, dev); | 3903 | if (err) { |
3875 | if (err) { | 3904 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); |
3876 | b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); | 3905 | goto out; |
3877 | goto out; | 3906 | } |
3907 | } else { | ||
3908 | err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, | ||
3909 | b43_interrupt_thread_handler, | ||
3910 | IRQF_SHARED, KBUILD_MODNAME, dev); | ||
3911 | if (err) { | ||
3912 | b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); | ||
3913 | goto out; | ||
3914 | } | ||
3878 | } | 3915 | } |
3879 | 3916 | ||
3880 | /* We are ready to run. */ | 3917 | /* We are ready to run. */ |
@@ -4266,7 +4303,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4266 | /* Maximum Contention Window */ | 4303 | /* Maximum Contention Window */ |
4267 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); | 4304 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); |
4268 | 4305 | ||
4269 | if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) { | 4306 | if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || |
4307 | (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || | ||
4308 | B43_FORCE_PIO) { | ||
4270 | dev->__using_pio_transfers = 1; | 4309 | dev->__using_pio_transfers = 1; |
4271 | err = b43_pio_init(dev); | 4310 | err = b43_pio_init(dev); |
4272 | } else { | 4311 | } else { |
@@ -4942,7 +4981,7 @@ static struct ssb_driver b43_ssb_driver = { | |||
4942 | static void b43_print_driverinfo(void) | 4981 | static void b43_print_driverinfo(void) |
4943 | { | 4982 | { |
4944 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", | 4983 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", |
4945 | *feat_leds = ""; | 4984 | *feat_leds = "", *feat_sdio = ""; |
4946 | 4985 | ||
4947 | #ifdef CONFIG_B43_PCI_AUTOSELECT | 4986 | #ifdef CONFIG_B43_PCI_AUTOSELECT |
4948 | feat_pci = "P"; | 4987 | feat_pci = "P"; |
@@ -4956,11 +4995,14 @@ static void b43_print_driverinfo(void) | |||
4956 | #ifdef CONFIG_B43_LEDS | 4995 | #ifdef CONFIG_B43_LEDS |
4957 | feat_leds = "L"; | 4996 | feat_leds = "L"; |
4958 | #endif | 4997 | #endif |
4998 | #ifdef CONFIG_B43_SDIO | ||
4999 | feat_sdio = "S"; | ||
5000 | #endif | ||
4959 | printk(KERN_INFO "Broadcom 43xx driver loaded " | 5001 | printk(KERN_INFO "Broadcom 43xx driver loaded " |
4960 | "[ Features: %s%s%s%s, Firmware-ID: " | 5002 | "[ Features: %s%s%s%s%s, Firmware-ID: " |
4961 | B43_SUPPORTED_FIRMWARE_ID " ]\n", | 5003 | B43_SUPPORTED_FIRMWARE_ID " ]\n", |
4962 | feat_pci, feat_pcmcia, feat_nphy, | 5004 | feat_pci, feat_pcmcia, feat_nphy, |
4963 | feat_leds); | 5005 | feat_leds, feat_sdio); |
4964 | } | 5006 | } |
4965 | 5007 | ||
4966 | static int __init b43_init(void) | 5008 | static int __init b43_init(void) |
@@ -4971,13 +5013,18 @@ static int __init b43_init(void) | |||
4971 | err = b43_pcmcia_init(); | 5013 | err = b43_pcmcia_init(); |
4972 | if (err) | 5014 | if (err) |
4973 | goto err_dfs_exit; | 5015 | goto err_dfs_exit; |
4974 | err = ssb_driver_register(&b43_ssb_driver); | 5016 | err = b43_sdio_init(); |
4975 | if (err) | 5017 | if (err) |
4976 | goto err_pcmcia_exit; | 5018 | goto err_pcmcia_exit; |
5019 | err = ssb_driver_register(&b43_ssb_driver); | ||
5020 | if (err) | ||
5021 | goto err_sdio_exit; | ||
4977 | b43_print_driverinfo(); | 5022 | b43_print_driverinfo(); |
4978 | 5023 | ||
4979 | return err; | 5024 | return err; |
4980 | 5025 | ||
5026 | err_sdio_exit: | ||
5027 | b43_sdio_exit(); | ||
4981 | err_pcmcia_exit: | 5028 | err_pcmcia_exit: |
4982 | b43_pcmcia_exit(); | 5029 | b43_pcmcia_exit(); |
4983 | err_dfs_exit: | 5030 | err_dfs_exit: |
@@ -4988,6 +5035,7 @@ err_dfs_exit: | |||
4988 | static void __exit b43_exit(void) | 5035 | static void __exit b43_exit(void) |
4989 | { | 5036 | { |
4990 | ssb_driver_unregister(&b43_ssb_driver); | 5037 | ssb_driver_unregister(&b43_ssb_driver); |
5038 | b43_sdio_exit(); | ||
4991 | b43_pcmcia_exit(); | 5039 | b43_pcmcia_exit(); |
4992 | b43_debugfs_exit(); | 5040 | b43_debugfs_exit(); |
4993 | } | 5041 | } |
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c new file mode 100644 index 000000000000..2d337f1a60b2 --- /dev/null +++ b/drivers/net/wireless/b43/sdio.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Broadcom B43 wireless driver | ||
3 | * | ||
4 | * SDIO over Sonics Silicon Backplane bus glue for b43. | ||
5 | * | ||
6 | * Copyright (C) 2009 Albert Herranz | ||
7 | * Copyright (C) 2009 Michael Buesch <mb@bu3sch.de> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/mmc/card.h> | ||
17 | #include <linux/mmc/sdio_func.h> | ||
18 | #include <linux/mmc/sdio_ids.h> | ||
19 | #include <linux/ssb/ssb.h> | ||
20 | |||
21 | #include "sdio.h" | ||
22 | #include "b43.h" | ||
23 | |||
24 | |||
25 | #define HNBU_CHIPID 0x01 /* vendor & device id */ | ||
26 | |||
27 | #define B43_SDIO_BLOCK_SIZE 64 /* rx fifo max size in bytes */ | ||
28 | |||
29 | |||
30 | static const struct b43_sdio_quirk { | ||
31 | u16 vendor; | ||
32 | u16 device; | ||
33 | unsigned int quirks; | ||
34 | } b43_sdio_quirks[] = { | ||
35 | { 0x14E4, 0x4318, SSB_QUIRK_SDIO_READ_AFTER_WRITE32, }, | ||
36 | { }, | ||
37 | }; | ||
38 | |||
39 | |||
40 | static unsigned int b43_sdio_get_quirks(u16 vendor, u16 device) | ||
41 | { | ||
42 | const struct b43_sdio_quirk *q; | ||
43 | |||
44 | for (q = b43_sdio_quirks; q->quirks; q++) { | ||
45 | if (vendor == q->vendor && device == q->device) | ||
46 | return q->quirks; | ||
47 | } | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) | ||
53 | { | ||
54 | struct b43_sdio *sdio = sdio_get_drvdata(func); | ||
55 | struct b43_wldev *dev = sdio->irq_handler_opaque; | ||
56 | |||
57 | sdio->irq_handler(dev); | ||
58 | } | ||
59 | |||
60 | int b43_sdio_request_irq(struct b43_wldev *dev, | ||
61 | void (*handler)(struct b43_wldev *dev)) | ||
62 | { | ||
63 | struct ssb_bus *bus = dev->dev->bus; | ||
64 | struct sdio_func *func = bus->host_sdio; | ||
65 | struct b43_sdio *sdio = sdio_get_drvdata(func); | ||
66 | int err; | ||
67 | |||
68 | sdio->irq_handler_opaque = dev; | ||
69 | sdio->irq_handler = handler; | ||
70 | sdio_claim_host(func); | ||
71 | err = sdio_claim_irq(func, b43_sdio_interrupt_dispatcher); | ||
72 | sdio_release_host(func); | ||
73 | |||
74 | return err; | ||
75 | } | ||
76 | |||
77 | void b43_sdio_free_irq(struct b43_wldev *dev) | ||
78 | { | ||
79 | struct ssb_bus *bus = dev->dev->bus; | ||
80 | struct sdio_func *func = bus->host_sdio; | ||
81 | struct b43_sdio *sdio = sdio_get_drvdata(func); | ||
82 | |||
83 | sdio_claim_host(func); | ||
84 | sdio_release_irq(func); | ||
85 | sdio_release_host(func); | ||
86 | sdio->irq_handler_opaque = NULL; | ||
87 | sdio->irq_handler = NULL; | ||
88 | } | ||
89 | |||
90 | static int b43_sdio_probe(struct sdio_func *func, | ||
91 | const struct sdio_device_id *id) | ||
92 | { | ||
93 | struct b43_sdio *sdio; | ||
94 | struct sdio_func_tuple *tuple; | ||
95 | u16 vendor = 0, device = 0; | ||
96 | int error; | ||
97 | |||
98 | /* Look for the card chip identifier. */ | ||
99 | tuple = func->tuples; | ||
100 | while (tuple) { | ||
101 | switch (tuple->code) { | ||
102 | case 0x80: | ||
103 | switch (tuple->data[0]) { | ||
104 | case HNBU_CHIPID: | ||
105 | if (tuple->size != 5) | ||
106 | break; | ||
107 | vendor = tuple->data[1] | (tuple->data[2]<<8); | ||
108 | device = tuple->data[3] | (tuple->data[4]<<8); | ||
109 | dev_info(&func->dev, "Chip ID %04x:%04x\n", | ||
110 | vendor, device); | ||
111 | break; | ||
112 | default: | ||
113 | break; | ||
114 | } | ||
115 | break; | ||
116 | default: | ||
117 | break; | ||
118 | } | ||
119 | tuple = tuple->next; | ||
120 | } | ||
121 | if (!vendor || !device) { | ||
122 | error = -ENODEV; | ||
123 | goto out; | ||
124 | } | ||
125 | |||
126 | sdio_claim_host(func); | ||
127 | error = sdio_set_block_size(func, B43_SDIO_BLOCK_SIZE); | ||
128 | if (error) { | ||
129 | dev_err(&func->dev, "failed to set block size to %u bytes," | ||
130 | " error %d\n", B43_SDIO_BLOCK_SIZE, error); | ||
131 | goto err_release_host; | ||
132 | } | ||
133 | error = sdio_enable_func(func); | ||
134 | if (error) { | ||
135 | dev_err(&func->dev, "failed to enable func, error %d\n", error); | ||
136 | goto err_release_host; | ||
137 | } | ||
138 | sdio_release_host(func); | ||
139 | |||
140 | sdio = kzalloc(sizeof(*sdio), GFP_KERNEL); | ||
141 | if (!sdio) { | ||
142 | error = -ENOMEM; | ||
143 | dev_err(&func->dev, "failed to allocate ssb bus\n"); | ||
144 | goto err_disable_func; | ||
145 | } | ||
146 | error = ssb_bus_sdiobus_register(&sdio->ssb, func, | ||
147 | b43_sdio_get_quirks(vendor, device)); | ||
148 | if (error) { | ||
149 | dev_err(&func->dev, "failed to register ssb sdio bus," | ||
150 | " error %d\n", error); | ||
151 | goto err_free_ssb; | ||
152 | } | ||
153 | sdio_set_drvdata(func, sdio); | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | err_free_ssb: | ||
158 | kfree(sdio); | ||
159 | err_disable_func: | ||
160 | sdio_disable_func(func); | ||
161 | err_release_host: | ||
162 | sdio_release_host(func); | ||
163 | out: | ||
164 | return error; | ||
165 | } | ||
166 | |||
167 | static void b43_sdio_remove(struct sdio_func *func) | ||
168 | { | ||
169 | struct b43_sdio *sdio = sdio_get_drvdata(func); | ||
170 | |||
171 | ssb_bus_unregister(&sdio->ssb); | ||
172 | sdio_disable_func(func); | ||
173 | kfree(sdio); | ||
174 | sdio_set_drvdata(func, NULL); | ||
175 | } | ||
176 | |||
177 | static const struct sdio_device_id b43_sdio_ids[] = { | ||
178 | { SDIO_DEVICE(0x02d0, 0x044b) }, /* Nintendo Wii WLAN daughter card */ | ||
179 | { }, | ||
180 | }; | ||
181 | |||
182 | static struct sdio_driver b43_sdio_driver = { | ||
183 | .name = "b43-sdio", | ||
184 | .id_table = b43_sdio_ids, | ||
185 | .probe = b43_sdio_probe, | ||
186 | .remove = b43_sdio_remove, | ||
187 | }; | ||
188 | |||
189 | int b43_sdio_init(void) | ||
190 | { | ||
191 | return sdio_register_driver(&b43_sdio_driver); | ||
192 | } | ||
193 | |||
194 | void b43_sdio_exit(void) | ||
195 | { | ||
196 | sdio_unregister_driver(&b43_sdio_driver); | ||
197 | } | ||
diff --git a/drivers/net/wireless/b43/sdio.h b/drivers/net/wireless/b43/sdio.h new file mode 100644 index 000000000000..fb633094403a --- /dev/null +++ b/drivers/net/wireless/b43/sdio.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef B43_SDIO_H_ | ||
2 | #define B43_SDIO_H_ | ||
3 | |||
4 | #include <linux/ssb/ssb.h> | ||
5 | |||
6 | struct b43_wldev; | ||
7 | |||
8 | |||
9 | #ifdef CONFIG_B43_SDIO | ||
10 | |||
11 | struct b43_sdio { | ||
12 | struct ssb_bus ssb; | ||
13 | void *irq_handler_opaque; | ||
14 | void (*irq_handler)(struct b43_wldev *dev); | ||
15 | }; | ||
16 | |||
17 | int b43_sdio_request_irq(struct b43_wldev *dev, | ||
18 | void (*handler)(struct b43_wldev *dev)); | ||
19 | void b43_sdio_free_irq(struct b43_wldev *dev); | ||
20 | |||
21 | int b43_sdio_init(void); | ||
22 | void b43_sdio_exit(void); | ||
23 | |||
24 | |||
25 | #else /* CONFIG_B43_SDIO */ | ||
26 | |||
27 | |||
28 | int b43_sdio_request_irq(struct b43_wldev *dev, | ||
29 | void (*handler)(struct b43_wldev *dev)) | ||
30 | { | ||
31 | return -ENODEV; | ||
32 | } | ||
33 | void b43_sdio_free_irq(struct b43_wldev *dev) | ||
34 | { | ||
35 | } | ||
36 | static inline int b43_sdio_init(void) | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | static inline void b43_sdio_exit(void) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | #endif /* CONFIG_B43_SDIO */ | ||
45 | #endif /* B43_SDIO_H_ */ | ||