ti113x.h

来自「Linux Kernel 2.6.9 for OMAP1710」· C头文件 代码 · 共 657 行 · 第 1/2 页

H
657
字号
{	u32 mfunc, mfunc_old, devctl;	u8 gpio3, gpio3_old;	int pci_irq_status;	mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);	printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",	       pci_name(socket->dev), mfunc, devctl);	/* make sure PCI interrupts are enabled before probing */	ti_init(socket);	/* test PCI interrupts first. only try fixing if return value is 0! */	pci_irq_status = yenta_probe_cb_irq(socket);	if (pci_irq_status)		goto out;	/*	 * We're here which means PCI interrupts are _not_ delivered. try to	 * find the right setting (all serial or parallel)	 */	printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",	       pci_name(socket->dev));	/* for serial PCI make sure MFUNC3 is set to IRQSER */	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {		switch (socket->dev->device) {		case PCI_DEVICE_ID_TI_1250:		case PCI_DEVICE_ID_TI_1251A:		case PCI_DEVICE_ID_TI_1251B:		case PCI_DEVICE_ID_TI_1450:		case PCI_DEVICE_ID_TI_1451A:		case PCI_DEVICE_ID_TI_4450:		case PCI_DEVICE_ID_TI_4451:			/* these chips have no IRQSER setting in MFUNC3  */			break;		default:			mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER;			/* write down if changed, probe */			if (mfunc != mfunc_old) {				config_writel(socket, TI122X_MFUNC, mfunc);				pci_irq_status = yenta_probe_cb_irq(socket);				if (pci_irq_status == 1) {					printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts ok\n",					       pci_name(socket->dev));					mfunc_old = mfunc;					goto out;				}				/* not working, back to old value */				mfunc = mfunc_old;				config_writel(socket, TI122X_MFUNC, mfunc);				if (pci_irq_status == -1)					goto out;			}		}		/* serial PCI interrupts not working fall back to parallel */		printk(KERN_INFO "Yenta TI: socket %s falling back to parallel PCI interrupts\n",		       pci_name(socket->dev));		devctl &= ~TI113X_DCR_IMODE_MASK;		devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */		config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);	}	/* parallel PCI interrupts: route INTA */	switch (socket->dev->device) {	case PCI_DEVICE_ID_TI_1250:	case PCI_DEVICE_ID_TI_1251A:	case PCI_DEVICE_ID_TI_1251B:	case PCI_DEVICE_ID_TI_1450:		/* make sure GPIO3 is set to INTA */		gpio3 = gpio3_old = config_readb(socket, TI1250_GPIO3_CONTROL);		gpio3 &= ~TI1250_GPIO_MODE_MASK;		if (gpio3 != gpio3_old)			config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3);		break;	default:		gpio3 = gpio3_old = 0;		mfunc = (mfunc & ~TI122X_MFUNC0_MASK) | TI122X_MFUNC0_INTA;		if (mfunc != mfunc_old)			config_writel(socket, TI122X_MFUNC, mfunc);	}	/* time to probe again */	pci_irq_status = yenta_probe_cb_irq(socket);	if (pci_irq_status == 1) {		mfunc_old = mfunc;		printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",		       pci_name(socket->dev));	} else {		/* not working, back to old value */		mfunc = mfunc_old;		config_writel(socket, TI122X_MFUNC, mfunc);		if (gpio3 != gpio3_old)			config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3_old);	}out:	if (pci_irq_status < 1) {		socket->cb_irq = 0;		printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",		       pci_name(socket->dev));	}}/* * ties INTA and INTB together. also changes the devices irq to that of * the function 0 device. call from func1 only. * returns 1 if INTRTIE changed, 0 otherwise. */static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq){	struct pci_dev *func0;	u32 sysctl;	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);	if (sysctl & TI122X_SCR_INTRTIE)		return 0;	/* find func0 device */	func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);	if (!func0)		return 0;	/* change the interrupt to match func0, tie 'em up */	*old_irq = socket->cb_irq;	socket->cb_irq = socket->dev->irq = func0->irq;	sysctl |= TI122X_SCR_INTRTIE;	config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);	pci_dev_put(func0);	return 1;}/* undo what ti12xx_tie_interrupts() did */static void ti12xx_untie_interrupts(struct yenta_socket *socket, int old_irq){	u32 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);	sysctl &= ~TI122X_SCR_INTRTIE;	config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);	socket->cb_irq = socket->dev->irq = old_irq;}/*  * irqrouting for func1, plays with INTB routing * only touches MFUNC for INTB routing. all other bits are taken * care of in func0 already. */static void ti12xx_irqroute_func1(struct yenta_socket *socket){	u32 mfunc, mfunc_old, devctl;	int pci_irq_status;	mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);	printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",	       pci_name(socket->dev), mfunc, devctl);	/* make sure PCI interrupts are enabled before probing */	ti_init(socket);	/* test PCI interrupts first. only try fixing if return value is 0! */	pci_irq_status = yenta_probe_cb_irq(socket);	if (pci_irq_status)		goto out;	/*	 * We're here which means PCI interrupts are _not_ delivered. try to	 * find the right setting	 */	printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",	       pci_name(socket->dev));	/* if all serial: set INTRTIE, probe again */	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {		int old_irq;		if (ti12xx_tie_interrupts(socket, &old_irq)) {			pci_irq_status = yenta_probe_cb_irq(socket);			if (pci_irq_status == 1) {				printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts, tied ok\n",				       pci_name(socket->dev));				goto out;			}			ti12xx_untie_interrupts(socket, old_irq);		}	}	/* parallel PCI: route INTB, probe again */	else {		int old_irq;		switch (socket->dev->device) {		case PCI_DEVICE_ID_TI_1250:			/* the 1250 has one pin for IRQSER/INTB depending on devctl */			break;		case PCI_DEVICE_ID_TI_1251A:		case PCI_DEVICE_ID_TI_1251B:		case PCI_DEVICE_ID_TI_1450:			/*			 *  those have a pin for IRQSER/INTB plus INTB in MFUNC0			 *  we alread probed the shared pin, now go for MFUNC0			 */			mfunc = (mfunc & ~TI122X_MFUNC0_MASK) | TI125X_MFUNC0_INTB;			break;		default:			mfunc = (mfunc & ~TI122X_MFUNC1_MASK) | TI122X_MFUNC1_INTB;			break;		}		/* write, probe */		if (mfunc != mfunc_old) {			config_writel(socket, TI122X_MFUNC, mfunc);			pci_irq_status = yenta_probe_cb_irq(socket);			if (pci_irq_status == 1) {				printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",				       pci_name(socket->dev));				goto out;			}			mfunc = mfunc_old;			config_writel(socket, TI122X_MFUNC, mfunc);			if (pci_irq_status == -1)				goto out;		}				/* still nothing: set INTRTIE */		if (ti12xx_tie_interrupts(socket, &old_irq)) {			pci_irq_status = yenta_probe_cb_irq(socket);			if (pci_irq_status == 1) {				printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts, tied ok\n",				       pci_name(socket->dev));				goto out;			}			ti12xx_untie_interrupts(socket, old_irq);		}	}out:	if (pci_irq_status < 1) {		socket->cb_irq = 0;		printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",		       pci_name(socket->dev));	}}static int ti12xx_override(struct yenta_socket *socket){	u32 val;	/* make sure that memory burst is active */	val = config_readl(socket, TI113X_SYSTEM_CONTROL);	if (!(val & TI122X_SCR_MRBURSTUP)) {		printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");		val |= TI122X_SCR_MRBURSTUP;		config_writel(socket, TI113X_SYSTEM_CONTROL, val);	}	/*	 * for EnE bridges only: clear testbit TLTEnable. this makes the	 * RME Hammerfall DSP sound card working.	 */	if (socket->dev->vendor == PCI_VENDOR_ID_ENE) {		u8 test_c9 = config_readb(socket, ENE_TEST_C9);		test_c9 &= ~ENE_TEST_C9_TLTENABLE;		config_writeb(socket, ENE_TEST_C9, test_c9);	}	/*	 * Yenta expects controllers to use CSCINT to route	 * CSC interrupts to PCI rather than INTVAL.	 */	val = config_readb(socket, TI1250_DIAGNOSTIC);	printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n",		(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");	printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",		(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");	/* do irqrouting, depending on function */	if (PCI_FUNC(socket->dev->devfn) == 0)		ti12xx_irqroute_func0(socket);	else		ti12xx_irqroute_func1(socket);	return ti_override(socket);}static int ti1250_override(struct yenta_socket *socket){	u8 old, diag;	old = config_readb(socket, TI1250_DIAGNOSTIC);	diag = old & ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);	if (socket->cb_irq)		diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;	if (diag != old) {		printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n",			old, diag);		config_writeb(socket, TI1250_DIAGNOSTIC, diag);	}	return ti12xx_override(socket);}#endif /* CONFIG_CARDBUS */#endif /* _LINUX_TI113X_H */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?