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

softing_cs.c (8992B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2008-2010
      4 *
      5 * - Kurt Van Dijck, EIA Electronics
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/kernel.h>
     10#include <linux/slab.h>
     11
     12#include <pcmcia/cistpl.h>
     13#include <pcmcia/ds.h>
     14
     15#include "softing_platform.h"
     16
     17static int softingcs_index;
     18static DEFINE_SPINLOCK(softingcs_index_lock);
     19
     20static int softingcs_reset(struct platform_device *pdev, int v);
     21static int softingcs_enable_irq(struct platform_device *pdev, int v);
     22
     23/*
     24 * platform_data descriptions
     25 */
     26#define MHZ (1000*1000)
     27static const struct softing_platform_data softingcs_platform_data[] = {
     28{
     29	.name = "CANcard",
     30	.manf = 0x0168, .prod = 0x001,
     31	.generation = 1,
     32	.nbus = 2,
     33	.freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4,
     34	.dpram_size = 0x0800,
     35	.boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
     36	.load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
     37	.app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
     38	.reset = softingcs_reset,
     39	.enable_irq = softingcs_enable_irq,
     40}, {
     41	.name = "CANcard-NEC",
     42	.manf = 0x0168, .prod = 0x002,
     43	.generation = 1,
     44	.nbus = 2,
     45	.freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4,
     46	.dpram_size = 0x0800,
     47	.boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
     48	.load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
     49	.app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
     50	.reset = softingcs_reset,
     51	.enable_irq = softingcs_enable_irq,
     52}, {
     53	.name = "CANcard-SJA",
     54	.manf = 0x0168, .prod = 0x004,
     55	.generation = 1,
     56	.nbus = 2,
     57	.freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4,
     58	.dpram_size = 0x0800,
     59	.boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
     60	.load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
     61	.app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
     62	.reset = softingcs_reset,
     63	.enable_irq = softingcs_enable_irq,
     64}, {
     65	.name = "CANcard-2",
     66	.manf = 0x0168, .prod = 0x005,
     67	.generation = 2,
     68	.nbus = 2,
     69	.freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
     70	.dpram_size = 0x1000,
     71	.boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
     72	.load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
     73	.app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
     74	.reset = softingcs_reset,
     75	.enable_irq = NULL,
     76}, {
     77	.name = "Vector-CANcard",
     78	.manf = 0x0168, .prod = 0x081,
     79	.generation = 1,
     80	.nbus = 2,
     81	.freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4,
     82	.dpram_size = 0x0800,
     83	.boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
     84	.load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
     85	.app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
     86	.reset = softingcs_reset,
     87	.enable_irq = softingcs_enable_irq,
     88}, {
     89	.name = "Vector-CANcard-SJA",
     90	.manf = 0x0168, .prod = 0x084,
     91	.generation = 1,
     92	.nbus = 2,
     93	.freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4,
     94	.dpram_size = 0x0800,
     95	.boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
     96	.load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
     97	.app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
     98	.reset = softingcs_reset,
     99	.enable_irq = softingcs_enable_irq,
    100}, {
    101	.name = "Vector-CANcard-2",
    102	.manf = 0x0168, .prod = 0x085,
    103	.generation = 2,
    104	.nbus = 2,
    105	.freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
    106	.dpram_size = 0x1000,
    107	.boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
    108	.load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
    109	.app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
    110	.reset = softingcs_reset,
    111	.enable_irq = NULL,
    112}, {
    113	.name = "EDICcard-NEC",
    114	.manf = 0x0168, .prod = 0x102,
    115	.generation = 1,
    116	.nbus = 2,
    117	.freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4,
    118	.dpram_size = 0x0800,
    119	.boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
    120	.load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
    121	.app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
    122	.reset = softingcs_reset,
    123	.enable_irq = softingcs_enable_irq,
    124}, {
    125	.name = "EDICcard-2",
    126	.manf = 0x0168, .prod = 0x105,
    127	.generation = 2,
    128	.nbus = 2,
    129	.freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
    130	.dpram_size = 0x1000,
    131	.boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
    132	.load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
    133	.app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
    134	.reset = softingcs_reset,
    135	.enable_irq = NULL,
    136}, {
    137	0, 0,
    138},
    139};
    140
    141MODULE_FIRMWARE(fw_dir "bcard.bin");
    142MODULE_FIRMWARE(fw_dir "ldcard.bin");
    143MODULE_FIRMWARE(fw_dir "cancard.bin");
    144MODULE_FIRMWARE(fw_dir "cansja.bin");
    145
    146MODULE_FIRMWARE(fw_dir "bcard2.bin");
    147MODULE_FIRMWARE(fw_dir "ldcard2.bin");
    148MODULE_FIRMWARE(fw_dir "cancrd2.bin");
    149
    150static const struct softing_platform_data
    151*softingcs_find_platform_data(unsigned int manf, unsigned int prod)
    152{
    153	const struct softing_platform_data *lp;
    154
    155	for (lp = softingcs_platform_data; lp->manf; ++lp) {
    156		if ((lp->manf == manf) && (lp->prod == prod))
    157			return lp;
    158	}
    159	return NULL;
    160}
    161
    162/*
    163 * platformdata callbacks
    164 */
    165static int softingcs_reset(struct platform_device *pdev, int v)
    166{
    167	struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);
    168
    169	dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20);
    170	return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20);
    171}
    172
    173static int softingcs_enable_irq(struct platform_device *pdev, int v)
    174{
    175	struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);
    176
    177	dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0);
    178	return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0);
    179}
    180
    181/*
    182 * pcmcia check
    183 */
    184static int softingcs_probe_config(struct pcmcia_device *pcmcia, void *priv_data)
    185{
    186	struct softing_platform_data *pdat = priv_data;
    187	struct resource *pres;
    188	int memspeed = 0;
    189
    190	WARN_ON(!pdat);
    191	pres = pcmcia->resource[PCMCIA_IOMEM_0];
    192	if (resource_size(pres) < 0x1000)
    193		return -ERANGE;
    194
    195	pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
    196	if (pdat->generation < 2) {
    197		pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8;
    198		memspeed = 3;
    199	} else {
    200		pres->flags |= WIN_DATA_WIDTH_16;
    201	}
    202	return pcmcia_request_window(pcmcia, pres, memspeed);
    203}
    204
    205static void softingcs_remove(struct pcmcia_device *pcmcia)
    206{
    207	struct platform_device *pdev = pcmcia->priv;
    208
    209	/* free bits */
    210	platform_device_unregister(pdev);
    211	/* release pcmcia stuff */
    212	pcmcia_disable_device(pcmcia);
    213}
    214
    215/*
    216 * platform_device wrapper
    217 * pdev->resource has 2 entries: io & irq
    218 */
    219static void softingcs_pdev_release(struct device *dev)
    220{
    221	struct platform_device *pdev = to_platform_device(dev);
    222	kfree(pdev);
    223}
    224
    225static int softingcs_probe(struct pcmcia_device *pcmcia)
    226{
    227	int ret;
    228	struct platform_device *pdev;
    229	const struct softing_platform_data *pdat;
    230	struct resource *pres;
    231	struct dev {
    232		struct platform_device pdev;
    233		struct resource res[2];
    234	} *dev;
    235
    236	/* find matching platform_data */
    237	pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id);
    238	if (!pdat)
    239		return -ENOTTY;
    240
    241	/* setup pcmcia device */
    242	pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM |
    243		CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
    244	ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat);
    245	if (ret)
    246		goto pcmcia_failed;
    247
    248	ret = pcmcia_enable_device(pcmcia);
    249	if (ret < 0)
    250		goto pcmcia_failed;
    251
    252	pres = pcmcia->resource[PCMCIA_IOMEM_0];
    253	if (!pres) {
    254		ret = -EBADF;
    255		goto pcmcia_bad;
    256	}
    257
    258	/* create softing platform device */
    259	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    260	if (!dev) {
    261		ret = -ENOMEM;
    262		goto mem_failed;
    263	}
    264	dev->pdev.resource = dev->res;
    265	dev->pdev.num_resources = ARRAY_SIZE(dev->res);
    266	dev->pdev.dev.release = softingcs_pdev_release;
    267
    268	pdev = &dev->pdev;
    269	pdev->dev.platform_data = (void *)pdat;
    270	pdev->dev.parent = &pcmcia->dev;
    271	pcmcia->priv = pdev;
    272
    273	/* platform device resources */
    274	pdev->resource[0].flags = IORESOURCE_MEM;
    275	pdev->resource[0].start = pres->start;
    276	pdev->resource[0].end = pres->end;
    277
    278	pdev->resource[1].flags = IORESOURCE_IRQ;
    279	pdev->resource[1].start = pcmcia->irq;
    280	pdev->resource[1].end = pdev->resource[1].start;
    281
    282	/* platform device setup */
    283	spin_lock(&softingcs_index_lock);
    284	pdev->id = softingcs_index++;
    285	spin_unlock(&softingcs_index_lock);
    286	pdev->name = "softing";
    287	dev_set_name(&pdev->dev, "softingcs.%i", pdev->id);
    288	ret = platform_device_register(pdev);
    289	if (ret < 0)
    290		goto platform_failed;
    291
    292	dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev));
    293	return 0;
    294
    295platform_failed:
    296	platform_device_put(pdev);
    297mem_failed:
    298pcmcia_bad:
    299pcmcia_failed:
    300	pcmcia_disable_device(pcmcia);
    301	pcmcia->priv = NULL;
    302	return ret;
    303}
    304
    305static const struct pcmcia_device_id softingcs_ids[] = {
    306	/* softing */
    307	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001),
    308	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002),
    309	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004),
    310	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005),
    311	/* vector, manufacturer? */
    312	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081),
    313	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084),
    314	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085),
    315	/* EDIC */
    316	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102),
    317	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105),
    318	PCMCIA_DEVICE_NULL,
    319};
    320
    321MODULE_DEVICE_TABLE(pcmcia, softingcs_ids);
    322
    323static struct pcmcia_driver softingcs_driver = {
    324	.owner		= THIS_MODULE,
    325	.name		= "softingcs",
    326	.id_table	= softingcs_ids,
    327	.probe		= softingcs_probe,
    328	.remove		= softingcs_remove,
    329};
    330
    331module_pcmcia_driver(softingcs_driver);
    332
    333MODULE_DESCRIPTION("softing CANcard driver"
    334		", links PCMCIA card to softing driver");
    335MODULE_LICENSE("GPL v2");