xref: /openbmc/linux/drivers/parisc/wax.c (revision ac65d9c9)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *	WAX Device Driver
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *	(c) Copyright 2000 The Puffin Group Inc.
61da177e4SLinus Torvalds  *
7*ac65d9c9SHelge Deller  *	(c) 2000-2023 by Helge Deller <deller@gmx.de>
81da177e4SLinus Torvalds  */
91da177e4SLinus Torvalds 
101da177e4SLinus Torvalds #include <linux/errno.h>
111da177e4SLinus Torvalds #include <linux/init.h>
121da177e4SLinus Torvalds #include <linux/interrupt.h>
131da177e4SLinus Torvalds #include <linux/ioport.h>
141da177e4SLinus Torvalds #include <linux/slab.h>
151da177e4SLinus Torvalds #include <linux/module.h>
161da177e4SLinus Torvalds #include <linux/types.h>
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds #include <asm/io.h>
191da177e4SLinus Torvalds #include <asm/hardware.h>
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds #include "gsc.h"
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds #define WAX_GSC_IRQ	7	/* Hardcoded Interrupt for GSC */
241da177e4SLinus Torvalds 
wax_choose_irq(struct parisc_device * dev,void * ctrl)251da177e4SLinus Torvalds static void wax_choose_irq(struct parisc_device *dev, void *ctrl)
261da177e4SLinus Torvalds {
271da177e4SLinus Torvalds 	int irq;
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds 	switch (dev->id.sversion) {
301da177e4SLinus Torvalds 		case 0x73:	irq =  1; break; /* i8042 General */
311da177e4SLinus Torvalds 		case 0x8c:	irq =  6; break; /* Serial */
321da177e4SLinus Torvalds 		case 0x90:	irq = 10; break; /* EISA */
331da177e4SLinus Torvalds 		default:	return;		 /* Unknown */
341da177e4SLinus Torvalds 	}
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds 	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds 	switch (dev->id.sversion) {
391da177e4SLinus Torvalds 		case 0x73:	irq =  2; break; /* i8042 High-priority */
401da177e4SLinus Torvalds 		case 0x90:	irq =  0; break; /* EISA NMI */
411da177e4SLinus Torvalds 		default:	return;		 /* No secondary IRQ */
421da177e4SLinus Torvalds 	}
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds 	gsc_asic_assign_irq(ctrl, irq, &dev->aux_irq);
451da177e4SLinus Torvalds }
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds static void __init
wax_init_irq(struct gsc_asic * wax)481da177e4SLinus Torvalds wax_init_irq(struct gsc_asic *wax)
491da177e4SLinus Torvalds {
501da177e4SLinus Torvalds 	unsigned long base = wax->hpa;
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds 	/* Wax-off */
531da177e4SLinus Torvalds 	gsc_writel(0x00000000, base+OFFSET_IMR);
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds 	/* clear pending interrupts */
561da177e4SLinus Torvalds 	gsc_readl(base+OFFSET_IRR);
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds 	/* We're not really convinced we want to reset the onboard
591da177e4SLinus Torvalds          * devices. Firmware does it for us...
601da177e4SLinus Torvalds 	 */
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds 	/* Resets */
631da177e4SLinus Torvalds //	gsc_writel(0xFFFFFFFF, base+0x1000); /* HIL */
641da177e4SLinus Torvalds //	gsc_writel(0xFFFFFFFF, base+0x2000); /* RS232-B on Wax */
651da177e4SLinus Torvalds }
661da177e4SLinus Torvalds 
wax_init_chip(struct parisc_device * dev)67df8e5bc6SAdrian Bunk static int __init wax_init_chip(struct parisc_device *dev)
681da177e4SLinus Torvalds {
691da177e4SLinus Torvalds 	struct gsc_asic *wax;
701da177e4SLinus Torvalds 	struct parisc_device *parent;
711da177e4SLinus Torvalds 	int ret;
721da177e4SLinus Torvalds 
73cb6fc18eSHelge Deller 	wax = kzalloc(sizeof(*wax), GFP_KERNEL);
741da177e4SLinus Torvalds 	if (!wax)
751da177e4SLinus Torvalds 		return -ENOMEM;
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 	wax->name = "wax";
7853f01bbaSMatthew Wilcox 	wax->hpa = dev->hpa.start;
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds 	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
811da177e4SLinus Torvalds 	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	/* Stop wax hissing for a bit */
841da177e4SLinus Torvalds 	wax_init_irq(wax);
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds 	/* the IRQ wax should use */
87939fc856SHelge Deller 	dev->irq = gsc_claim_irq(&wax->gsc_irq, WAX_GSC_IRQ);
881da177e4SLinus Torvalds 	if (dev->irq < 0) {
891da177e4SLinus Torvalds 		printk(KERN_ERR "%s(): cannot get GSC irq\n",
90a8043ecbSHarvey Harrison 				__func__);
911da177e4SLinus Torvalds 		kfree(wax);
921da177e4SLinus Torvalds 		return -EBUSY;
931da177e4SLinus Torvalds 	}
941da177e4SLinus Torvalds 
95939fc856SHelge Deller 	wax->eim = ((u32) wax->gsc_irq.txn_addr) | wax->gsc_irq.txn_data;
961da177e4SLinus Torvalds 
97939fc856SHelge Deller 	ret = request_irq(wax->gsc_irq.irq, gsc_asic_intr, 0, "wax", wax);
981da177e4SLinus Torvalds 	if (ret < 0) {
991da177e4SLinus Torvalds 		kfree(wax);
1001da177e4SLinus Torvalds 		return ret;
1011da177e4SLinus Torvalds 	}
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds 	/* enable IRQ's for devices below WAX */
1041da177e4SLinus Torvalds 	gsc_writel(wax->eim, wax->hpa + OFFSET_IAR);
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds 	/* Done init'ing, register this driver */
1071da177e4SLinus Torvalds 	ret = gsc_common_setup(dev, wax);
1081da177e4SLinus Torvalds 	if (ret) {
1091da177e4SLinus Torvalds 		kfree(wax);
1101da177e4SLinus Torvalds 		return ret;
1111da177e4SLinus Torvalds 	}
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds 	gsc_fixup_irqs(dev, wax, wax_choose_irq);
1141da177e4SLinus Torvalds 	/* On 715-class machines, Wax EISA is a sibling of Wax, not a child. */
1151da177e4SLinus Torvalds 	parent = parisc_parent(dev);
1161da177e4SLinus Torvalds 	if (parent->id.hw_type != HPHW_IOA) {
1171da177e4SLinus Torvalds 		gsc_fixup_irqs(parent, wax, wax_choose_irq);
1181da177e4SLinus Torvalds 	}
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 	return ret;
1211da177e4SLinus Torvalds }
1221da177e4SLinus Torvalds 
123cfe4fbfbSHelge Deller static const struct parisc_device_id wax_tbl[] __initconst = {
1241da177e4SLinus Torvalds 	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e },
1251da177e4SLinus Torvalds 	{ 0, }
1261da177e4SLinus Torvalds };
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds MODULE_DEVICE_TABLE(parisc, wax_tbl);
1291da177e4SLinus Torvalds 
130*ac65d9c9SHelge Deller static struct parisc_driver wax_driver __refdata = {
1311da177e4SLinus Torvalds 	.name =		"wax",
1321da177e4SLinus Torvalds 	.id_table =	wax_tbl,
1331da177e4SLinus Torvalds 	.probe =	wax_init_chip,
1341da177e4SLinus Torvalds };
135*ac65d9c9SHelge Deller 
wax_init(void)136*ac65d9c9SHelge Deller static int __init wax_init(void)
137*ac65d9c9SHelge Deller {
138*ac65d9c9SHelge Deller 	return register_parisc_driver(&wax_driver);
139*ac65d9c9SHelge Deller }
140*ac65d9c9SHelge Deller arch_initcall(wax_init);
141