Blame view
drivers/ssb/bridge_pcmcia_80211.c
2.78 KB
399500da1
|
1 2 3 4 5 6 7 |
/* * Broadcom 43xx PCMCIA-SSB bridge module * * Copyright (c) 2007 Michael Buesch <m@bues.ch> * * Licensed under the GNU/GPL. See COPYING for details. */ |
b8b6069cf
|
8 |
#include "ssb_private.h" |
399500da1
|
9 10 11 12 13 14 15 16 |
#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> |
399500da1
|
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
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: |
b8b6069cf
|
70 71 |
dev_err(&dev->dev, "Initialization failed (%d, %d) ", res, err); |
399500da1
|
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
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 CONFIG_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 /* CONFIG_PM */ # define ssb_host_pcmcia_suspend NULL # define ssb_host_pcmcia_resume NULL #endif /* CONFIG_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, }; |
b2c01aab9
|
113 |
static int pcmcia_init_failed; |
399500da1
|
114 115 116 117 118 119 |
/* * These are not module init/exit functions! * The module_pcmcia_driver() helper cannot be used here. */ int ssb_host_pcmcia_init(void) { |
b2c01aab9
|
120 121 122 |
pcmcia_init_failed = pcmcia_register_driver(&ssb_host_pcmcia_driver); return pcmcia_init_failed; |
399500da1
|
123 124 125 126 |
} void ssb_host_pcmcia_exit(void) { |
b2c01aab9
|
127 128 |
if (!pcmcia_init_failed) pcmcia_unregister_driver(&ssb_host_pcmcia_driver); |
399500da1
|
129 |
} |