예제 #1
0
static void eeh_report_error(struct pci_dev *dev, void *userdata)
{
	enum pci_ers_result rc, *res = userdata;
	struct pci_driver *driver = dev->driver;

	dev->error_state = pci_channel_io_frozen;

	if (!driver)
		return;

	if (irq_in_use (dev->irq)) {
		struct device_node *dn = pci_device_to_OF_node(dev);
		PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
		disable_irq_nosync(dev->irq);
	}
	if (!driver->err_handler ||
	    !driver->err_handler->error_detected)
		return;

	rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);

	/* A driver that needs a reset trumps all others */
	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
}
예제 #2
0
int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid)
{
	struct device_node *dp;
	unsigned char *pedid = NULL;
	unsigned char *disptype = NULL;
	static char *propnames[] = {
		"DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
	int i;

	dp = pci_device_to_OF_node(par->pci_dev);
	for (; dp != NULL; dp = dp->child) {
		disptype = (unsigned char *)get_property(dp, "display-type", NULL);
		if (disptype == NULL)
			continue;
		if (strncmp(disptype, "LCD", 3) != 0)
			continue;
		for (i = 0; propnames[i] != NULL; ++i) {
			pedid = (unsigned char *)
				get_property(dp, propnames[i], NULL);
			if (pedid != NULL) {
				*out_edid = pedid;
				return 0;
			}
		}
	}
	return 1;
}
예제 #3
0
static int ohci_rbus_resume (struct usb_hcd *hcd)
{
	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
	int			retval = 0;

#ifdef CONFIG_PMAC_PBOOK
	if (_machine == _MACH_Pmac) {
		struct device_node *of_node;

		/* Re-enable USB PAD & cell clock */
		of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
		if (of_node)
			pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
	}
#endif /* CONFIG_PMAC_PBOOK */

	/* resume root hub */
	if (time_before (jiffies, ohci->next_statechange))
		msleep (100);
#ifdef	CONFIG_USB_SUSPEND
	/* get extra cleanup even if remote wakeup isn't in use */
	retval = usb_resume_device (hcd->self.root_hub);
#else
	usb_lock_device (hcd->self.root_hub);
	retval = ohci_hub_resume (hcd);
	usb_unlock_device (hcd->self.root_hub);
#endif

	return retval;
}
예제 #4
0
파일: siena.c 프로젝트: 383530895/linux
/* When a PCI device is isolated from the bus, a subsequent MMIO read is
 * required for the kernel EEH mechanisms to notice. As the Solarflare driver
 * was written to minimise MMIO read (for latency) then a periodic call to check
 * the EEH status of the device is required so that device recovery can happen
 * in a timely fashion.
 */
static void siena_monitor(struct efx_nic *efx)
{
	struct eeh_dev *eehdev =
		of_node_to_eeh_dev(pci_device_to_OF_node(efx->pci_dev));

	eeh_dev_check_failure(eehdev);
}
예제 #5
0
static int ohci_rbus_suspend (struct usb_hcd *hcd, pm_message_t message)
{
	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);

	/* suspend root hub, hoping it keeps power during suspend */
	if (time_before (jiffies, ohci->next_statechange))
		msleep (100);

#ifdef	CONFIG_USB_SUSPEND
	(void) usb_suspend_device (hcd->self.root_hub, message);
#else
	usb_lock_device (hcd->self.root_hub);
	(void) ohci_hub_suspend (hcd);
	usb_unlock_device (hcd->self.root_hub);
#endif

	/* let things settle down a bit */
	msleep (100);
	
#ifdef CONFIG_PMAC_PBOOK
	if (_machine == _MACH_Pmac) {
	   	struct device_node	*of_node;
 
		/* Disable USB PAD & cell clock */
		of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
		if (of_node)
			pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
	}
#endif /* CONFIG_PMAC_PBOOK */
	return 0;
}
예제 #6
0
static void __devinit apple_kiwi_init(struct pci_dev *pdev)
{
	struct device_node *np = pci_device_to_OF_node(pdev);
	unsigned int class_rev = 0;
	unsigned long mmio;
	u8 conf;

	if (np == NULL || !device_is_compatible(np, "kiwi-root"))
		return;

	pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
	class_rev &= 0xff;

	if (class_rev >= 0x03) {
		/* Setup chip magic config stuff (from darwin) */
		pci_read_config_byte(pdev, 0x40, &conf);
		pci_write_config_byte(pdev, 0x40, conf | 0x01);
	}
	mmio = (unsigned long)ioremap(pci_resource_start(pdev, 5),
				      pci_resource_len(pdev, 5));

	/* Setup some PLL stuffs */
	switch (pdev->device) {
	case PCI_DEVICE_ID_PROMISE_20270:
		writew(0x0d2b, mmio + 0x1202);
		mdelay(30);
		break;
	case PCI_DEVICE_ID_PROMISE_20271:
		writew(0x0826, mmio + 0x1202);
		mdelay(30);
		break;
	}

	iounmap((void *)mmio);
}
예제 #7
0
파일: siena.c 프로젝트: 3null/fastsocket
/* When a PCI device is isolated from the bus, a subsequent MMIO read is
 * required for the kernel EEH mechanisms to notice. As the Solarflare driver
 * was written to minimise MMIO read (for latency) then a periodic call to check
 * the EEH status of the device is required so that device recovery can happen
 * in a timely fashion.
 */
