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

c2port-duramar2150.c (3150B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Silicon Labs C2 port Linux support for Eurotech Duramar 2150
      4 *
      5 *  Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it>
      6 *  Copyright (c) 2008 Eurotech S.p.A. <info@eurotech.it>
      7 */
      8
      9#include <linux/errno.h>
     10#include <linux/init.h>
     11#include <linux/kernel.h>
     12#include <linux/module.h>
     13#include <linux/delay.h>
     14#include <linux/io.h>
     15#include <linux/ioport.h>
     16#include <linux/c2port.h>
     17
     18#define DATA_PORT	0x325
     19#define DIR_PORT	0x326
     20#define    C2D		   (1 << 0)
     21#define    C2CK		   (1 << 1)
     22
     23static DEFINE_MUTEX(update_lock);
     24
     25/*
     26 * C2 port operations
     27 */
     28
     29static void duramar2150_c2port_access(struct c2port_device *dev, int status)
     30{
     31	u8 v;
     32
     33	mutex_lock(&update_lock);
     34
     35	v = inb(DIR_PORT);
     36
     37	/* 0 = input, 1 = output */
     38	if (status)
     39		outb(v | (C2D | C2CK), DIR_PORT);
     40	else
     41		/* When access is "off" is important that both lines are set
     42		 * as inputs or hi-impedance */
     43		outb(v & ~(C2D | C2CK), DIR_PORT);
     44
     45	mutex_unlock(&update_lock);
     46}
     47
     48static void duramar2150_c2port_c2d_dir(struct c2port_device *dev, int dir)
     49{
     50	u8 v;
     51
     52	mutex_lock(&update_lock);
     53
     54	v = inb(DIR_PORT);
     55
     56	if (dir)
     57		outb(v & ~C2D, DIR_PORT);
     58	else
     59		outb(v | C2D, DIR_PORT);
     60
     61	mutex_unlock(&update_lock);
     62}
     63
     64static int duramar2150_c2port_c2d_get(struct c2port_device *dev)
     65{
     66	return inb(DATA_PORT) & C2D;
     67}
     68
     69static void duramar2150_c2port_c2d_set(struct c2port_device *dev, int status)
     70{
     71	u8 v;
     72
     73	mutex_lock(&update_lock);
     74
     75	v = inb(DATA_PORT);
     76
     77	if (status)
     78		outb(v | C2D, DATA_PORT);
     79	else
     80		outb(v & ~C2D, DATA_PORT);
     81
     82	mutex_unlock(&update_lock);
     83}
     84
     85static void duramar2150_c2port_c2ck_set(struct c2port_device *dev, int status)
     86{
     87	u8 v;
     88
     89	mutex_lock(&update_lock);
     90
     91	v = inb(DATA_PORT);
     92
     93	if (status)
     94		outb(v | C2CK, DATA_PORT);
     95	else
     96		outb(v & ~C2CK, DATA_PORT);
     97
     98	mutex_unlock(&update_lock);
     99}
    100
    101static struct c2port_ops duramar2150_c2port_ops = {
    102	.block_size	= 512,	/* bytes */
    103	.blocks_num	= 30,	/* total flash size: 15360 bytes */
    104
    105	.access		= duramar2150_c2port_access,
    106	.c2d_dir	= duramar2150_c2port_c2d_dir,
    107	.c2d_get	= duramar2150_c2port_c2d_get,
    108	.c2d_set	= duramar2150_c2port_c2d_set,
    109	.c2ck_set	= duramar2150_c2port_c2ck_set,
    110};
    111
    112static struct c2port_device *duramar2150_c2port_dev;
    113
    114/*
    115 * Module stuff
    116 */
    117
    118static int __init duramar2150_c2port_init(void)
    119{
    120	struct resource *res;
    121	int ret = 0;
    122
    123	res = request_region(0x325, 2, "c2port");
    124	if (!res)
    125		return -EBUSY;
    126
    127	duramar2150_c2port_dev = c2port_device_register("uc",
    128					&duramar2150_c2port_ops, NULL);
    129	if (IS_ERR(duramar2150_c2port_dev)) {
    130		ret = PTR_ERR(duramar2150_c2port_dev);
    131		goto free_region;
    132	}
    133
    134	return 0;
    135
    136free_region:
    137	release_region(0x325, 2);
    138	return ret;
    139}
    140
    141static void __exit duramar2150_c2port_exit(void)
    142{
    143	/* Setup the GPIOs as input by default (access = 0) */
    144	duramar2150_c2port_access(duramar2150_c2port_dev, 0);
    145
    146	c2port_device_unregister(duramar2150_c2port_dev);
    147
    148	release_region(0x325, 2);
    149}
    150
    151module_init(duramar2150_c2port_init);
    152module_exit(duramar2150_c2port_exit);
    153
    154MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
    155MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for Duramar 2150");
    156MODULE_LICENSE("GPL");