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

📄 feature.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}#endif}static struct feature_controller*feature_add_controller(struct device_node *controller_device, fbit* bits){	struct feature_controller*	controller;		if (controller_count >= MAX_FEATURE_CONTROLLERS) {		printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n",			controller_device->full_name, MAX_FEATURE_CONTROLLERS);		return NULL;	}	controller = &controllers[controller_count];	controller->bits	= bits;	controller->device	= controller_device;	if (controller_device->n_addrs == 0) {		printk(KERN_ERR "No addresses for %s\n",			controller_device->full_name);		return NULL;	}	controller->reg		= (volatile u32 *)ioremap(		controller_device->addrs[0].address, MAX_FEATURE_OFFSET);	if (bits == NULL) {		printk(KERN_INFO "Twiddling the magic ohare bits\n");		out_le32(FREG(controller,OHARE_FEATURE_REG), STARMAX_FEATURES);		return NULL;	}	spin_lock_init(&controller->lock);	controller_count++;	return controller;}static struct feature_controller*feature_lookup_controller(struct device_node *device){	int	i;		if (device == NULL)		return NULL;			while(device)	{		for (i=0; i<controller_count; i++)			if (device == controllers[i].device)				return &controllers[i];		device = device->parent;	}#ifdef DEBUG_FEATURE	printk("feature: <%s> not found on any controller\n",		device->name);#endif		return NULL;}intfeature_set(struct device_node* device, enum system_feature f){	struct feature_controller*	controller;	unsigned long			flags;	unsigned long			value;	fbit*				bit;	if (f >= FEATURE_last)		return -EINVAL;		controller = feature_lookup_controller(device);	if (!controller)		return -ENODEV;	bit = &controller->bits[f];	if (!bit->mask)		return -EINVAL;	#ifdef DEBUG_FEATURE	printk("feature: <%s> setting feature %d in controller @0x%x\n",		device->name, (int)f, (unsigned int)controller->reg);#endif	spin_lock_irqsave(&controller->lock, flags);	value = in_le32(FREG(controller, bit->reg));	value = bit->polarity ? (value & ~bit->mask) : (value | bit->mask);	out_le32(FREG(controller, bit->reg), value);	(void)in_le32(FREG(controller, bit->reg));	spin_unlock_irqrestore(&controller->lock, flags);		return 0;}intfeature_clear(struct device_node* device, enum system_feature f){	struct feature_controller*	controller;	unsigned long			flags;	unsigned long			value;	fbit*				bit;	if (f >= FEATURE_last)		return -EINVAL;		controller = feature_lookup_controller(device);	if (!controller)		return -ENODEV;	bit = &controller->bits[f];	if (!bit->mask)		return -EINVAL;	#ifdef DEBUG_FEATURE	printk("feature: <%s> clearing feature %d in controller @0x%x\n",		device->name, (int)f, (unsigned int)controller->reg);#endif	spin_lock_irqsave(&controller->lock, flags);	value = in_le32(FREG(controller, bit->reg));	value = bit->polarity ? (value | bit->mask) : (value & ~bit->mask);	out_le32(FREG(controller, bit->reg), value);	(void)in_le32(FREG(controller, bit->reg));	spin_unlock_irqrestore(&controller->lock, flags);		return 0;}intfeature_test(struct device_node* device, enum system_feature f){	struct feature_controller*	controller;	unsigned long			value;	fbit*				bit;	if (f >= FEATURE_last)		return -EINVAL;		controller = feature_lookup_controller(device);	if (!controller)		return -ENODEV;	bit = &controller->bits[f];	if (!bit->mask)		return -EINVAL;	#ifdef DEBUG_FEATURE	printk("feature: <%s> clearing feature %d in controller @0x%x\n",		device->name, (int)f, (unsigned int)controller->reg);#endif	/* If one feature contains several bits, all of them must be set	 * for value to be true, or all of them must be 0 if polarity is	 * inverse	 */	value = (in_le32(FREG(controller, bit->reg)) & bit->mask);	return bit->polarity ? (value == 0) : (value == bit->mask);}/* * Core99 functions *  * Note: We currently assume there is _one_ UniN chip and _one_ KeyLargo *       chip, which is the case on all Core99 machines so far *//* Only one GMAC is assumed */voidfeature_set_gmac_power(struct device_node* device, int power){	if (!uninorth_base)		return;	if (power)		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);	else		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);	udelay(20);}voidfeature_set_gmac_phy_reset(struct device_node* device, int reset){	if (!keylargo_base)		return;	out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), reset);	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));}/* Pass the node of the correct controller, please */voidfeature_set_usb_power(struct device_node* device, int power){}/* Not yet implemented */void feature_set_firewire_power(struct device_node* device, int power){}/* Initialize the Core99 UniNorth host bridge and memory controller */static voiduninorth_init(void){	struct device_node* gmac;	unsigned long actrl;		/* Set the arbitrer QAck delay according to what Apple does	 */	actrl = in_be32(UN_REG(UNI_N_ARB_CTRL)) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;	actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY)		<< UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;	UN_OUT(UNI_N_ARB_CTRL, actrl);		/* 	 * Turns OFF the gmac clock. The gmac driver will turn	 * it back ON when the interface is enabled. This save	 * power on portables.	 * 	 * Note: We could also try to turn OFF the PHY. Since this	 * has to be done by both the gmac driver and this code,	 * I'll probably end-up moving some of this out of the	 * modular gmac driver into a non-modular stub containing	 * some basic PHY management and power management stuffs	 */	gmac = find_devices("ethernet");	while(gmac) {		if (device_is_compatible(gmac, "gmac"))			break;		gmac = gmac->next;	}	if (gmac)		feature_set_gmac_power(gmac, 0);}/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure * OpenPIC is enabled */static voidkeylargo_init(void){	KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE);}#ifdef CONFIG_PMAC_PBOOKvoidfeature_prepare_for_sleep(void){	/* We assume gatwick is second */	struct feature_controller* ctrler = &controllers[0];	if (!ctrler)		return;	if (controller_count > 1 &&		device_is_compatible(ctrler->device, "gatwick"))		ctrler = &controllers[1];	if (ctrler->bits == feature_bits_heathrow ||		ctrler->bits == feature_bits_paddington) {		heathrow_prepare_for_sleep(ctrler);		return;	}	if (ctrler->bits == feature_bits_keylargo) {		core99_prepare_for_sleep(ctrler);		return;	}}voidfeature_wake_up(void){	struct feature_controller* ctrler = &controllers[0];	if (!ctrler)		return;	if (controller_count > 1 &&		device_is_compatible(ctrler->device, "gatwick"))		ctrler = &controllers[1];		if (ctrler->bits == feature_bits_heathrow ||		ctrler->bits == feature_bits_paddington) {		heathrow_wakeup(ctrler);		return;	}	if (ctrler->bits == feature_bits_keylargo) {		core99_wake_up(ctrler);		return;	}}static u32 save_fcr[5];static u32 save_mbcr;static voidheathrow_prepare_for_sleep(struct feature_controller* ctrler){	save_mbcr = in_le32(FREG(ctrler, 0x34));	save_fcr[0] = in_le32(FREG(ctrler, 0x38));	save_fcr[1] = in_le32(FREG(ctrler, 0x3c));	out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE);}static voidheathrow_wakeup(struct feature_controller* ctrler){	out_le32(FREG(ctrler, 0x38), save_fcr[0]);	out_le32(FREG(ctrler, 0x3c), save_fcr[1]);	out_le32(FREG(ctrler, 0x34), save_mbcr);	mdelay(1);	out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE);	mdelay(1);}static voidcore99_prepare_for_sleep(struct feature_controller* ctrler){	/* Not yet implemented */}static voidcore99_wake_up(struct feature_controller* ctrler){	/* Not yet implemented */}#endif /* CONFIG_PMAC_PBOOK */

⌨️ 快捷键说明

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