static void siena_monitor(struct efx_nic *efx)
{
	struct pci_dev *pcidev = efx->pci_dev;
	struct device_node *dn = pci_device_to_OF_node(pcidev);

	eeh_dn_check_failure(dn, pcidev);
}
/******************************************************************
 * pci_read_irq_line
 *
 * Reads the Interrupt Pin to determine if interrupt is use by card.
 * If the interrupt is used, then gets the interrupt line from the 
 * openfirmware and sets it in the pci_dev and pci_config line.
 *
 ******************************************************************/
int 
pci_read_irq_line(struct pci_dev *Pci_Dev)
{
	u8 InterruptPin;
	struct device_node *Node;

    	pci_read_config_byte(Pci_Dev, PCI_INTERRUPT_PIN, &InterruptPin);
	if (InterruptPin == 0) {
		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Interrupt used by device.\n",Pci_Dev->slot_name);
		return 0;	
	}

	Node = pci_device_to_OF_node(Pci_Dev);
	if ( Node == NULL) { 
		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s Device Node not found.\n",Pci_Dev->slot_name);
		return -1;	
	}
	if (Node->n_intrs == 0) 	{
		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Device OF interrupts defined.\n",Pci_Dev->slot_name);
		return -1;	
	}
	Pci_Dev->irq = Node->intrs[0].line;

	if (s7a_workaround) {
		if (Pci_Dev->irq > 16)
			Pci_Dev->irq -= 3;
	}

	pci_write_config_byte(Pci_Dev, PCI_INTERRUPT_LINE, Pci_Dev->irq);
	
	PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s pci_dev->irq = 0x%02X\n",Pci_Dev->slot_name,Pci_Dev->irq);
	return 0;
}
예제 #9
0
파일: eeh.c 프로젝트: sarnobat/knoppix
/* Check for an eeh failure at the given token address.
 * The given value has been read and it should be 1's (0xff, 0xffff or
 * 0xffffffff).
 *
 * Probe to determine if an error actually occurred.  If not return val.
 * Otherwise panic.
 */
