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

📄 pic.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		max_irqs = max_real_irqs = 32;		level_mask[0] = OHARE_LEVEL_MASK;		/* We might have a second cascaded ohare */		slave = of_find_node_by_name(NULL, "pci106b,7");		if (slave) {			max_irqs = 64;			level_mask[1] = OHARE_LEVEL_MASK;		}	} else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {		max_irqs = max_real_irqs = 64;		level_mask[0] = HEATHROW_LEVEL_MASK;		level_mask[1] = 0;		/* We might have a second cascaded heathrow */		slave = of_find_node_by_name(master, "mac-io");		/* Check ordering of master & slave */		if (of_device_is_compatible(master, "gatwick")) {			struct device_node *tmp;			BUG_ON(slave == NULL);			tmp = master;			master = slave;			slave = tmp;		}		/* We found a slave */		if (slave) {			max_irqs = 128;			level_mask[2] = HEATHROW_LEVEL_MASK;			level_mask[3] = 0;		}	}	BUG_ON(master == NULL);	/*	 * Allocate an irq host	 */	pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,				       &pmac_pic_host_ops,				       max_irqs);	BUG_ON(pmac_pic_host == NULL);	irq_set_default_host(pmac_pic_host);	/* Get addresses of first controller if we have a node for it */	BUG_ON(of_address_to_resource(master, 0, &r));	/* Map interrupts of primary controller */	addr = (u8 __iomem *) ioremap(r.start, 0x40);	i = 0;	pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)		(addr + 0x20);	if (max_real_irqs > 32)		pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)			(addr + 0x10);	of_node_put(master);	printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n",	       master->full_name, max_real_irqs);	/* Map interrupts of cascaded controller */	if (slave && !of_address_to_resource(slave, 0, &r)) {		addr = (u8 __iomem *)ioremap(r.start, 0x40);		pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)			(addr + 0x20);		if (max_irqs > 64)			pmac_irq_hw[i++] =				(volatile struct pmac_irq_hw __iomem *)				(addr + 0x10);		pmac_irq_cascade = irq_of_parse_and_map(slave, 0);		printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"		       " cascade: %d\n", slave->full_name,		       max_irqs - max_real_irqs, pmac_irq_cascade);	}	of_node_put(slave);	/* Disable all interrupts in all controllers */	for (i = 0; i * 32 < max_irqs; ++i)		out_le32(&pmac_irq_hw[i]->enable, 0);	/* Hookup cascade irq */	if (slave && pmac_irq_cascade != NO_IRQ)		setup_irq(pmac_irq_cascade, &gatwick_cascade_action);	printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);#ifdef CONFIG_XMON	setup_irq(irq_create_mapping(NULL, 20), &xmon_action);#endif}#endif /* CONFIG_PPC32 */static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc){	struct mpic *mpic = desc->handler_data;	unsigned int cascade_irq = mpic_get_one_irq(mpic);	if (cascade_irq != NO_IRQ)		generic_handle_irq(cascade_irq);	desc->chip->eoi(irq);}static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic){#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)	struct device_node* pswitch;	int nmi_irq;	pswitch = of_find_node_by_name(NULL, "programmer-switch");	if (pswitch) {		nmi_irq = irq_of_parse_and_map(pswitch, 0);		if (nmi_irq != NO_IRQ) {			mpic_irq_set_priority(nmi_irq, 9);			setup_irq(nmi_irq, &xmon_action);		}		of_node_put(pswitch);	}#endif	/* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */}static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,						int master){	const char *name = master ? " MPIC 1   " : " MPIC 2   ";	struct resource r;	struct mpic *mpic;	unsigned int flags = master ? MPIC_PRIMARY : 0;	int rc;	rc = of_address_to_resource(np, 0, &r);	if (rc)		return NULL;	pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);	flags |= MPIC_WANTS_RESET;	if (of_get_property(np, "big-endian", NULL))		flags |= MPIC_BIG_ENDIAN;	/* Primary Big Endian means HT interrupts. This is quite dodgy	 * but works until I find a better way	 */	if (master && (flags & MPIC_BIG_ENDIAN))		flags |= MPIC_U3_HT_IRQS;	mpic = mpic_alloc(np, r.start, flags, 0, 0, name);	if (mpic == NULL)		return NULL;	mpic_init(mpic);	return mpic; }static int __init pmac_pic_probe_mpic(void){	struct mpic *mpic1, *mpic2;	struct device_node *np, *master = NULL, *slave = NULL;	unsigned int cascade;	/* We can have up to 2 MPICs cascaded */	for (np = NULL; (np = of_find_node_by_type(np, "open-pic"))		     != NULL;) {		if (master == NULL &&		    of_get_property(np, "interrupts", NULL) == NULL)			master = of_node_get(np);		else if (slave == NULL)			slave = of_node_get(np);		if (master && slave)			break;	}	/* Check for bogus setups */	if (master == NULL && slave != NULL) {		master = slave;		slave = NULL;	}	/* Not found, default to good old pmac pic */	if (master == NULL)		return -ENODEV;	/* Set master handler */	ppc_md.get_irq = mpic_get_irq;	/* Setup master */	mpic1 = pmac_setup_one_mpic(master, 1);	BUG_ON(mpic1 == NULL);	/* Install NMI if any */	pmac_pic_setup_mpic_nmi(mpic1);	of_node_put(master);	/* No slave, let's go out */	if (slave == NULL)		return 0;	/* Get/Map slave interrupt */	cascade = irq_of_parse_and_map(slave, 0);	if (cascade == NO_IRQ) {		printk(KERN_ERR "Failed to map cascade IRQ\n");		return 0;	}	mpic2 = pmac_setup_one_mpic(slave, 0);	if (mpic2 == NULL) {		printk(KERN_ERR "Failed to setup slave MPIC\n");		of_node_put(slave);		return 0;	}	set_irq_data(cascade, mpic2);	set_irq_chained_handler(cascade, pmac_u3_cascade);	of_node_put(slave);	return 0;}void __init pmac_pic_init(void){	unsigned int flags = 0;	/* We configure the OF parsing based on our oldworld vs. newworld	 * platform type and wether we were booted by BootX.	 */#ifdef CONFIG_PPC32	if (!pmac_newworld)		flags |= OF_IMAP_OLDWORLD_MAC;	if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)		flags |= OF_IMAP_NO_PHANDLE;#endif /* CONFIG_PPC_32 */	of_irq_map_init(flags);	/* We first try to detect Apple's new Core99 chipset, since mac-io	 * is quite different on those machines and contains an IBM MPIC2.	 */	if (pmac_pic_probe_mpic() == 0)		return;#ifdef CONFIG_PPC32	pmac_pic_probe_oldstyle();#endif}#if defined(CONFIG_PM) && defined(CONFIG_PPC32)/* * These procedures are used in implementing sleep on the powerbooks. * sleep_save_intrs() saves the states of all interrupt enables * and disables all interrupts except for the nominated one. * sleep_restore_intrs() restores the states of all interrupt enables. */unsigned long sleep_save_mask[2];/* This used to be passed by the PMU driver but that link got * broken with the new driver model. We use this tweak for now... * We really want to do things differently though... */static int pmacpic_find_viaint(void){	int viaint = -1;#ifdef CONFIG_ADB_PMU	struct device_node *np;	if (pmu_get_model() != PMU_OHARE_BASED)		goto not_found;	np = of_find_node_by_name(NULL, "via-pmu");	if (np == NULL)		goto not_found;	viaint = irq_of_parse_and_map(np, 0);;#endif /* CONFIG_ADB_PMU */not_found:	return viaint;}static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state){	int viaint = pmacpic_find_viaint();	sleep_save_mask[0] = ppc_cached_irq_mask[0];	sleep_save_mask[1] = ppc_cached_irq_mask[1];	ppc_cached_irq_mask[0] = 0;	ppc_cached_irq_mask[1] = 0;	if (viaint > 0)		set_bit(viaint, ppc_cached_irq_mask);	out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);	if (max_real_irqs > 32)		out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);	(void)in_le32(&pmac_irq_hw[0]->event);	/* make sure mask gets to controller before we return to caller */	mb();        (void)in_le32(&pmac_irq_hw[0]->enable);        return 0;}static int pmacpic_resume(struct sys_device *sysdev){	int i;	out_le32(&pmac_irq_hw[0]->enable, 0);	if (max_real_irqs > 32)		out_le32(&pmac_irq_hw[1]->enable, 0);	mb();	for (i = 0; i < max_real_irqs; ++i)		if (test_bit(i, sleep_save_mask))			pmac_unmask_irq(i);	return 0;}#endif /* CONFIG_PM && CONFIG_PPC32 */static struct sysdev_class pmacpic_sysclass = {	set_kset_name("pmac_pic"),};static struct sys_device device_pmacpic = {	.id		= 0,	.cls		= &pmacpic_sysclass,};static struct sysdev_driver driver_pmacpic = {#if defined(CONFIG_PM) && defined(CONFIG_PPC32)	.suspend	= &pmacpic_suspend,	.resume		= &pmacpic_resume,#endif /* CONFIG_PM && CONFIG_PPC32 */};static int __init init_pmacpic_sysfs(void){#ifdef CONFIG_PPC32	if (max_irqs == 0)		return -ENODEV;#endif	printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");	sysdev_class_register(&pmacpic_sysclass);	sysdev_register(&device_pmacpic);	sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);	return 0;}subsys_initcall(init_pmacpic_sysfs);

⌨️ 快捷键说明

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