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

wax.c (3030B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *	WAX Device Driver
      4 *
      5 *	(c) Copyright 2000 The Puffin Group Inc.
      6 *
      7 *	by Helge Deller <deller@gmx.de>
      8 */
      9
     10#include <linux/errno.h>
     11#include <linux/init.h>
     12#include <linux/interrupt.h>
     13#include <linux/ioport.h>
     14#include <linux/slab.h>
     15#include <linux/module.h>
     16#include <linux/types.h>
     17
     18#include <asm/io.h>
     19#include <asm/hardware.h>
     20
     21#include "gsc.h"
     22
     23#define WAX_GSC_IRQ	7	/* Hardcoded Interrupt for GSC */
     24
     25static void wax_choose_irq(struct parisc_device *dev, void *ctrl)
     26{
     27	int irq;
     28
     29	switch (dev->id.sversion) {
     30		case 0x73:	irq =  1; break; /* i8042 General */
     31		case 0x8c:	irq =  6; break; /* Serial */
     32		case 0x90:	irq = 10; break; /* EISA */
     33		default:	return;		 /* Unknown */
     34	}
     35
     36	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
     37
     38	switch (dev->id.sversion) {
     39		case 0x73:	irq =  2; break; /* i8042 High-priority */
     40		case 0x90:	irq =  0; break; /* EISA NMI */
     41		default:	return;		 /* No secondary IRQ */
     42	}
     43
     44	gsc_asic_assign_irq(ctrl, irq, &dev->aux_irq);
     45}
     46
     47static void __init
     48wax_init_irq(struct gsc_asic *wax)
     49{
     50	unsigned long base = wax->hpa;
     51
     52	/* Wax-off */
     53	gsc_writel(0x00000000, base+OFFSET_IMR);
     54
     55	/* clear pending interrupts */
     56	gsc_readl(base+OFFSET_IRR);
     57
     58	/* We're not really convinced we want to reset the onboard
     59         * devices. Firmware does it for us...
     60	 */
     61
     62	/* Resets */
     63//	gsc_writel(0xFFFFFFFF, base+0x1000); /* HIL */
     64//	gsc_writel(0xFFFFFFFF, base+0x2000); /* RS232-B on Wax */
     65}
     66
     67static int __init wax_init_chip(struct parisc_device *dev)
     68{
     69	struct gsc_asic *wax;
     70	struct parisc_device *parent;
     71	int ret;
     72
     73	wax = kzalloc(sizeof(*wax), GFP_KERNEL);
     74	if (!wax)
     75		return -ENOMEM;
     76
     77	wax->name = "wax";
     78	wax->hpa = dev->hpa.start;
     79
     80	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
     81	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
     82
     83	/* Stop wax hissing for a bit */
     84	wax_init_irq(wax);
     85
     86	/* the IRQ wax should use */
     87	dev->irq = gsc_claim_irq(&wax->gsc_irq, WAX_GSC_IRQ);
     88	if (dev->irq < 0) {
     89		printk(KERN_ERR "%s(): cannot get GSC irq\n",
     90				__func__);
     91		kfree(wax);
     92		return -EBUSY;
     93	}
     94
     95	wax->eim = ((u32) wax->gsc_irq.txn_addr) | wax->gsc_irq.txn_data;
     96
     97	ret = request_irq(wax->gsc_irq.irq, gsc_asic_intr, 0, "wax", wax);
     98	if (ret < 0) {
     99		kfree(wax);
    100		return ret;
    101	}
    102
    103	/* enable IRQ's for devices below WAX */
    104	gsc_writel(wax->eim, wax->hpa + OFFSET_IAR);
    105
    106	/* Done init'ing, register this driver */
    107	ret = gsc_common_setup(dev, wax);
    108	if (ret) {
    109		kfree(wax);
    110		return ret;
    111	}
    112
    113	gsc_fixup_irqs(dev, wax, wax_choose_irq);
    114	/* On 715-class machines, Wax EISA is a sibling of Wax, not a child. */
    115	parent = parisc_parent(dev);
    116	if (parent->id.hw_type != HPHW_IOA) {
    117		gsc_fixup_irqs(parent, wax, wax_choose_irq);
    118	}
    119
    120	return ret;
    121}
    122
    123static const struct parisc_device_id wax_tbl[] __initconst = {
    124  	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e },
    125	{ 0, }
    126};
    127
    128MODULE_DEVICE_TABLE(parisc, wax_tbl);
    129
    130struct parisc_driver wax_driver __refdata = {
    131	.name =		"wax",
    132	.id_table =	wax_tbl,
    133	.probe =	wax_init_chip,
    134};