unsigned long eeh_check_failure(void *token, unsigned long val)
{
	unsigned long addr;
	struct pci_dev *dev;
	struct device_node *dn;
	unsigned long ret, rets[2];

	/* IO BAR access could get us here...or if we manually force EEH
	 * operation on even if the hardware won't support it.
	 */
	if (!eeh_implemented || ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE)
		return val;

	/* Finding the phys addr + pci device is quite expensive.
	 * However, the RTAS call is MUCH slower.... :(
	 */
	addr = eeh_token_to_phys((unsigned long)token);
	dev = pci_find_dev_by_addr(addr);
	if (!dev) {
		printk("EEH: no pci dev found for addr=0x%lx\n", addr);
		return val;
	}
	dn = pci_device_to_OF_node(dev);
	if (!dn) {
		printk("EEH: no pci dn found for addr=0x%lx\n", addr);
		return val;
	}

	/* Access to IO BARs might get this far and still not want checking. */
	if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || dn->eeh_mode & EEH_MODE_NOCHECK)
		return val;


	/* Now test for an EEH failure.  This is VERY expensive.
	 * Note that the eeh_config_addr may be a parent device
	 * in the case of a device behind a bridge, or it may be
	 * function zero of a multi-function device.
	 * In any case they must share a common PHB.
	 */
	if (dn->eeh_config_addr) {
		ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
				dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
		if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
			/*
			 * XXX We should create a separate sysctl for this.
			 *
			 * Since the panic_on_oops sysctl is used to halt
			 * the system in light of potential corruption, we
			 * can use it here.
			 */
			if (panic_on_oops)
				panic("EEH: MMIO failure (%ld) on device:\n%s\n", rets[0], pci_name(dev));
			else
				printk("EEH: MMIO failure (%ld) on device:\n%s\n", rets[0], pci_name(dev));
		}
	}
	eeh_false_positives++;
	return val;	/* good case */

}
static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct device_node* np;
	struct macio_chip* chip;
	
	if (ent->vendor != PCI_VENDOR_ID_APPLE)
		return -ENODEV;

	/* Note regarding refcounting: We assume pci_device_to_OF_node() is
	 * ported to new OF APIs and returns a node with refcount incremented.
	 */
	np = pci_device_to_OF_node(pdev);
	if (np == NULL)
		return -ENODEV;

	/* The above assumption is wrong !!!
	 * fix that here for now until I fix the arch code
	 */
	of_node_get(np);

	/* We also assume that pmac_feature will have done a get() on nodes
	 * stored in the macio chips array
	 */
	chip = macio_find(np, macio_unknown);
       	of_node_put(np);
	if (chip == NULL)
		return -ENODEV;

	/* XXX Need locking ??? */
	if (chip->lbus.pdev == NULL) {
		chip->lbus.pdev = pdev;
		chip->lbus.chip = chip;
		pci_set_drvdata(pdev, &chip->lbus);
		pci_set_master(pdev);
	}

	printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n",
		chip->name);

	/*
	 * HACK ALERT: The WallStreet PowerBook and some OHare based machines
	 * have 2 macio ASICs. I must probe the "main" one first or IDE
	 * ordering will be incorrect. So I put on "hold" the second one since
	 * it seem to appear first on PCI
	 */
	if (chip->type == macio_gatwick || chip->type == macio_ohareII)
		if (macio_chips[0].lbus.pdev == NULL) {
			macio_on_hold = chip;
			return 0;
		}

	macio_pci_add_devices(chip);
	if (macio_on_hold && macio_chips[0].lbus.pdev != NULL) {
		macio_pci_add_devices(macio_on_hold);
		macio_on_hold = NULL;
	}

	return 0;
}
예제 #11
0
파일: eeh_driver.c 프로젝트: 08opt/linux
/**
 * eeh_enable_irq - enable interrupt for the recovering device
 */
