macio_asic.c

来自「linux 内核源代码」· C语言 代码 · 共 734 行 · 第 1/2 页

C
734
字号
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);	if (!dev)		return NULL;	dev->bus = &chip->lbus;	dev->media_bay = in_bay;	dev->ofdev.node = np;	dev->ofdev.dma_mask = 0xffffffffUL;	dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask;	dev->ofdev.dev.parent = parent;	dev->ofdev.dev.bus = &macio_bus_type;	dev->ofdev.dev.release = macio_release_dev;#ifdef DEBUG	printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n",	       dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj);#endif	/* MacIO itself has a different reg, we use it's PCI base */	if (np == chip->of_node) {		sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s",			chip->lbus.index,#ifdef CONFIG_PCI			(unsigned int)pci_resource_start(chip->lbus.pdev, 0),#else			0, /* NuBus may want to do something better here */#endif			MAX_NODE_NAME_SIZE, np->name);	} else {		reg = of_get_property(np, "reg", NULL);		sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s",			chip->lbus.index,			reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name);	}	/* Setup interrupts & resources */	macio_setup_interrupts(dev);	macio_setup_resources(dev, parent_res);	macio_add_missing_resources(dev);	/* Register with core */	if (of_device_register(&dev->ofdev) != 0) {		printk(KERN_DEBUG"macio: device registration error for %s!\n",		       dev->ofdev.dev.bus_id);		kfree(dev);		return NULL;	}	return dev;}static int macio_skip_device(struct device_node *np){	if (strncmp(np->name, "battery", 7) == 0)		return 1;	if (strncmp(np->name, "escc-legacy", 11) == 0)		return 1;	return 0;}/** * macio_pci_add_devices - Adds sub-devices of mac-io to the device tree * @chip: pointer to the macio_chip holding the devices *  * This function will do the job of extracting devices from the * Open Firmware device tree, build macio_dev structures and add * them to the Linux device tree. *  * For now, childs of media-bay are added now as well. This will * change rsn though. */static void macio_pci_add_devices(struct macio_chip *chip){	struct device_node *np, *pnode;	struct macio_dev *rdev, *mdev, *mbdev = NULL, *sdev = NULL;	struct device *parent = NULL;	struct resource *root_res = &iomem_resource;		/* Add a node for the macio bus itself */#ifdef CONFIG_PCI	if (chip->lbus.pdev) {		parent = &chip->lbus.pdev->dev;		root_res = &chip->lbus.pdev->resource[0];	}#endif	pnode = of_node_get(chip->of_node);	if (pnode == NULL)		return;	/* Add macio itself to hierarchy */	rdev = macio_add_one_device(chip, parent, pnode, NULL, root_res);	if (rdev == NULL)		return;	root_res = &rdev->resource[0];	/* First scan 1st level */	for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {		if (macio_skip_device(np))			continue;		of_node_get(np);		mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL,					    root_res);		if (mdev == NULL)			of_node_put(np);		else if (strncmp(np->name, "media-bay", 9) == 0)			mbdev = mdev;		else if (strncmp(np->name, "escc", 4) == 0)			sdev = mdev;	}	/* Add media bay devices if any */	if (mbdev)		for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np))			     != NULL;) {			if (macio_skip_device(np))				continue;			of_node_get(np);			if (macio_add_one_device(chip, &mbdev->ofdev.dev, np,						 mbdev,  root_res) == NULL)				of_node_put(np);		}	/* Add serial ports if any */	if (sdev) {		for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np))			     != NULL;) {			if (macio_skip_device(np))				continue;			of_node_get(np);			if (macio_add_one_device(chip, &sdev->ofdev.dev, np,						 NULL, root_res) == NULL)				of_node_put(np);		}	}}/** * macio_register_driver - Registers a new MacIO device driver * @drv: pointer to the driver definition structure */int macio_register_driver(struct macio_driver *drv){	/* initialize common driver fields */	drv->driver.name = drv->name;	drv->driver.bus = &macio_bus_type;	/* register with core */	return driver_register(&drv->driver);}/** * macio_unregister_driver - Unregisters a new MacIO device driver * @drv: pointer to the driver definition structure */void macio_unregister_driver(struct macio_driver *drv){	driver_unregister(&drv->driver);}/** *	macio_request_resource - Request an MMIO resource * 	@dev: pointer to the device holding the resource *	@resource_no: resource number to request *	@name: resource name * *	Mark  memory region number @resource_no associated with MacIO *	device @dev as being reserved by owner @name.  Do not access *	any address inside the memory regions unless this call returns *	successfully. * *	Returns 0 on success, or %EBUSY on error.  A warning *	message is also printed on failure. */int macio_request_resource(struct macio_dev *dev, int resource_no,			   const char *name){	if (macio_resource_len(dev, resource_no) == 0)		return 0;			if (!request_mem_region(macio_resource_start(dev, resource_no),				macio_resource_len(dev, resource_no),				name))		goto err_out;		return 0;err_out:	printk (KERN_WARNING "MacIO: Unable to reserve resource #%d:%lx@%lx"		" for device %s\n",		resource_no,		macio_resource_len(dev, resource_no),		macio_resource_start(dev, resource_no),		dev->ofdev.dev.bus_id);	return -EBUSY;}/** * macio_release_resource - Release an MMIO resource * @dev: pointer to the device holding the resource * @resource_no: resource number to release */void macio_release_resource(struct macio_dev *dev, int resource_no){	if (macio_resource_len(dev, resource_no) == 0)		return;	release_mem_region(macio_resource_start(dev, resource_no),			   macio_resource_len(dev, resource_no));}/** *	macio_request_resources - Reserve all memory resources *	@dev: MacIO device whose resources are to be reserved *	@name: Name to be associated with resource. * *	Mark all memory regions associated with MacIO device @dev as *	being reserved by owner @name.  Do not access any address inside *	the memory regions unless this call returns successfully. * *	Returns 0 on success, or %EBUSY on error.  A warning *	message is also printed on failure. */int macio_request_resources(struct macio_dev *dev, const char *name){	int i;		for (i = 0; i < dev->n_resources; i++)		if (macio_request_resource(dev, i, name))			goto err_out;	return 0;err_out:	while(--i >= 0)		macio_release_resource(dev, i);			return -EBUSY;}/** *	macio_release_resources - Release reserved memory resources *	@dev: MacIO device whose resources were previously reserved */void macio_release_resources(struct macio_dev *dev){	int i;		for (i = 0; i < dev->n_resources; i++)		macio_release_resource(dev, i);}#ifdef CONFIG_PCIstatic int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent){	struct device_node* np;	struct macio_chip* chip;		if (ent->vendor != PCI_VENDOR_ID_APPLE)		return -ENODEV;	/* Note regarding refcounting: We assume pci_device_to_OF_node() is	 * ported to new OF APIs and returns a node with refcount incremented.	 */	np = pci_device_to_OF_node(pdev);	if (np == NULL)		return -ENODEV;	/* The above assumption is wrong !!!	 * fix that here for now until I fix the arch code	 */	of_node_get(np);	/* We also assume that pmac_feature will have done a get() on nodes	 * stored in the macio chips array	 */	chip = macio_find(np, macio_unknown);       	of_node_put(np);	if (chip == NULL)		return -ENODEV;	/* XXX Need locking ??? */	if (chip->lbus.pdev == NULL) {		chip->lbus.pdev = pdev;		chip->lbus.chip = chip;		pci_set_drvdata(pdev, &chip->lbus);		pci_set_master(pdev);	}	printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n",		chip->name);	/*	 * HACK ALERT: The WallStreet PowerBook and some OHare based machines	 * have 2 macio ASICs. I must probe the "main" one first or IDE	 * ordering will be incorrect. So I put on "hold" the second one since	 * it seem to appear first on PCI	 */	if (chip->type == macio_gatwick || chip->type == macio_ohareII)		if (macio_chips[0].lbus.pdev == NULL) {			macio_on_hold = chip;			return 0;		}	macio_pci_add_devices(chip);	if (macio_on_hold && macio_chips[0].lbus.pdev != NULL) {		macio_pci_add_devices(macio_on_hold);		macio_on_hold = NULL;	}	return 0;}static void __devexit macio_pci_remove(struct pci_dev* pdev){	panic("removing of macio-asic not supported !\n");}/* * MacIO is matched against any Apple ID, it's probe() function * will then decide wether it applies or not */static const struct pci_device_id __devinitdata pci_ids [] = { {	.vendor		= PCI_VENDOR_ID_APPLE,	.device		= PCI_ANY_ID,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	}, { /* end: all zeroes */ }};MODULE_DEVICE_TABLE (pci, pci_ids);/* pci driver glue; this is a "new style" PCI driver module */static struct pci_driver macio_pci_driver = {	.name		= (char *) "macio",	.id_table	= pci_ids,	.probe		= macio_pci_probe,	.remove		= macio_pci_remove,};#endif /* CONFIG_PCI */static int __init macio_module_init (void) {#ifdef CONFIG_PCI	int rc;	rc = pci_register_driver(&macio_pci_driver);	if (rc)		return rc;#endif /* CONFIG_PCI */	return 0;}module_init(macio_module_init);EXPORT_SYMBOL(macio_register_driver);EXPORT_SYMBOL(macio_unregister_driver);EXPORT_SYMBOL(macio_dev_get);EXPORT_SYMBOL(macio_dev_put);EXPORT_SYMBOL(macio_request_resource);EXPORT_SYMBOL(macio_release_resource);EXPORT_SYMBOL(macio_request_resources);EXPORT_SYMBOL(macio_release_resources);

⌨️ 快捷键说明

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