static void ti12xx_irqroute_func0()

in ti113x.h [367:478]


static void ti12xx_irqroute_func0(struct yenta_socket *socket)
{
	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);
	dev_info(&socket->dev->dev, "TI: mfunc 0x%08x, devctl 0x%02x\n",
		 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)
	 */
	dev_info(&socket->dev->dev,
		 "TI: probing PCI interrupt failed, trying to fix\n");

	/* 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) {
					dev_info(&socket->dev->dev,
						 "TI: all-serial interrupts ok\n");
					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 */
		dev_info(&socket->dev->dev,
			 "TI: falling back to parallel PCI interrupts\n");
		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;
		dev_info(&socket->dev->dev, "TI: parallel PCI interrupts ok\n");
	} 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;
		dev_info(&socket->dev->dev,
			 "Yenta TI: no PCI interrupts. Fish. Please report.\n");
	}
}