static void eeh_enable_irq(struct pci_dev *dev)
{
	struct device_node *dn = pci_device_to_OF_node(dev);

	if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
		PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
		enable_irq(dev->irq);
	}
}
예제 #12
0
int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
{
	struct nvidia_par *par = info->par;
	struct device_node *parent, *dp;
	unsigned char *pedid = NULL;
	static char *propnames[] = {
		"DFP,EDID", "LCD,EDID", "EDID", "EDID1",
		"EDID,B", "EDID,A", NULL };
	int i;

	parent = pci_device_to_OF_node(par->pci_dev);
	if (parent == NULL)
		return -1;
	if (par->twoHeads) {
		char *pname;
		int len;

		for (dp = NULL;
		     (dp = of_get_next_child(parent, dp)) != NULL;) {
			pname = (char *)get_property(dp, "name", NULL);
			if (!pname)
				continue;
			len = strlen(pname);
			if ((pname[len-1] == 'A' && conn == 1) ||
			    (pname[len-1] == 'B' && conn == 2)) {
				for (i = 0; propnames[i] != NULL; ++i) {
					pedid = (unsigned char *)
						get_property(dp, propnames[i],
							     NULL);
					if (pedid != NULL)
						break;
				}
				of_node_put(dp);
				break;
			}
		}
	}
	if (pedid == NULL) {
		for (i = 0; propnames[i] != NULL; ++i) {
			pedid = (unsigned char *)
				get_property(parent, propnames[i], NULL);
			if (pedid != NULL)
				break;
		}
	}
	if (pedid) {
		*out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
		if (*out_edid == NULL)
			return -1;
		memcpy(*out_edid, pedid, EDID_LENGTH);
		printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
		return 0;
	}
	return -1;
}
예제 #13
0
파일: axon_msi.c 프로젝트: DenisLug/mptcp
static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
{
	struct device_node *dn;
	struct msi_desc *entry;
	int len;
	const u32 *prop;

	dn = of_node_get(pci_device_to_OF_node(dev));
	if (!dn) {
		dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n");
		return -ENODEV;
	}

	entry = first_pci_msi_entry(dev);

	for (; dn; dn = of_get_next_parent(dn)) {
		if (entry->msi_attrib.is_64) {
			prop = of_get_property(dn, "msi-address-64", &len);
			if (prop)
				break;
		}

		prop = of_get_property(dn, "msi-address-32", &len);
		if (prop)
			break;
	}

	if (!prop) {
		dev_dbg(&dev->dev,
			"axon_msi: no msi-address-(32|64) properties found\n");
		return -ENOENT;
	}

	switch (len) {
	case 8:
		msg->address_hi = prop[0];
		msg->address_lo = prop[1];
		break;
	case 4:
		msg->address_hi = 0;
		msg->address_lo = prop[0];
		break;
	default:
		dev_dbg(&dev->dev,
			"axon_msi: malformed msi-address-(32|64) property\n");
		of_node_put(dn);
		return -EINVAL;
	}

	of_node_put(dn);

	return 0;
}
예제 #14
0
static void apple_kiwi_init(struct pci_dev *pdev)
{
	struct device_node *np = pci_device_to_OF_node(pdev);
	u8 conf;

	if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
		return;

	if (pdev->revision >= 0x03) {
		/* Setup chip magic config stuff (from darwin) */
		pci_read_config_byte (pdev, 0x40, &conf);
		pci_write_config_byte(pdev, 0x40, (conf | 0x01));
	}
}
예제 #15
0
파일: chrp_pci.c 프로젝트: TitaniumBoy/lin
void __init
chrp_pcibios_fixup(void)
{
	struct pci_dev *dev;
	struct device_node *np;

	/* PCI interrupts are controlled by the OpenPIC */
	pci_for_each_dev(dev) {
		np = pci_device_to_OF_node(dev);
		if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
			dev->irq = np->intrs[0].line;
		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
	}
}
예제 #16
0
파일: shadowof.c 프로젝트: 168519/linux
static void *
of_init(struct nvkm_bios *bios, const char *name)
{
	struct pci_dev *pdev = nv_device(bios)->pdev;
	struct device_node *dn;
	struct priv *priv;
	if (!(dn = pci_device_to_OF_node(pdev)))
		return ERR_PTR(-ENODEV);
	if (!(priv = kzalloc(sizeof(*priv), GFP_KERNEL)))
		return ERR_PTR(-ENOMEM);
	if ((priv->data = of_get_property(dn, "NVDA,BMP", &priv->size)))
		return priv;
	kfree(priv);
	return ERR_PTR(-EINVAL);
}
예제 #17
0
파일: axon_msi.c 프로젝트: DenisLug/mptcp
static struct axon_msic *find_msi_translator(struct pci_dev *dev)
{
	struct irq_domain *irq_domain;
	struct device_node *dn, *tmp;
	const phandle *ph;
	struct axon_msic *msic = NULL;

