static int __init sba_driver_callback()

in sba_iommu.c [1882:1973]


static int __init sba_driver_callback(struct parisc_device *dev)
{
	struct sba_device *sba_dev;
	u32 func_class;
	int i;
	char *version;
	void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE);
#ifdef CONFIG_PROC_FS
	struct proc_dir_entry *root;
#endif

	sba_dump_ranges(sba_addr);

	/* Read HW Rev First */
	func_class = READ_REG(sba_addr + SBA_FCLASS);

	if (IS_ASTRO(dev)) {
		unsigned long fclass;
		static char astro_rev[]="Astro ?.?";

		/* Astro is broken...Read HW Rev First */
		fclass = READ_REG(sba_addr);

		astro_rev[6] = '1' + (char) (fclass & 0x7);
		astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
		version = astro_rev;

	} else if (IS_IKE(dev)) {
		static char ike_rev[] = "Ike rev ?";
		ike_rev[8] = '0' + (char) (func_class & 0xff);
		version = ike_rev;
	} else if (IS_PLUTO(dev)) {
		static char pluto_rev[]="Pluto ?.?";
		pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4); 
		pluto_rev[8] = '0' + (char) (func_class & 0x0f); 
		version = pluto_rev;
	} else {
		static char reo_rev[] = "REO rev ?";
		reo_rev[8] = '0' + (char) (func_class & 0xff);
		version = reo_rev;
	}

	if (!global_ioc_cnt) {
		global_ioc_cnt = count_parisc_driver(&sba_driver);

		/* Astro and Pluto have one IOC per SBA */
		if ((!IS_ASTRO(dev)) || (!IS_PLUTO(dev)))
			global_ioc_cnt *= 2;
	}

	printk(KERN_INFO "%s found %s at 0x%llx\n",
		MODULE_NAME, version, (unsigned long long)dev->hpa.start);

	sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL);
	if (!sba_dev) {
		printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n");
		return -ENOMEM;
	}

	parisc_set_drvdata(dev, sba_dev);

	for(i=0; i<MAX_IOC; i++)
		spin_lock_init(&(sba_dev->ioc[i].res_lock));

	sba_dev->dev = dev;
	sba_dev->hw_rev = func_class;
	sba_dev->name = dev->name;
	sba_dev->sba_hpa = sba_addr;

	sba_get_pat_resources(sba_dev);
	sba_hw_init(sba_dev);
	sba_common_init(sba_dev);

	hppa_dma_ops = &sba_ops;

#ifdef CONFIG_PROC_FS
	switch (dev->id.hversion) {
	case PLUTO_MCKINLEY_PORT:
		root = proc_mckinley_root;
		break;
	case ASTRO_RUNWAY_PORT:
	case IKE_MERCED_PORT:
	default:
		root = proc_runway_root;
		break;
	}

	proc_create_single("sba_iommu", 0, root, sba_proc_info);
	proc_create_single("sba_iommu-bitmap", 0, root, sba_proc_bitmap_info);
#endif
	return 0;
}