cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bridge_pcmcia_80211.c (2843B)


      1/*
      2 * Broadcom 43xx PCMCIA-SSB bridge module
      3 *
      4 * Copyright (c) 2007 Michael Buesch <m@bues.ch>
      5 *
      6 * Licensed under the GNU/GPL. See COPYING for details.
      7 */
      8
      9#include "ssb_private.h"
     10
     11#include <linux/ssb/ssb.h>
     12#include <linux/slab.h>
     13#include <linux/module.h>
     14
     15#include <pcmcia/cistpl.h>
     16#include <pcmcia/ciscode.h>
     17#include <pcmcia/ds.h>
     18#include <pcmcia/cisreg.h>
     19
     20static const struct pcmcia_device_id ssb_host_pcmcia_tbl[] = {
     21	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
     22	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
     23	PCMCIA_DEVICE_NULL,
     24};
     25
     26MODULE_DEVICE_TABLE(pcmcia, ssb_host_pcmcia_tbl);
     27
     28static int ssb_host_pcmcia_probe(struct pcmcia_device *dev)
     29{
     30	struct ssb_bus *ssb;
     31	int err = -ENOMEM;
     32	int res = 0;
     33
     34	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
     35	if (!ssb)
     36		goto out_error;
     37
     38	err = -ENODEV;
     39
     40	dev->config_flags |= CONF_ENABLE_IRQ;
     41
     42	dev->resource[2]->flags |=  WIN_ENABLE | WIN_DATA_WIDTH_16 |
     43			 WIN_USE_WAIT;
     44	dev->resource[2]->start = 0;
     45	dev->resource[2]->end = SSB_CORE_SIZE;
     46	res = pcmcia_request_window(dev, dev->resource[2], 250);
     47	if (res != 0)
     48		goto err_kfree_ssb;
     49
     50	res = pcmcia_map_mem_page(dev, dev->resource[2], 0);
     51	if (res != 0)
     52		goto err_disable;
     53
     54	if (!dev->irq)
     55		goto err_disable;
     56
     57	res = pcmcia_enable_device(dev);
     58	if (res != 0)
     59		goto err_disable;
     60
     61	err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start);
     62	if (err)
     63		goto err_disable;
     64	dev->priv = ssb;
     65
     66	return 0;
     67
     68err_disable:
     69	pcmcia_disable_device(dev);
     70err_kfree_ssb:
     71	kfree(ssb);
     72out_error:
     73	dev_err(&dev->dev, "Initialization failed (%d, %d)\n", res, err);
     74	return err;
     75}
     76
     77static void ssb_host_pcmcia_remove(struct pcmcia_device *dev)
     78{
     79	struct ssb_bus *ssb = dev->priv;
     80
     81	ssb_bus_unregister(ssb);
     82	pcmcia_disable_device(dev);
     83	kfree(ssb);
     84	dev->priv = NULL;
     85}
     86
     87#ifdef CONFIG_PM
     88static int ssb_host_pcmcia_suspend(struct pcmcia_device *dev)
     89{
     90	struct ssb_bus *ssb = dev->priv;
     91
     92	return ssb_bus_suspend(ssb);
     93}
     94
     95static int ssb_host_pcmcia_resume(struct pcmcia_device *dev)
     96{
     97	struct ssb_bus *ssb = dev->priv;
     98
     99	return ssb_bus_resume(ssb);
    100}
    101#else /* CONFIG_PM */
    102# define ssb_host_pcmcia_suspend		NULL
    103# define ssb_host_pcmcia_resume		NULL
    104#endif /* CONFIG_PM */
    105
    106static struct pcmcia_driver ssb_host_pcmcia_driver = {
    107	.owner		= THIS_MODULE,
    108	.name		= "ssb-pcmcia",
    109	.id_table	= ssb_host_pcmcia_tbl,
    110	.probe		= ssb_host_pcmcia_probe,
    111	.remove		= ssb_host_pcmcia_remove,
    112	.suspend	= ssb_host_pcmcia_suspend,
    113	.resume		= ssb_host_pcmcia_resume,
    114};
    115
    116static int pcmcia_init_failed;
    117
    118/*
    119 * These are not module init/exit functions!
    120 * The module_pcmcia_driver() helper cannot be used here.
    121 */
    122int ssb_host_pcmcia_init(void)
    123{
    124	pcmcia_init_failed = pcmcia_register_driver(&ssb_host_pcmcia_driver);
    125
    126	return pcmcia_init_failed;
    127}
    128
    129void ssb_host_pcmcia_exit(void)
    130{
    131	if (!pcmcia_init_failed)
    132		pcmcia_unregister_driver(&ssb_host_pcmcia_driver);
    133}