欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

prom.c

优龙2410linux2.6.8内核源代码
C
第 1 页 / 共 5 页
字号:
		imap = (unsigned int *)			get_property(p, "interrupt-map", &imaplen);		if (imap == NULL) {			p = intr_parent(p);			continue;		}		imask = (unsigned int *)			get_property(p, "interrupt-map-mask", NULL);		if (imask == NULL) {			printk("oops, %s has interrupt-map but no mask\n",			       p->full_name);			return 0;		}		imaplen /= sizeof(unsigned int);		match = 0;		ipar = NULL;		while (imaplen > 0 && !match) {			/* check the child-interrupt field */			match = 1;			for (i = 0; i < naddrc && match; ++i)				match = ((reg[i] ^ imap[i]) & imask[i]) == 0;			for (; i < naddrc + nintrc && match; ++i)				match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;			imap += naddrc + nintrc;			imaplen -= naddrc + nintrc;			/* grab the interrupt parent */			ipar = find_phandle((phandle) *imap++);			--imaplen;			if (ipar == NULL) {				printk("oops, no int parent %x in map of %s\n",				       imap[-1], p->full_name);				return 0;			}			/* find the parent's # addr and intr cells */			ip = (unsigned int *)				get_property(ipar, "#interrupt-cells", NULL);			if (ip == NULL) {				printk("oops, no #interrupt-cells on %s\n",				       ipar->full_name);				return 0;			}			newintrc = *ip;			ip = (unsigned int *)				get_property(ipar, "#address-cells", NULL);			newaddrc = (ip == NULL)? 0: *ip;			imap += newaddrc + newintrc;			imaplen -= newaddrc + newintrc;		}		if (imaplen < 0) {			printk("oops, error decoding int-map on %s, len=%d\n",			       p->full_name, imaplen);			return 0;		}		if (!match) {#ifdef DEBUG_IRQ			printk("oops, no match in %s int-map for %s\n",			       p->full_name, np->full_name);#endif			return 0;		}		p = ipar;		naddrc = newaddrc;		nintrc = newintrc;		ints = imap - nintrc;		reg = ints - naddrc;	}	if (p == NULL) {#ifdef DEBUG_IRQ		printk("hmmm, int tree for %s doesn't have ctrler\n",		       np->full_name);#endif		return 0;	}	*irq = ints;	*ictrler = p;	return nintrc;}static unsigned long __initfinish_node_interrupts(struct device_node *np, unsigned long mem_start,		       int measure_only){	unsigned int *ints;	int intlen, intrcells, intrcount;	int i, j, n;	unsigned int *irq, virq;	struct device_node *ic;	ints = (unsigned int *) get_property(np, "interrupts", &intlen);	if (ints == NULL)		return mem_start;	intrcells = prom_n_intr_cells(np);	intlen /= intrcells * sizeof(unsigned int);	np->intrs = (struct interrupt_info *) mem_start;	mem_start += intlen * sizeof(struct interrupt_info);	if (measure_only)		return mem_start;	intrcount = 0;	for (i = 0; i < intlen; ++i, ints += intrcells) {		n = map_interrupt(&irq, &ic, np, ints, intrcells);		if (n <= 0)			continue;		/* don't map IRQ numbers under a cascaded 8259 controller */		if (ic && device_is_compatible(ic, "chrp,iic")) {			np->intrs[intrcount].line = irq[0];		} else {			virq = virt_irq_create_mapping(irq[0]);			if (virq == NO_IRQ) {				printk(KERN_CRIT "Could not allocate interrupt"				       " number for %s\n", np->full_name);				continue;			}			np->intrs[intrcount].line = irq_offset_up(virq);		}		/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */		if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {			char *name = get_property(ic->parent, "name", NULL);			if (name && !strcmp(name, "u3"))				np->intrs[intrcount].line += 128;		}		np->intrs[intrcount].sense = 1;		if (n > 1)			np->intrs[intrcount].sense = irq[1];		if (n > 2) {			printk("hmmm, got %d intr cells for %s:", n,			       np->full_name);			for (j = 0; j < n; ++j)				printk(" %d", irq[j]);			printk("\n");		}		++intrcount;	}	np->n_intrs = intrcount;	return mem_start;}static unsigned long __initinterpret_pci_props(struct device_node *np, unsigned long mem_start,		    int naddrc, int nsizec, int measure_only){	struct address_range *adr;	struct pci_reg_property *pci_addrs;	int i, l;	pci_addrs = (struct pci_reg_property *)		get_property(np, "assigned-addresses", &l);	if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct pci_reg_property)) >= 0) {			if (!measure_only) {				adr[i].space = pci_addrs[i].addr.a_hi;				adr[i].address = pci_addrs[i].addr.a_lo;				adr[i].size = pci_addrs[i].size_lo;			}			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	return mem_start;}static unsigned long __initinterpret_dbdma_props(struct device_node *np, unsigned long mem_start,		      int naddrc, int nsizec, int measure_only){	struct reg_property32 *rp;	struct address_range *adr;	unsigned long base_address;	int i, l;	struct device_node *db;	base_address = 0;	if (!measure_only) {		for (db = np->parent; db != NULL; db = db->parent) {			if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {				base_address = db->addrs[0].address;				break;			}		}	}	rp = (struct reg_property32 *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct reg_property32)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property32)) >= 0) {			if (!measure_only) {				adr[i].space = 2;				adr[i].address = rp[i].address + base_address;				adr[i].size = rp[i].size;			}			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	return mem_start;}static unsigned long __initinterpret_macio_props(struct device_node *np, unsigned long mem_start,		      int naddrc, int nsizec, int measure_only){	struct reg_property32 *rp;	struct address_range *adr;	unsigned long base_address;	int i, l;	struct device_node *db;	base_address = 0;	if (!measure_only) {		for (db = np->parent; db != NULL; db = db->parent) {			if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {				base_address = db->addrs[0].address;				break;			}		}	}	rp = (struct reg_property32 *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct reg_property32)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property32)) >= 0) {			if (!measure_only) {				adr[i].space = 2;				adr[i].address = rp[i].address + base_address;				adr[i].size = rp[i].size;			}			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	return mem_start;}static unsigned long __initinterpret_isa_props(struct device_node *np, unsigned long mem_start,		    int naddrc, int nsizec, int measure_only){	struct isa_reg_property *rp;	struct address_range *adr;	int i, l;	rp = (struct isa_reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			if (!measure_only) {				adr[i].space = rp[i].space;				adr[i].address = rp[i].address;				adr[i].size = rp[i].size;			}			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	return mem_start;}static unsigned long __initinterpret_root_props(struct device_node *np, unsigned long mem_start,		     int naddrc, int nsizec, int measure_only){	struct address_range *adr;	int i, l;	unsigned int *rp;	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);	rp = (unsigned int *) get_property(np, "reg", &l);	if (rp != 0 && l >= rpsize) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= rpsize) >= 0) {			if (!measure_only) {				adr[i].space = 0;				adr[i].address = rp[naddrc - 1];				adr[i].size = rp[naddrc + nsizec - 1];			}			++i;			rp += naddrc + nsizec;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	return mem_start;}static unsigned long __initfinish_node(struct device_node *np, unsigned long mem_start,	    interpret_func *ifunc, int naddrc, int nsizec, int measure_only){	struct device_node *child;	int *ip;	np->name = get_property(np, "name", NULL);	np->type = get_property(np, "device_type", NULL);	if (!np->name)		np->name = "<NULL>";	if (!np->type)		np->type = "<NULL>";	/* get the device addresses and interrupts */	if (ifunc != NULL)		mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);	mem_start = finish_node_interrupts(np, mem_start, measure_only);	/* Look for #address-cells and #size-cells properties. */	ip = (int *) get_property(np, "#address-cells", NULL);	if (ip != NULL)		naddrc = *ip;	ip = (int *) get_property(np, "#size-cells", NULL);	if (ip != NULL)		nsizec = *ip;	/* the f50 sets the name to 'display' and 'compatible' to what we	 * expect for the name -- Cort	 */	if (!strcmp(np->name, "display"))		np->name = get_property(np, "compatible", NULL);	if (!strcmp(np->name, "device-tree") || np->parent == NULL)		ifunc = interpret_root_props;	else if (np->type == 0)		ifunc = NULL;	else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))		ifunc = interpret_pci_props;	else if (!strcmp(np->type, "dbdma"))		ifunc = interpret_dbdma_props;	else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)		ifunc = interpret_macio_props;	else if (!strcmp(np->type, "isa"))		ifunc = interpret_isa_props;	else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))		ifunc = interpret_root_props;	else if (!((ifunc == interpret_dbdma_props		    || ifunc == interpret_macio_props)		   && (!strcmp(np->type, "escc")		       || !strcmp(np->type, "media-bay"))))		ifunc = NULL;	for (child = np->child; child != NULL; child = child->sibling)		mem_start = finish_node(child, mem_start, ifunc,					naddrc, nsizec, measure_only);	return mem_start;}/** * finish_device_tree is called once things are running normally * (i.e. with text and data mapped to the address they were linked at). * It traverses the device tree and fills in the name, type, * {n_}addrs and {n_}intrs fields of each node. */void __initfinish_device_tree(void){	unsigned long mem = klimit;	virt_irq_init();	dev_tree_size = finish_node(allnodes, 0, NULL, 0, 0, 1);	mem = (long)abs_to_virt(lmb_alloc(dev_tree_size,					  __alignof__(struct device_node)));	if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + dev_tree_size)		BUG();	rtas.dev = of_find_node_by_name(NULL, "rtas");}intprom_n_addr_cells(struct device_node* np){	int* ip;	do {		if (np->parent)			np = np->parent;		ip = (int *) get_property(np, "#address-cells", NULL);		if (ip != NULL)			return *ip;	} while (np->parent);	/* No #address-cells property for the root node, default to 1 */	return 1;}intprom_n_size_cells(struct device_node* np){	int* ip;	do {		if (np->parent)			np = np->parent;		ip = (int *) get_property(np, "#size-cells", NULL);		if (ip != NULL)			return *ip;	} while (np->parent);	/* No #size-cells property for the root node, default to 1 */	return 1;}/** * Work out the sense (active-low level / active-high edge) * of each interrupt from the device tree. */void __initprom_get_irq_senses(unsigned char *senses, int off, int max){	struct device_node *np;	int i, j;	/* default to level-triggered */	memset(senses, 1, max - off);	for (np = allnodes; np != 0; np = np->allnext) {		for (j = 0; j < np->n_intrs; j++) {			i = np->intrs[j].line;			if (i >= off && i < max)				senses[i-off] = np->intrs[j].sense;		}	}}/** * Construct and return a list of the device_nodes with a given name. */struct device_node *find_devices(const char *name){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (np->name != 0 && strcasecmp(np->name, name) == 0) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = NULL;	return head;}/** * Construct and return a list of the device_nodes with a given type. */struct device_node *find_type_devices(const char *type){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (np->type != 0 && strcasecmp(np->type, type) == 0) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = NULL;	re

⌨️ 快捷键说明

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