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

📄 open_pic2.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
{	DECL_THIS_CPU;	CHECK_THIS_CPU;	check_arg_pri(pri);	openpic2_writefield(&OpenPIC2->THIS_CPU.Current_Task_Priority,			   OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri);}/* *  Get/set the spurious vector */#ifdef notusedstatic u_int openpic2_get_spurious(void){	return openpic2_readfield(&OpenPIC2->Global.Spurious_Vector,				 OPENPIC_VECTOR_MASK);}#endif /* notused *//* This can't be __init, it is used in openpic_sleep_restore_intrs */static void openpic2_set_spurious(u_int vec){	check_arg_vec(vec);	openpic2_writefield(&OpenPIC2->Global.Spurious_Vector, OPENPIC_VECTOR_MASK,			   vec);}static DEFINE_SPINLOCK(openpic2_setup_lock);/* *  Initialize a timer interrupt (and disable it) * *  timer: OpenPIC timer number *  pri: interrupt source priority *  vec: the vector it will produce */static void __init openpic2_inittimer(u_int timer, u_int pri, u_int vec){	check_arg_timer(timer);	check_arg_pri(pri);	check_arg_vec(vec);	openpic2_safe_writefield(&OpenPIC2->Global.Timer[timer].Vector_Priority,				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,				(pri << OPENPIC_PRIORITY_SHIFT) | vec);}/* *  Map a timer interrupt to one or more CPUs */static void __init openpic2_maptimer(u_int timer, u_int cpumask){	check_arg_timer(timer);	openpic2_write(&OpenPIC2->Global.Timer[timer].Destination,		      cpumask);}/* * Initalize the interrupt source which will generate an NMI. * This raises the interrupt's priority from 8 to 9. * * irq: The logical IRQ which generates an NMI. */void __initopenpic2_init_nmi_irq(u_int irq){	check_arg_irq(irq);	openpic2_safe_writefield(&ISR[irq - open_pic2_irq_offset]->Vector_Priority,				OPENPIC_PRIORITY_MASK,				9 << OPENPIC_PRIORITY_SHIFT);}/* * * All functions below take an offset'ed irq argument * *//* *  Enable/disable an external interrupt source * *  Externally called, irq is an offseted system-wide interrupt number */static void openpic2_enable_irq(u_int irq){	volatile u_int *vpp;	check_arg_irq(irq);	vpp = &ISR[irq - open_pic2_irq_offset]->Vector_Priority;       	openpic2_clearfield(vpp, OPENPIC_MASK);	/* make sure mask gets to controller before we return to user */       	do {       		mb(); /* sync is probably useless here */       	} while (openpic2_readfield(vpp, OPENPIC_MASK));}static void openpic2_disable_irq(u_int irq){	volatile u_int *vpp;	u32 vp;	check_arg_irq(irq);	vpp = &ISR[irq - open_pic2_irq_offset]->Vector_Priority;	openpic2_setfield(vpp, OPENPIC_MASK);	/* make sure mask gets to controller before we return to user */	do {		mb();  /* sync is probably useless here */		vp = openpic2_readfield(vpp, OPENPIC_MASK | OPENPIC_ACTIVITY);	} while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));}/* *  Initialize an interrupt source (and disable it!) * *  irq: OpenPIC interrupt number *  pri: interrupt source priority *  vec: the vector it will produce *  pol: polarity (1 for positive, 0 for negative) *  sense: 1 for level, 0 for edge */static void __initopenpic2_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense){	openpic2_safe_writefield(&ISR[irq]->Vector_Priority,				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |				OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,				(pri << OPENPIC_PRIORITY_SHIFT) | vec |				(pol ? OPENPIC_POLARITY_POSITIVE :			    		OPENPIC_POLARITY_NEGATIVE) |				(sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));}/* *  Map an interrupt source to one or more CPUs */static void openpic2_mapirq(u_int irq, u_int physmask, u_int keepmask){	if (ISR[irq] == 0)		return;	if (keepmask != 0)		physmask |= openpic2_read(&ISR[irq]->Destination) & keepmask;	openpic2_write(&ISR[irq]->Destination, physmask);}#ifdef notused/* *  Set the sense for an interrupt source (and disable it!) * *  sense: 1 for level, 0 for edge */static void openpic2_set_sense(u_int irq, int sense){	if (ISR[irq] != 0)		openpic2_safe_writefield(&ISR[irq]->Vector_Priority,					OPENPIC_SENSE_LEVEL,					(sense ? OPENPIC_SENSE_LEVEL : 0));}#endif /* notused *//* No spinlocks, should not be necessary with the OpenPIC * (1 register = 1 interrupt and we have the desc lock). */static void openpic2_ack_irq(unsigned int irq_nr){	openpic2_disable_irq(irq_nr);	openpic2_eoi();}static void openpic2_end_irq(unsigned int irq_nr){	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))		openpic2_enable_irq(irq_nr);}intopenpic2_get_irq(struct pt_regs *regs){	int irq = openpic2_irq();	if (irq == (OPENPIC2_VEC_SPURIOUS + open_pic2_irq_offset))		irq = -1;	return irq;}#ifdef CONFIG_PM/* * We implement the IRQ controller as a sysdev and put it * to sleep at powerdown stage (the callback is named suspend, * but it's old semantics, for the Device Model, it's really * powerdown). The possible problem is that another sysdev that * happens to be suspend after this one will have interrupts off, * that may be an issue... For now, this isn't an issue on pmac * though... */static u32 save_ipi_vp[OPENPIC_NUM_IPI];static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES];static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES];static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS];static int openpic_suspend_count;static void openpic2_cached_enable_irq(u_int irq){	check_arg_irq(irq);	save_irq_src_vp[irq - open_pic2_irq_offset] &= ~OPENPIC_MASK;}static void openpic2_cached_disable_irq(u_int irq){	check_arg_irq(irq);	save_irq_src_vp[irq - open_pic2_irq_offset] |= OPENPIC_MASK;}/* WARNING: Can be called directly by the cpufreq code with NULL parameter, * we need something better to deal with that... Maybe switch to S1 for * cpufreq changes */int openpic2_suspend(struct sys_device *sysdev, pm_message_t state){	int	i;	unsigned long flags;	spin_lock_irqsave(&openpic2_setup_lock, flags);	if (openpic_suspend_count++ > 0) {		spin_unlock_irqrestore(&openpic2_setup_lock, flags);		return 0;	}	open_pic2.enable = openpic2_cached_enable_irq;	open_pic2.disable = openpic2_cached_disable_irq;	for (i=0; i<NumProcessors; i++) {		save_cpu_task_pri[i] = openpic2_read(&OpenPIC2->Processor[i].Current_Task_Priority);		openpic2_writefield(&OpenPIC2->Processor[i].Current_Task_Priority,				   OPENPIC_CURRENT_TASK_PRIORITY_MASK, 0xf);	}	for (i=0; i<OPENPIC_NUM_IPI; i++)		save_ipi_vp[i] = openpic2_read(&OpenPIC2->Global.IPI_Vector_Priority(i));	for (i=0; i<NumSources; i++) {		if (ISR[i] == 0)			continue;		save_irq_src_vp[i] = openpic2_read(&ISR[i]->Vector_Priority) & ~OPENPIC_ACTIVITY;		save_irq_src_dest[i] = openpic2_read(&ISR[i]->Destination);	}	spin_unlock_irqrestore(&openpic2_setup_lock, flags);	return 0;}/* WARNING: Can be called directly by the cpufreq code with NULL parameter, * we need something better to deal with that... Maybe switch to S1 for * cpufreq changes */int openpic2_resume(struct sys_device *sysdev){	int		i;	unsigned long	flags;	u32		vppmask =	OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |					OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK |					OPENPIC_MASK;	spin_lock_irqsave(&openpic2_setup_lock, flags);	if ((--openpic_suspend_count) > 0) {		spin_unlock_irqrestore(&openpic2_setup_lock, flags);		return 0;	}	openpic2_reset();	/* OpenPIC sometimes seem to need some time to be fully back up... */	do {		openpic2_set_spurious(OPENPIC2_VEC_SPURIOUS+open_pic2_irq_offset);	} while(openpic2_readfield(&OpenPIC2->Global.Spurious_Vector, OPENPIC_VECTOR_MASK)			!= (OPENPIC2_VEC_SPURIOUS + open_pic2_irq_offset));		openpic2_disable_8259_pass_through();	for (i=0; i<OPENPIC_NUM_IPI; i++)		openpic2_write(&OpenPIC2->Global.IPI_Vector_Priority(i),			      save_ipi_vp[i]);	for (i=0; i<NumSources; i++) {		if (ISR[i] == 0)			continue;		openpic2_write(&ISR[i]->Destination, save_irq_src_dest[i]);		openpic2_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);		/* make sure mask gets to controller before we return to user */		do {			openpic2_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);		} while (openpic2_readfield(&ISR[i]->Vector_Priority, vppmask)			 != (save_irq_src_vp[i] & vppmask));	}	for (i=0; i<NumProcessors; i++)		openpic2_write(&OpenPIC2->Processor[i].Current_Task_Priority,			      save_cpu_task_pri[i]);	open_pic2.enable = openpic2_enable_irq;	open_pic2.disable = openpic2_disable_irq;	spin_unlock_irqrestore(&openpic2_setup_lock, flags);	return 0;}#endif /* CONFIG_PM *//* HACK ALERT */static struct sysdev_class openpic2_sysclass = {	set_kset_name("openpic2"),};static struct sys_device device_openpic2 = {	.id		= 0,	.cls		= &openpic2_sysclass,};static struct sysdev_driver driver_openpic2 = {#ifdef CONFIG_PM	.suspend	= &openpic2_suspend,	.resume		= &openpic2_resume,#endif /* CONFIG_PM */};static int __init init_openpic2_sysfs(void){	int rc;	if (!OpenPIC2_Addr)		return -ENODEV;	printk(KERN_DEBUG "Registering openpic2 with sysfs...\n");	rc = sysdev_class_register(&openpic2_sysclass);	if (rc) {		printk(KERN_ERR "Failed registering openpic sys class\n");		return -ENODEV;	}	rc = sysdev_register(&device_openpic2);	if (rc) {		printk(KERN_ERR "Failed registering openpic sys device\n");		return -ENODEV;	}	rc = sysdev_driver_register(&openpic2_sysclass, &driver_openpic2);	if (rc) {		printk(KERN_ERR "Failed registering openpic sys driver\n");		return -ENODEV;	}	return 0;}subsys_initcall(init_openpic2_sysfs);

⌨️ 快捷键说明

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