⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocp.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	up_read(&ocp_devices_sem);	return dev;}/** *	ocp_get_one_device -	Find a def by function & index *      @vendor: vendor ID of the device (or OCP_ANY_ID) *	@function: function code of the device (or OCP_ANY_ID) *	@idx: index of the device (or OCP_ANY_INDEX) * *	This function allows a lookup of a given ocp_def by it's *	vendor, function, and index.  The main purpose for is to *	allow modification of the def before binding to the driver */struct ocp_def *ocp_get_one_device(unsigned int vendor, unsigned int function, int index){	struct ocp_device	*dev;	struct ocp_def		*found = NULL;	DBG(("ocp: ocp_get_one_device(vendor: %x, function: %x, index: %d)...\n",		vendor, function, index));	dev = ocp_find_device(vendor, function, index);	if (dev) 		found = dev->def;	DBG(("ocp: ocp_get_one_device(vendor: %x, function: %x, index: %d)... done.\n",		vendor, function, index));	return found;}/** *	ocp_add_one_device	-	Add a device *	@def: static device definition structure * *	This function adds a device definition to the *	device list. It may only be called before *	ocp_driver_init() and will return an error *	otherwise. */intocp_add_one_device(struct ocp_def *def){	struct	ocp_device	*dev;	DBG(("ocp: ocp_add_one_device(vendor: %x, function: %x, index: %d)...\n", vendor, function, index));	/* Can't be called after ocp driver init */	if (ocp_inited)		return 1;	if (mem_init_done)		dev = kmalloc(sizeof(*dev), GFP_KERNEL);	else		dev = alloc_bootmem(sizeof(*dev));	if (dev == NULL)		return 1;	memset(dev, 0, sizeof(*dev));	dev->def = def;	dev->current_state = 4;	sprintf(dev->name, "OCP device %04x:%04x:%04x",		dev->def->vendor, dev->def->function, dev->def->index);	down_write(&ocp_devices_sem);	list_add_tail(&dev->link, &ocp_devices);	up_write(&ocp_devices_sem);	DBG(("ocp: ocp_add_one_device(vendor: %x, function: %x, index: %d)...done.\n", vendor, function, index));	return 0;}/** *	ocp_remove_one_device -	Remove a device by function & index *      @vendor: vendor ID of the device (or OCP_ANY_ID) *	@function: function code of the device (or OCP_ANY_ID) *	@idx: index of the device (or OCP_ANY_INDEX) * *	This function allows removal of a given function by its *	index. It may only be called before ocp_driver_init() *	and will return an error otherwise. */intocp_remove_one_device(unsigned int vendor, unsigned int function, int index){	struct ocp_device *dev;	int	rc = 0;	DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)...\n", vendor, function, index));	/* Can't be called after ocp driver init */	if (ocp_inited)		return 1;	down_write(&ocp_devices_sem);	dev = __ocp_find_device(vendor, function, index);	if (dev != NULL)		list_del((struct list_head *)dev);	else		rc = 1;	up_write(&ocp_devices_sem);	DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index));	return rc;}#ifdef CONFIG_PM/** * OCP Power management.. * * This needs to be done centralized, so that we power manage PCI * devices in the right order: we should not shut down PCI bridges * before we've shut down the devices behind them, and we should * not wake up devices before we've woken up the bridge to the * device.. Eh? * * We do not touch devices that don't have a driver that exports * a suspend/resume function. That is just too dangerous. If the default * PCI suspend/resume functions work for a device, the driver can * easily implement them (ie just have a suspend function that calls * the pci_set_power_state() function). * * BenH: Implementation here couldn't work properly. This version *       slightly modified and _might_ be more useable, but real *       PM support will probably have to wait for 2.5 */static int ocp_pm_save_state_device(struct ocp_device *dev, u32 state){	int error = 0;	if (dev) {		struct ocp_driver *driver = dev->driver;		if (driver && driver->save_state)			error = driver->save_state(dev,state);	}	return error;}static int ocp_pm_suspend_device(struct ocp_device *dev, u32 state){	int error = 0;	if (dev) {		struct ocp_driver *driver = dev->driver;		if (driver && driver->suspend)			error = driver->suspend(dev,state);	}	return error;}static int ocp_pm_resume_device(struct ocp_device *dev){	int error = 0;	if (dev) {		struct ocp_driver *driver = dev->driver;		if (driver && driver->resume)			error = driver->resume(dev);	}	return error;}static intocp_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data){	int error = 0;	struct list_head	*entry;	struct ocp_device	*dev;	down(&ocp_drivers_sem);	down_read(&ocp_devices_sem);	list_for_each(entry, &ocp_devices) {		dev = list_entry(entry, struct ocp_device, link);		switch (rqst) {		case PM_SAVE_STATE:			error = ocp_pm_save_state_device(dev, 3);			break;		case PM_SUSPEND:			error = ocp_pm_suspend_device(dev, 3);			break;		case PM_RESUME:			error = ocp_pm_resume_device(dev);			break;		default: break;		}		if (error)			break;	}	return error;}/* * Is this ever used ? */voidppc4xx_cpm_fr(u32 bits, int val){	unsigned long flags;	save_flags(flags);	cli();	if (val)		mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | bits);	else		mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~bits);	restore_flags(flags);}#endif /* CONFIG_PM *//** *	ocp_early_init	-	Init OCP device management * *	This function builds the list of devices before setup_arch.  *	This allows platform code to modify the device lists before *	they are bound to drivers (changes to paddr, removing devices *	etc) */int __initocp_early_init(void){	struct ocp_def	*def;	DBG(("ocp: ocp_early_init()...\n"));	/* Fill the devices list */	for (def = core_ocp; def->vendor != OCP_VENDOR_INVALID; def++)		ocp_add_one_device(def);	DBG(("ocp: ocp_early_init()... done.\n"));	return 0;}/** *	ocp_driver_init	-	Init OCP device management * *	This function is meant to be called once, and only once to initialize *	the OCP device management. Note that it can actually be called at any  *	time, it's perfectly legal to register drivers before  *	ocp_driver_init() is called */intocp_driver_init(void){	/* ocp_driver_init is by default an initcall. If your arch requires 	 * this to be called earlier, then go on, ocp_driver_init is 	 * non-static for that purpose, and can safely be called twice	 */	if (ocp_inited)		return 0;	ocp_inited = 1;	DBG(("ocp: ocp_driver_init()...\n"));	/* Call drivers probes */	down(&ocp_drivers_sem);	ocp_bind_drivers(NULL);	up(&ocp_drivers_sem);#ifdef CONFIG_PM	pm_register(PM_SYS_DEV, 0, ocp_pm_callback);#endif	DBG(("ocp: ocp_driver_init()... done.\n"));	return 0;}__initcall(ocp_driver_init);EXPORT_SYMBOL(ocp_find_device);EXPORT_SYMBOL(ocp_register_driver);EXPORT_SYMBOL(ocp_unregister_driver);

⌨️ 快捷键说明

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