diff options
Diffstat (limited to 'package/kernel/mac80211/patches/315-ssb-pick-PCMCIA-host-code-support-from-b43-driver.patch')
-rw-r--r-- | package/kernel/mac80211/patches/315-ssb-pick-PCMCIA-host-code-support-from-b43-driver.patch | 485 |
1 files changed, 485 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/315-ssb-pick-PCMCIA-host-code-support-from-b43-driver.patch b/package/kernel/mac80211/patches/315-ssb-pick-PCMCIA-host-code-support-from-b43-driver.patch new file mode 100644 index 0000000000..64601ddf45 --- /dev/null +++ b/package/kernel/mac80211/patches/315-ssb-pick-PCMCIA-host-code-support-from-b43-driver.patch @@ -0,0 +1,485 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> +Date: Thu, 15 Oct 2015 07:23:25 +0200 +Subject: [PATCH] ssb: pick PCMCIA host code support from b43 driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ssb bus can be found on various "host" devices like PCI/PCMCIA/SDIO. +Every ssb bus contains cores AKA devices. +The main idea is to have ssb driver scan/initialize bus and register +ready-to-use cores. This way ssb drivers can operate on a single core +mostly ignoring underlaying details. + +For some reason PCMCIA support was split between ssb and b43. We got +PCMCIA host device probing in b43, then bus scanning in ssb and then +wireless core probing back in b43. The truth is it's very unlikely we +will ever see PCMCIA ssb device with no 802.11 core but I still don't +see any advantage of the current architecture. + +With proposed change we get the same functionality with a simpler +architecture, less Kconfig symbols, one killed EXPORT and hopefully +cleaner b43. Since b43 supports both: ssb & bcma I prefer to keep ssb +specific code in ssb driver. + +This mostly moves code from b43's pcmcia.c to bridge_pcmcia_80211.c. We +already use similar solution with b43_pci_bridge.c. I didn't use "b43" +in name of this new file as in theory any driver can operate on wireless +core. + +Signed-off-by: Rafał Miłecki <zajec5@gmail.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +--- + delete mode 100644 drivers/net/wireless/b43/pcmcia.c + delete mode 100644 drivers/net/wireless/b43/pcmcia.h + create mode 100644 drivers/ssb/bridge_pcmcia_80211.c + +--- a/drivers/net/wireless/b43/Kconfig ++++ b/drivers/net/wireless/b43/Kconfig +@@ -72,26 +72,6 @@ config B43_PCICORE_AUTOSELECT + select SSB_DRIVER_PCICORE + default y + +-config B43_PCMCIA +- bool "Broadcom 43xx PCMCIA device support" +- depends on B43 && B43_SSB && SSB_PCMCIAHOST_POSSIBLE +- select SSB_PCMCIAHOST +- ---help--- +- Broadcom 43xx PCMCIA device support. +- +- Support for 16bit PCMCIA devices. +- Please note that most PC-CARD devices are _NOT_ 16bit PCMCIA +- devices, but 32bit CardBUS devices. CardBUS devices are supported +- out of the box by b43. +- +- With this config option you can drive b43 cards in +- CompactFlash formfactor in a PCMCIA adaptor. +- CF b43 cards can sometimes be found in handheld PCs. +- +- It's safe to select Y here, even if you don't have a B43 PCMCIA device. +- +- If unsure, say N. +- + config B43_SDIO + bool "Broadcom 43xx SDIO device support" + depends on B43 && B43_SSB && SSB_SDIOHOST_POSSIBLE +--- a/drivers/net/wireless/b43/Makefile ++++ b/drivers/net/wireless/b43/Makefile +@@ -21,7 +21,6 @@ b43-y += pio.o + b43-y += rfkill.o + b43-y += ppr.o + b43-$(CPTCFG_B43_LEDS) += leds.o +-b43-$(CPTCFG_B43_PCMCIA) += pcmcia.o + b43-$(CPTCFG_B43_SDIO) += sdio.o + b43-$(CPTCFG_B43_DEBUG) += debugfs.o + +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -56,7 +56,6 @@ + #include "sysfs.h" + #include "xmit.h" + #include "lo.h" +-#include "pcmcia.h" + #include "sdio.h" + #include <linux/mmc/sdio_func.h> + +@@ -5850,12 +5849,9 @@ static int __init b43_init(void) + int err; + + b43_debugfs_init(); +- err = b43_pcmcia_init(); +- if (err) +- goto err_dfs_exit; + err = b43_sdio_init(); + if (err) +- goto err_pcmcia_exit; ++ goto err_dfs_exit; + #ifdef CPTCFG_B43_BCMA + err = bcma_driver_register(&b43_bcma_driver); + if (err) +@@ -5878,8 +5874,6 @@ err_bcma_driver_exit: + err_sdio_exit: + #endif + b43_sdio_exit(); +-err_pcmcia_exit: +- b43_pcmcia_exit(); + err_dfs_exit: + b43_debugfs_exit(); + return err; +@@ -5894,7 +5888,6 @@ static void __exit b43_exit(void) + bcma_driver_unregister(&b43_bcma_driver); + #endif + b43_sdio_exit(); +- b43_pcmcia_exit(); + b43_debugfs_exit(); + } + +--- a/drivers/net/wireless/b43/pcmcia.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-#ifndef B43_PCMCIA_H_ +-#define B43_PCMCIA_H_ +- +-#ifdef CPTCFG_B43_PCMCIA +- +-int b43_pcmcia_init(void); +-void b43_pcmcia_exit(void); +- +-#else /* CPTCFG_B43_PCMCIA */ +- +-static inline int b43_pcmcia_init(void) +-{ +- return 0; +-} +-static inline void b43_pcmcia_exit(void) +-{ +-} +- +-#endif /* CPTCFG_B43_PCMCIA */ +-#endif /* B43_PCMCIA_H_ */ +--- a/drivers/ssb/Makefile ++++ b/drivers/ssb/Makefile +@@ -5,7 +5,7 @@ ssb-$(CPTCFG_SSB_SPROM) += sprom.o + + # host support + ssb-$(CPTCFG_SSB_PCIHOST) += pci.o pcihost_wrapper.o +-ssb-$(CPTCFG_SSB_PCMCIAHOST) += pcmcia.o ++ssb-$(CPTCFG_SSB_PCMCIAHOST) += pcmcia.o bridge_pcmcia_80211.o + ssb-$(CPTCFG_SSB_SDIOHOST) += sdio.o + + # built-in drivers +--- /dev/null ++++ b/drivers/ssb/bridge_pcmcia_80211.c +@@ -0,0 +1,128 @@ ++/* ++ * Broadcom 43xx PCMCIA-SSB bridge module ++ * ++ * Copyright (c) 2007 Michael Buesch <m@bues.ch> ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++ ++#include <linux/ssb/ssb.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++ ++#include <pcmcia/cistpl.h> ++#include <pcmcia/ciscode.h> ++#include <pcmcia/ds.h> ++#include <pcmcia/cisreg.h> ++ ++#include "ssb_private.h" ++ ++static const struct pcmcia_device_id ssb_host_pcmcia_tbl[] = { ++ PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), ++ PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476), ++ PCMCIA_DEVICE_NULL, ++}; ++ ++MODULE_DEVICE_TABLE(pcmcia, ssb_host_pcmcia_tbl); ++ ++static int ssb_host_pcmcia_probe(struct pcmcia_device *dev) ++{ ++ struct ssb_bus *ssb; ++ int err = -ENOMEM; ++ int res = 0; ++ ++ ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); ++ if (!ssb) ++ goto out_error; ++ ++ err = -ENODEV; ++ ++ dev->config_flags |= CONF_ENABLE_IRQ; ++ ++ dev->resource[2]->flags |= WIN_ENABLE | WIN_DATA_WIDTH_16 | ++ WIN_USE_WAIT; ++ dev->resource[2]->start = 0; ++ dev->resource[2]->end = SSB_CORE_SIZE; ++ res = pcmcia_request_window(dev, dev->resource[2], 250); ++ if (res != 0) ++ goto err_kfree_ssb; ++ ++ res = pcmcia_map_mem_page(dev, dev->resource[2], 0); ++ if (res != 0) ++ goto err_disable; ++ ++ if (!dev->irq) ++ goto err_disable; ++ ++ res = pcmcia_enable_device(dev); ++ if (res != 0) ++ goto err_disable; ++ ++ err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start); ++ if (err) ++ goto err_disable; ++ dev->priv = ssb; ++ ++ return 0; ++ ++err_disable: ++ pcmcia_disable_device(dev); ++err_kfree_ssb: ++ kfree(ssb); ++out_error: ++ ssb_err("Initialization failed (%d, %d)\n", res, err); ++ return err; ++} ++ ++static void ssb_host_pcmcia_remove(struct pcmcia_device *dev) ++{ ++ struct ssb_bus *ssb = dev->priv; ++ ++ ssb_bus_unregister(ssb); ++ pcmcia_disable_device(dev); ++ kfree(ssb); ++ dev->priv = NULL; ++} ++ ++#ifdef CPTCFG_PM ++static int ssb_host_pcmcia_suspend(struct pcmcia_device *dev) ++{ ++ struct ssb_bus *ssb = dev->priv; ++ ++ return ssb_bus_suspend(ssb); ++} ++ ++static int ssb_host_pcmcia_resume(struct pcmcia_device *dev) ++{ ++ struct ssb_bus *ssb = dev->priv; ++ ++ return ssb_bus_resume(ssb); ++} ++#else /* CPTCFG_PM */ ++# define ssb_host_pcmcia_suspend NULL ++# define ssb_host_pcmcia_resume NULL ++#endif /* CPTCFG_PM */ ++ ++static struct pcmcia_driver ssb_host_pcmcia_driver = { ++ .owner = THIS_MODULE, ++ .name = "ssb-pcmcia", ++ .id_table = ssb_host_pcmcia_tbl, ++ .probe = ssb_host_pcmcia_probe, ++ .remove = ssb_host_pcmcia_remove, ++ .suspend = ssb_host_pcmcia_suspend, ++ .resume = ssb_host_pcmcia_resume, ++}; ++ ++/* ++ * These are not module init/exit functions! ++ * The module_pcmcia_driver() helper cannot be used here. ++ */ ++int ssb_host_pcmcia_init(void) ++{ ++ return pcmcia_register_driver(&ssb_host_pcmcia_driver); ++} ++ ++void ssb_host_pcmcia_exit(void) ++{ ++ pcmcia_unregister_driver(&ssb_host_pcmcia_driver); ++} +--- a/drivers/ssb/main.c ++++ b/drivers/ssb/main.c +@@ -906,7 +906,6 @@ int ssb_bus_pcmciabus_register(struct ss + + return err; + } +-EXPORT_SYMBOL(ssb_bus_pcmciabus_register); + #endif /* CPTCFG_SSB_PCMCIAHOST */ + + #ifdef CPTCFG_SSB_SDIOHOST +@@ -1474,6 +1473,12 @@ static int __init ssb_modinit(void) + /* don't fail SSB init because of this */ + err = 0; + } ++ err = ssb_host_pcmcia_init(); ++ if (err) { ++ ssb_err("PCMCIA host initialization failed\n"); ++ /* don't fail SSB init because of this */ ++ err = 0; ++ } + err = ssb_gige_init(); + if (err) { + ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n"); +@@ -1491,6 +1496,7 @@ fs_initcall(ssb_modinit); + static void __exit ssb_modexit(void) + { + ssb_gige_exit(); ++ ssb_host_pcmcia_exit(); + b43_pci_ssb_bridge_exit(); + bus_unregister(&ssb_bustype); + } +--- a/drivers/ssb/ssb_private.h ++++ b/drivers/ssb/ssb_private.h +@@ -94,6 +94,8 @@ extern int ssb_pcmcia_get_invariants(str + extern int ssb_pcmcia_hardware_setup(struct ssb_bus *bus); + extern void ssb_pcmcia_exit(struct ssb_bus *bus); + extern int ssb_pcmcia_init(struct ssb_bus *bus); ++extern int ssb_host_pcmcia_init(void); ++extern void ssb_host_pcmcia_exit(void); + extern const struct ssb_bus_ops ssb_pcmcia_ops; + #else /* CPTCFG_SSB_PCMCIAHOST */ + static inline int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, +@@ -117,6 +119,13 @@ static inline int ssb_pcmcia_init(struct + { + return 0; + } ++static inline int ssb_host_pcmcia_init(void) ++{ ++ return 0; ++} ++static inline void ssb_host_pcmcia_exit(void) ++{ ++} + #endif /* CPTCFG_SSB_PCMCIAHOST */ + + /* sdio.c */ +--- a/drivers/net/wireless/b43/pcmcia.c ++++ /dev/null +@@ -1,145 +0,0 @@ +-/* +- +- Broadcom B43 wireless driver +- +- Copyright (c) 2007 Michael Buesch <m@bues.ch> +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to +- the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, +- Boston, MA 02110-1301, USA. +- +-*/ +- +-#include "pcmcia.h" +- +-#include <linux/ssb/ssb.h> +-#include <linux/slab.h> +-#include <linux/module.h> +- +-#include <pcmcia/cistpl.h> +-#include <pcmcia/ciscode.h> +-#include <pcmcia/ds.h> +-#include <pcmcia/cisreg.h> +- +- +-static const struct pcmcia_device_id b43_pcmcia_tbl[] = { +- PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), +- PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476), +- PCMCIA_DEVICE_NULL, +-}; +- +-MODULE_DEVICE_TABLE(pcmcia, b43_pcmcia_tbl); +- +-#ifdef CONFIG_PM +-static int b43_pcmcia_suspend(struct pcmcia_device *dev) +-{ +- struct ssb_bus *ssb = dev->priv; +- +- return ssb_bus_suspend(ssb); +-} +- +-static int b43_pcmcia_resume(struct pcmcia_device *dev) +-{ +- struct ssb_bus *ssb = dev->priv; +- +- return ssb_bus_resume(ssb); +-} +-#else /* CONFIG_PM */ +-# define b43_pcmcia_suspend NULL +-# define b43_pcmcia_resume NULL +-#endif /* CONFIG_PM */ +- +-static int b43_pcmcia_probe(struct pcmcia_device *dev) +-{ +- struct ssb_bus *ssb; +- int err = -ENOMEM; +- int res = 0; +- +- ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); +- if (!ssb) +- goto out_error; +- +- err = -ENODEV; +- +- dev->config_flags |= CONF_ENABLE_IRQ; +- +- dev->resource[2]->flags |= WIN_ENABLE | WIN_DATA_WIDTH_16 | +- WIN_USE_WAIT; +- dev->resource[2]->start = 0; +- dev->resource[2]->end = SSB_CORE_SIZE; +- res = pcmcia_request_window(dev, dev->resource[2], 250); +- if (res != 0) +- goto err_kfree_ssb; +- +- res = pcmcia_map_mem_page(dev, dev->resource[2], 0); +- if (res != 0) +- goto err_disable; +- +- if (!dev->irq) +- goto err_disable; +- +- res = pcmcia_enable_device(dev); +- if (res != 0) +- goto err_disable; +- +- err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start); +- if (err) +- goto err_disable; +- dev->priv = ssb; +- +- return 0; +- +-err_disable: +- pcmcia_disable_device(dev); +-err_kfree_ssb: +- kfree(ssb); +-out_error: +- printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n", +- res, err); +- return err; +-} +- +-static void b43_pcmcia_remove(struct pcmcia_device *dev) +-{ +- struct ssb_bus *ssb = dev->priv; +- +- ssb_bus_unregister(ssb); +- pcmcia_disable_device(dev); +- kfree(ssb); +- dev->priv = NULL; +-} +- +-static struct pcmcia_driver b43_pcmcia_driver = { +- .owner = THIS_MODULE, +- .name = "b43-pcmcia", +- .id_table = b43_pcmcia_tbl, +- .probe = b43_pcmcia_probe, +- .remove = b43_pcmcia_remove, +- .suspend = b43_pcmcia_suspend, +- .resume = b43_pcmcia_resume, +-}; +- +-/* +- * These are not module init/exit functions! +- * The module_pcmcia_driver() helper cannot be used here. +- */ +-int b43_pcmcia_init(void) +-{ +- return pcmcia_register_driver(&b43_pcmcia_driver); +-} +- +-void b43_pcmcia_exit(void) +-{ +- pcmcia_unregister_driver(&b43_pcmcia_driver); +-} |