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

i2c-hydra.c (3462B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3    i2c Support for the Apple `Hydra' Mac I/O
      4
      5    Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
      6
      7    Based on i2c Support for Via Technologies 82C586B South Bridge
      8    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
      9
     10*/
     11
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/pci.h>
     15#include <linux/types.h>
     16#include <linux/i2c.h>
     17#include <linux/i2c-algo-bit.h>
     18#include <linux/io.h>
     19#include <asm/hydra.h>
     20
     21
     22#define HYDRA_CPD_PD0	0x00000001	/* CachePD lines */
     23#define HYDRA_CPD_PD1	0x00000002
     24#define HYDRA_CPD_PD2	0x00000004
     25#define HYDRA_CPD_PD3	0x00000008
     26
     27#define HYDRA_SCLK	HYDRA_CPD_PD0
     28#define HYDRA_SDAT	HYDRA_CPD_PD1
     29#define HYDRA_SCLK_OE	0x00000010
     30#define HYDRA_SDAT_OE	0x00000020
     31
     32static inline void pdregw(void *data, u32 val)
     33{
     34	struct Hydra *hydra = (struct Hydra *)data;
     35	writel(val, &hydra->CachePD);
     36}
     37
     38static inline u32 pdregr(void *data)
     39{
     40	struct Hydra *hydra = (struct Hydra *)data;
     41	return readl(&hydra->CachePD);
     42}
     43
     44static void hydra_bit_setscl(void *data, int state)
     45{
     46	u32 val = pdregr(data);
     47	if (state)
     48		val &= ~HYDRA_SCLK_OE;
     49	else {
     50		val &= ~HYDRA_SCLK;
     51		val |= HYDRA_SCLK_OE;
     52	}
     53	pdregw(data, val);
     54}
     55
     56static void hydra_bit_setsda(void *data, int state)
     57{
     58	u32 val = pdregr(data);
     59	if (state)
     60		val &= ~HYDRA_SDAT_OE;
     61	else {
     62		val &= ~HYDRA_SDAT;
     63		val |= HYDRA_SDAT_OE;
     64	}
     65	pdregw(data, val);
     66}
     67
     68static int hydra_bit_getscl(void *data)
     69{
     70	return (pdregr(data) & HYDRA_SCLK) != 0;
     71}
     72
     73static int hydra_bit_getsda(void *data)
     74{
     75	return (pdregr(data) & HYDRA_SDAT) != 0;
     76}
     77
     78/* ------------------------------------------------------------------------ */
     79
     80static struct i2c_algo_bit_data hydra_bit_data = {
     81	.setsda		= hydra_bit_setsda,
     82	.setscl		= hydra_bit_setscl,
     83	.getsda		= hydra_bit_getsda,
     84	.getscl		= hydra_bit_getscl,
     85	.udelay		= 5,
     86	.timeout	= HZ
     87};
     88
     89static struct i2c_adapter hydra_adap = {
     90	.owner		= THIS_MODULE,
     91	.name		= "Hydra i2c",
     92	.algo_data	= &hydra_bit_data,
     93};
     94
     95static const struct pci_device_id hydra_ids[] = {
     96	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
     97	{ 0, }
     98};
     99
    100MODULE_DEVICE_TABLE (pci, hydra_ids);
    101
    102static int hydra_probe(struct pci_dev *dev,
    103				 const struct pci_device_id *id)
    104{
    105	unsigned long base = pci_resource_start(dev, 0);
    106	int res;
    107
    108	if (!request_mem_region(base+offsetof(struct Hydra, CachePD), 4,
    109				hydra_adap.name))
    110		return -EBUSY;
    111
    112	hydra_bit_data.data = pci_ioremap_bar(dev, 0);
    113	if (hydra_bit_data.data == NULL) {
    114		release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
    115		return -ENODEV;
    116	}
    117
    118	pdregw(hydra_bit_data.data, 0);		/* clear SCLK_OE and SDAT_OE */
    119	hydra_adap.dev.parent = &dev->dev;
    120	res = i2c_bit_add_bus(&hydra_adap);
    121	if (res < 0) {
    122		iounmap(hydra_bit_data.data);
    123		release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
    124		return res;
    125	}
    126	return 0;
    127}
    128
    129static void hydra_remove(struct pci_dev *dev)
    130{
    131	pdregw(hydra_bit_data.data, 0);		/* clear SCLK_OE and SDAT_OE */
    132	i2c_del_adapter(&hydra_adap);
    133	iounmap(hydra_bit_data.data);
    134	release_mem_region(pci_resource_start(dev, 0)+
    135			   offsetof(struct Hydra, CachePD), 4);
    136}
    137
    138
    139static struct pci_driver hydra_driver = {
    140	.name		= "hydra_smbus",
    141	.id_table	= hydra_ids,
    142	.probe		= hydra_probe,
    143	.remove		= hydra_remove,
    144};
    145
    146module_pci_driver(hydra_driver);
    147
    148MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
    149MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O");
    150MODULE_LICENSE("GPL");