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

saa7164-i2c.c (2679B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Driver for the NXP SAA7164 PCIe bridge
      4 *
      5 *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/moduleparam.h>
     10#include <linux/init.h>
     11#include <linux/delay.h>
     12#include <linux/io.h>
     13
     14#include "saa7164.h"
     15
     16static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
     17{
     18	struct saa7164_i2c *bus = i2c_adap->algo_data;
     19	struct saa7164_dev *dev = bus->dev;
     20	int i, retval = 0;
     21
     22	dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
     23
     24	for (i = 0 ; i < num; i++) {
     25		dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",
     26			__func__, num, msgs[i].addr, msgs[i].len);
     27		if (msgs[i].flags & I2C_M_RD) {
     28			retval = saa7164_api_i2c_read(bus,
     29				msgs[i].addr,
     30				0 /* reglen */,
     31				NULL /* reg */, msgs[i].len, msgs[i].buf);
     32		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
     33			   msgs[i].addr == msgs[i + 1].addr) {
     34			/* write then read from same address */
     35
     36			retval = saa7164_api_i2c_read(bus, msgs[i].addr,
     37				msgs[i].len, msgs[i].buf,
     38				msgs[i+1].len, msgs[i+1].buf
     39				);
     40
     41			i++;
     42
     43			if (retval < 0)
     44				goto err;
     45		} else {
     46			/* write */
     47			retval = saa7164_api_i2c_write(bus, msgs[i].addr,
     48				msgs[i].len, msgs[i].buf);
     49		}
     50		if (retval < 0)
     51			goto err;
     52	}
     53	return num;
     54
     55err:
     56	return retval;
     57}
     58
     59static u32 saa7164_functionality(struct i2c_adapter *adap)
     60{
     61	return I2C_FUNC_I2C;
     62}
     63
     64static const struct i2c_algorithm saa7164_i2c_algo_template = {
     65	.master_xfer	= i2c_xfer,
     66	.functionality	= saa7164_functionality,
     67};
     68
     69/* ----------------------------------------------------------------------- */
     70
     71static const struct i2c_adapter saa7164_i2c_adap_template = {
     72	.name              = "saa7164",
     73	.owner             = THIS_MODULE,
     74	.algo              = &saa7164_i2c_algo_template,
     75};
     76
     77static const struct i2c_client saa7164_i2c_client_template = {
     78	.name	= "saa7164 internal",
     79};
     80
     81int saa7164_i2c_register(struct saa7164_i2c *bus)
     82{
     83	struct saa7164_dev *dev = bus->dev;
     84
     85	dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
     86
     87	bus->i2c_adap = saa7164_i2c_adap_template;
     88	bus->i2c_client = saa7164_i2c_client_template;
     89
     90	bus->i2c_adap.dev.parent = &dev->pci->dev;
     91
     92	strscpy(bus->i2c_adap.name, bus->dev->name,
     93		sizeof(bus->i2c_adap.name));
     94
     95	bus->i2c_adap.algo_data = bus;
     96	i2c_set_adapdata(&bus->i2c_adap, bus);
     97	i2c_add_adapter(&bus->i2c_adap);
     98
     99	bus->i2c_client.adapter = &bus->i2c_adap;
    100
    101	if (0 != bus->i2c_rc)
    102		printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
    103			dev->name, bus->nr);
    104
    105	return bus->i2c_rc;
    106}
    107
    108int saa7164_i2c_unregister(struct saa7164_i2c *bus)
    109{
    110	i2c_del_adapter(&bus->i2c_adap);
    111	return 0;
    112}