	dn = of_node_get(pci_device_to_OF_node(dev));
	if (!dn) {
		dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n");
		return NULL;
	}

	for (; dn; dn = of_get_next_parent(dn)) {
		ph = of_get_property(dn, "msi-translator", NULL);
		if (ph)
			break;
	}

	if (!ph) {
		dev_dbg(&dev->dev,
			"axon_msi: no msi-translator property found\n");
		goto out_error;
	}

	tmp = dn;
	dn = of_find_node_by_phandle(*ph);
	of_node_put(tmp);
	if (!dn) {
		dev_dbg(&dev->dev,
			"axon_msi: msi-translator doesn't point to a node\n");
		goto out_error;
	}

	irq_domain = irq_find_host(dn);
	if (!irq_domain) {
		dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n",
			dn->full_name);
		goto out_error;
	}

	msic = irq_domain->host_data;

out_error:
	of_node_put(dn);

	return msic;
}
예제 #18
0
파일: eeh_driver.c 프로젝트: 08opt/linux
/**
 * eeh_disable_irq - disable interrupt for the recovering device
 */
static void eeh_disable_irq(struct pci_dev *dev)
{
	struct device_node *dn = pci_device_to_OF_node(dev);

	/* Don't disable MSI and MSI-X interrupts. They are
	 * effectively disabled by the DMA Stopped state
	 * when an EEH error occurs.
	*/
	if (dev->msi_enabled || dev->msix_enabled)
		return;

	if (!irq_has_action(dev->irq))
		return;

	PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
	disable_irq_nosync(dev->irq);
}
예제 #19
0
static int hcd_pci_suspend_noirq(struct device *dev)
{
	struct pci_dev		*pci_dev = to_pci_dev(dev);
	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev);
	int			retval;

	retval = check_root_hub_suspended(dev);
	if (retval)
		return retval;

	pci_save_state(pci_dev);

	/* If the root hub is HALTed rather than SUSPENDed,
	 * disallow remote wakeup.
	 */
	if (hcd->state == HC_STATE_HALT)
		device_set_wakeup_enable(dev, 0);
	dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev));

	/* Possibly enable remote wakeup,
	 * choose the appropriate low-power state, and go to that state.
	 */
	retval = pci_prepare_to_sleep(pci_dev);
	if (retval == -EIO) {		/* Low-power not supported */
		dev_dbg(dev, "--> PCI D0 legacy\n");
		retval = 0;
	} else if (retval == 0) {
		dev_dbg(dev, "--> PCI %s\n",
				pci_power_name(pci_dev->current_state));
	} else {
		suspend_report_result(pci_prepare_to_sleep, retval);
		return retval;
	}

#ifdef CONFIG_PPC_PMAC
	/* Disable ASIC clocks for USB */
	if (machine_is(powermac)) {
		struct device_node	*of_node;

		of_node = pci_device_to_OF_node(pci_dev);
		if (of_node)
			pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
	}
