linux/drivers/net/wireless/b43/pcmcia.c
<<
>>
Prefs
   1/*
   2
   3  Broadcom B43 wireless driver
   4
   5  Copyright (c) 2007 Michael Buesch <mb@bu3sch.de>
   6
   7  This program is free software; you can redistribute it and/or modify
   8  it under the terms of the GNU General Public License as published by
   9  the Free Software Foundation; either version 2 of the License, or
  10  (at your option) any later version.
  11
  12  This program is distributed in the hope that it will be useful,
  13  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  GNU General Public License for more details.
  16
  17  You should have received a copy of the GNU General Public License
  18  along with this program; see the file COPYING.  If not, write to
  19  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  20  Boston, MA 02110-1301, USA.
  21
  22*/
  23
  24#include "pcmcia.h"
  25
  26#include <linux/ssb/ssb.h>
  27#include <linux/slab.h>
  28
  29#include <pcmcia/cs_types.h>
  30#include <pcmcia/cs.h>
  31#include <pcmcia/cistpl.h>
  32#include <pcmcia/ciscode.h>
  33#include <pcmcia/ds.h>
  34#include <pcmcia/cisreg.h>
  35
  36
  37static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = {
  38        PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
  39        PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
  40        PCMCIA_DEVICE_NULL,
  41};
  42
  43MODULE_DEVICE_TABLE(pcmcia, b43_pcmcia_tbl);
  44
  45#ifdef CONFIG_PM
  46static int b43_pcmcia_suspend(struct pcmcia_device *dev)
  47{
  48        struct ssb_bus *ssb = dev->priv;
  49
  50        return ssb_bus_suspend(ssb);
  51}
  52
  53static int b43_pcmcia_resume(struct pcmcia_device *dev)
  54{
  55        struct ssb_bus *ssb = dev->priv;
  56
  57        return ssb_bus_resume(ssb);
  58}
  59#else /* CONFIG_PM */
  60# define b43_pcmcia_suspend             NULL
  61# define b43_pcmcia_resume              NULL
  62#endif /* CONFIG_PM */
  63
  64static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
  65{
  66        struct ssb_bus *ssb;
  67        win_req_t win;
  68        memreq_t mem;
  69        int err = -ENOMEM;
  70        int res = 0;
  71
  72        ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
  73        if (!ssb)
  74                goto out_error;
  75
  76        err = -ENODEV;
  77
  78        dev->conf.Attributes = CONF_ENABLE_IRQ;
  79        dev->conf.IntType = INT_MEMORY_AND_IO;
  80
  81        dev->io.BasePort2 = 0;
  82        dev->io.NumPorts2 = 0;
  83        dev->io.Attributes2 = 0;
  84
  85        win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
  86                         WIN_ENABLE | WIN_DATA_WIDTH_16 |
  87                         WIN_USE_WAIT;
  88        win.Base = 0;
  89        win.Size = SSB_CORE_SIZE;
  90        win.AccessSpeed = 250;
  91        res = pcmcia_request_window(dev, &win, &dev->win);
  92        if (res != 0)
  93                goto err_kfree_ssb;
  94
  95        mem.CardOffset = 0;
  96        mem.Page = 0;
  97        res = pcmcia_map_mem_page(dev, dev->win, &mem);
  98        if (res != 0)
  99                goto err_disable;
 100
 101        dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 102        dev->irq.Handler = NULL; /* The handler is registered later. */
 103        res = pcmcia_request_irq(dev, &dev->irq);
 104        if (res != 0)
 105                goto err_disable;
 106
 107        res = pcmcia_request_configuration(dev, &dev->conf);
 108        if (res != 0)
 109                goto err_disable;
 110
 111        err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
 112        if (err)
 113                goto err_disable;
 114        dev->priv = ssb;
 115
 116        return 0;
 117
 118err_disable:
 119        pcmcia_disable_device(dev);
 120err_kfree_ssb:
 121        kfree(ssb);
 122out_error:
 123        printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
 124               res, err);
 125        return err;
 126}
 127
 128static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
 129{
 130        struct ssb_bus *ssb = dev->priv;
 131
 132        ssb_bus_unregister(ssb);
 133        pcmcia_disable_device(dev);
 134        kfree(ssb);
 135        dev->priv = NULL;
 136}
 137
 138static struct pcmcia_driver b43_pcmcia_driver = {
 139        .owner          = THIS_MODULE,
 140        .drv            = {
 141                                .name = "b43-pcmcia",
 142                        },
 143        .id_table       = b43_pcmcia_tbl,
 144        .probe          = b43_pcmcia_probe,
 145        .remove         = __devexit_p(b43_pcmcia_remove),
 146        .suspend        = b43_pcmcia_suspend,
 147        .resume         = b43_pcmcia_resume,
 148};
 149
 150int b43_pcmcia_init(void)
 151{
 152        return pcmcia_register_driver(&b43_pcmcia_driver);
 153}
 154
 155void b43_pcmcia_exit(void)
 156{
 157        pcmcia_unregister_driver(&b43_pcmcia_driver);
 158}
 159
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.