#endif
	return retval;
}
예제 #20
0
static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
					  u8 **out_EDID)
{
        struct device_node *dp;

	RTRACE("radeon_probe_OF_head\n");

        dp = pci_device_to_OF_node(rinfo->pdev);
        while (dp == NULL)
		return MT_NONE;

	if (rinfo->has_CRTC2) {
		char *pname;
		int len, second = 0;

		dp = dp->child;
		do {
			if (!dp)
				return MT_NONE;
			pname = (char *)get_property(dp, "name", NULL);
			if (!pname)
				return MT_NONE;
			len = strlen(pname);
			RTRACE("head: %s (letter: %c, head_no: %d)\n",
			       pname, pname[len-1], head_no);
			if (pname[len-1] == 'A' && head_no == 0) {
				int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
				/* Maybe check for LVDS_GEN_CNTL here ? I need to check out
				 * what OF does when booting with lid closed
				 */
				if (mt == MT_DFP && rinfo->is_mobility)
					mt = MT_LCD;
				return mt;
			} else if (pname[len-1] == 'B' && head_no == 1)
				return radeon_parse_montype_prop(dp, out_EDID, 1);
			second = 1;
			dp = dp->sibling;
		} while(!second);
	} else {
		if (head_no > 0)
			return MT_NONE;
		return radeon_parse_montype_prop(dp, out_EDID, -1);
	}
        return MT_NONE;
}
예제 #21
0
/* first module load, setup the mmio/fb mapping */
int nouveau_firstopen(struct drm_device *dev)
{
#if defined(__powerpc__)
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct device_node *dn;
#endif
	int ret;
	/* Map any PCI resources we need on the card */
	ret = nouveau_init_card_mappings(dev);
	if (ret) return ret;

#if defined(__powerpc__)
	/* Put the card in BE mode if it's not */
	if (NV_READ(NV03_PMC_BOOT_1))
		NV_WRITE(NV03_PMC_BOOT_1,0x00000001);

	DRM_MEMORYBARRIER();
#endif

#if defined(__linux__) && defined(__powerpc__)
	/* if we have an OF card, copy vbios to RAMIN */
	dn = pci_device_to_OF_node(dev->pdev);
	if (dn)
	{
		int size;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
		const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size);
#else
		const uint32_t *bios = get_property(dn, "NVDA,BMP", &size);
#endif
		if (bios)
		{
			int i;
			for(i=0;i<size;i+=4)
				NV_WI32(i, bios[i/4]);
			DRM_INFO("OF bios successfully copied (%d bytes)\n",size);
		}
		else
			DRM_INFO("Unable to get the OF bios\n");
	}
	else
		DRM_INFO("Unable to get the OF node\n");
#endif
	return 0;
}
예제 #22
0
static void __devinit apple_kiwi_init(struct pci_dev *pdev)
{
	struct device_node *np = pci_device_to_OF_node(pdev);
	unsigned int class_rev = 0;
	u8 conf;

	if (np == NULL || !device_is_compatible(np, "kiwi-root"))
		return;

	pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
	class_rev &= 0xff;

	if (class_rev >= 0x03) {
		/* Setup chip magic config stuff (from darwin) */
		pci_read_config_byte (pdev, 0x40, &conf);
		pci_write_config_byte(pdev, 0x40, (conf | 0x01));
	}
}
예제 #23
0
static void eeh_report_reset(struct pci_dev *dev, void *userdata)
{
	struct pci_driver *driver = dev->driver;
	struct device_node *dn = pci_device_to_OF_node(dev);

	if (!driver)
		return;

	if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
		PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
		enable_irq(dev->irq);
	}
	if (!driver->err_handler)
		return;
	if (!driver->err_handler->slot_reset)
		return;

	driver->err_handler->slot_reset(dev);
}
예제 #24
0
/**
 * eeh_check_failure - check if all 1's data is due to EEH slot freeze
 * @token i/o token, should be address in the form 0xA....
 * @val value, should be all 1's (XXX why do we need this arg??)
 *
 * Check for an EEH failure at the given token address.  Call this
 * routine if the result of a read was all 0xff's and you want to
 * find out if this is due to an EEH slot freeze event.  This routine
 * will query firmware for the EEH status.
 *
 * Note this routine is safe to call in an interrupt context.
 */
unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
{
	unsigned long addr;
	struct pci_dev *dev;
	struct device_node *dn;

	/* Finding the phys addr + pci device; this is pretty quick. */
	addr = eeh_token_to_phys((unsigned long __force) token);
	dev = pci_get_device_by_addr(addr);
	if (!dev) {
		no_device++;
		return val;
	}

	dn = pci_device_to_OF_node(dev);
	eeh_dn_check_failure (dn, dev);

	pci_dev_put(dev);
	return val;
}
예제 #25
0
static int rtas_pci_write_config(struct pci_bus *bus,
				 unsigned int devfn,
				 int where, int size, u32 val)
{
	struct device_node *busdn, *dn;

	if (bus->self)
		busdn = pci_device_to_OF_node(bus->self);
	else
		busdn = bus->sysdata;	/* must be a phb */

	/* Search only direct children of the bus */
	for (dn = busdn->child; dn; dn = dn->sibling) {
		struct pci_dn *pdn = PCI_DN(dn);
		if (pdn && pdn->devfn == devfn
		    && of_device_available(dn))
			return rtas_write_config(pdn, where, size, val);
	}
	return PCIBIOS_DEVICE_NOT_FOUND;
}
예제 #26
0
static void eeh_report_failure(struct pci_dev *dev, void *userdata)
{
	struct pci_driver *driver = dev->driver;

	dev->error_state = pci_channel_io_perm_failure;

	if (!driver)
		return;

	if (irq_in_use (dev->irq)) {
		struct device_node *dn = pci_device_to_OF_node(dev);
		PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
		disable_irq_nosync(dev->irq);
	}
	if (!driver->err_handler)
		return;
	if (!driver->err_handler->error_detected)
		return;
	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
}
예제 #27
0
static void eeh_report_resume(struct pci_dev *dev, void *userdata)
{
	struct pci_driver *driver = dev->driver;
	struct device_node *dn = pci_device_to_OF_node(dev);

	dev->error_state = pci_channel_io_normal;

	if (!driver)
		return;

	if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
		PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
		enable_irq(dev->irq);
	}
	if (!driver->err_handler ||
	    !driver->err_handler->resume)
		return;

	driver->err_handler->resume(dev);
}
예제 #28
0
static int hcd_pci_resume_noirq(struct device *dev)
{
	struct pci_dev		*pci_dev = to_pci_dev(dev);

#ifdef CONFIG_PPC_PMAC
	/* Reenable ASIC clocks for USB */
	if (machine_is(powermac)) {
		struct device_node *of_node;

		of_node = pci_device_to_OF_node(pci_dev);
		if (of_node)
			pmac_call_feature(PMAC_FTR_USB_ENABLE,
						of_node, 0, 1);
	}
#endif

	/* Go back to D0 and disable remote wakeup */
	pci_back_from_sleep(pci_dev);
	return 0;
}
예제 #29
0
static void *map_onedev(struct pci_dev *p, int index)
{
	struct device_node *dn;
	void __iomem *ret;

	dn = pci_device_to_OF_node(p);
	if (!dn)
		goto fallback;

	ret = of_iomap(dn, index);
	if (!ret)
		goto fallback;

	return ret;
fallback:
	/* This is hardcoded and ugly, but we have some firmware versions
	 * that don't provide the register space in the device tree. Luckily
	 * they are at well-known locations so we can just do the math here.
	 */
	return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
}
예제 #30
0
/* if we have an OF card, copy vbios to RAMIN */
static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
{
#if defined(__powerpc__)
    int size, i;
    const uint32_t *bios;
    struct device_node *dn = pci_device_to_OF_node(dev->pdev);
    if (!dn) {
        NV_INFO(dev, "Unable to get the OF node\n");
        return;
    }

    bios = of_get_property(dn, "NVDA,BMP", &size);
    if (bios) {
        for (i = 0; i < size; i += 4)
            nv_wi32(dev, i, bios[i/4]);
        NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
    } else {
        NV_INFO(dev, "Unable to get the OF bios\n");
    }
#endif
}