static int radeonfb_pci_register()

in fbdev/aty/radeon_base.c [2258:2516]


static int radeonfb_pci_register(struct pci_dev *pdev,
				 const struct pci_device_id *ent)
{
	struct fb_info *info;
	struct radeonfb_info *rinfo;
	int ret;
	unsigned char c1, c2;
	int err = 0;

	pr_debug("radeonfb_pci_register BEGIN\n");
	
	/* Enable device in PCI config */
	ret = pci_enable_device(pdev);
	if (ret < 0) {
		printk(KERN_ERR "radeonfb (%s): Cannot enable PCI device\n",
		       pci_name(pdev));
		goto err_out;
	}

	info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
	if (!info) {
		ret = -ENOMEM;
		goto err_disable;
	}
	rinfo = info->par;
	rinfo->info = info;	
	rinfo->pdev = pdev;
	
	spin_lock_init(&rinfo->reg_lock);
	timer_setup(&rinfo->lvds_timer, radeon_lvds_timer_func, 0);

	c1 = ent->device >> 8;
	c2 = ent->device & 0xff;
	if (isprint(c1) && isprint(c2))
		snprintf(rinfo->name, sizeof(rinfo->name),
			 "ATI Radeon %x \"%c%c\"", ent->device & 0xffff, c1, c2);
	else
		snprintf(rinfo->name, sizeof(rinfo->name),
			 "ATI Radeon %x", ent->device & 0xffff);

	rinfo->family = ent->driver_data & CHIP_FAMILY_MASK;
	rinfo->chipset = pdev->device;
	rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0;
	rinfo->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0;
	rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0;

	/* Set base addrs */
	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);

	ret = radeon_kick_out_firmware_fb(pdev);
	if (ret)
		goto err_release_fb;

	/* request the mem regions */
	ret = pci_request_region(pdev, 0, "radeonfb framebuffer");
	if (ret < 0) {
		printk( KERN_ERR "radeonfb (%s): cannot request region 0.\n",
			pci_name(rinfo->pdev));
		goto err_release_fb;
	}

	ret = pci_request_region(pdev, 2, "radeonfb mmio");
	if (ret < 0) {
		printk( KERN_ERR "radeonfb (%s): cannot request region 2.\n",
			pci_name(rinfo->pdev));
		goto err_release_pci0;
	}

	/* map the regions */
	rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE);
	if (!rinfo->mmio_base) {
		printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n",
		       pci_name(rinfo->pdev));
		ret = -EIO;
		goto err_release_pci2;
	}

	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;

	/*
	 * Check for errata
	 */
	rinfo->errata = 0;
	if (rinfo->family == CHIP_FAMILY_R300 &&
	    (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK)
	    == CFG_ATI_REV_A11)
		rinfo->errata |= CHIP_ERRATA_R300_CG;

	if (rinfo->family == CHIP_FAMILY_RV200 ||
	    rinfo->family == CHIP_FAMILY_RS200)
		rinfo->errata |= CHIP_ERRATA_PLL_DUMMYREADS;

	if (rinfo->family == CHIP_FAMILY_RV100 ||
	    rinfo->family == CHIP_FAMILY_RS100 ||
	    rinfo->family == CHIP_FAMILY_RS200)
		rinfo->errata |= CHIP_ERRATA_PLL_DELAY;

#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
	/* On PPC, we obtain the OF device-node pointer to the firmware
	 * data for this chip
	 */
	rinfo->of_node = pci_device_to_OF_node(pdev);
	if (rinfo->of_node == NULL)
		printk(KERN_WARNING "radeonfb (%s): Cannot match card to OF node !\n",
		       pci_name(rinfo->pdev));

#endif /* CONFIG_PPC || CONFIG_SPARC */
#ifdef CONFIG_PPC
	/* On PPC, the firmware sets up a memory mapping that tends
	 * to cause lockups when enabling the engine. We reconfigure
	 * the card internal memory mappings properly
	 */
	fixup_memory_mappings(rinfo);
#endif /* CONFIG_PPC */

	/* Get VRAM size and type */
	radeon_identify_vram(rinfo);

	rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);

	do {
		rinfo->fb_base = ioremap_wc(rinfo->fb_base_phys,
					    rinfo->mapped_vram);
	} while (rinfo->fb_base == NULL &&
		 ((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM));

	if (rinfo->fb_base == NULL) {
		printk (KERN_ERR "radeonfb (%s): cannot map FB\n",
			pci_name(rinfo->pdev));
		ret = -EIO;
		goto err_unmap_rom;
	}

	pr_debug("radeonfb (%s): mapped %ldk videoram\n", pci_name(rinfo->pdev),
	       rinfo->mapped_vram/1024);

	/*
	 * Map the BIOS ROM if any and retrieve PLL parameters from
	 * the BIOS. We skip that on mobility chips as the real panel
	 * values we need aren't in the ROM but in the BIOS image in
	 * memory. This is definitely not the best meacnism though,
	 * we really need the arch code to tell us which is the "primary"
	 * video adapter to use the memory image (or better, the arch
	 * should provide us a copy of the BIOS image to shield us from
	 * archs who would store that elsewhere and/or could initialize
	 * more than one adapter during boot).
	 */
	if (!rinfo->is_mobility)
		radeon_map_ROM(rinfo, pdev);

	/*
	 * On x86, the primary display on laptop may have it's BIOS
	 * ROM elsewhere, try to locate it at the legacy memory hole.
	 * We probably need to make sure this is the primary display,
	 * but that is difficult without some arch support.
	 */
#ifdef CONFIG_X86
	if (rinfo->bios_seg == NULL)
		radeon_find_mem_vbios(rinfo);
#endif

	/* If both above failed, try the BIOS ROM again for mobility
	 * chips
	 */
	if (rinfo->bios_seg == NULL && rinfo->is_mobility)
		radeon_map_ROM(rinfo, pdev);

	/* Get informations about the board's PLL */
	radeon_get_pllinfo(rinfo);

#ifdef CONFIG_FB_RADEON_I2C
	/* Register I2C bus */
	radeon_create_i2c_busses(rinfo);
#endif

	/* set all the vital stuff */
	radeon_set_fbinfo (rinfo);

	/* Probe screen types */
	radeon_probe_screens(rinfo, monitor_layout, ignore_edid);

	/* Build mode list, check out panel native model */
	radeon_check_modes(rinfo, mode_option);

	/* Register some sysfs stuff (should be done better) */
	if (rinfo->mon1_EDID)
		err |= sysfs_create_bin_file(&rinfo->pdev->dev.kobj,
						&edid1_attr);
	if (rinfo->mon2_EDID)
		err |= sysfs_create_bin_file(&rinfo->pdev->dev.kobj,
						&edid2_attr);
	if (err)
		pr_warn("%s() Creating sysfs files failed, continuing\n",
			__func__);

	/* save current mode regs before we switch into the new one
	 * so we can restore this upon __exit
	 */
	radeon_save_state (rinfo, &rinfo->init_state);
	memcpy(&rinfo->state, &rinfo->init_state, sizeof(struct radeon_regs));

	/* Setup Power Management capabilities */
	if (default_dynclk < -1) {
		/* -2 is special: means  ON on mobility chips and do not
		 * change on others
		 */
		radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep);
	} else
		radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep);

	pci_set_drvdata(pdev, info);

	/* Register with fbdev layer */
	ret = register_framebuffer(info);
	if (ret < 0) {
		printk (KERN_ERR "radeonfb (%s): could not register framebuffer\n",
			pci_name(rinfo->pdev));
		goto err_unmap_fb;
	}

	if (!nomtrr)
		rinfo->wc_cookie = arch_phys_wc_add(rinfo->fb_base_phys,
						    rinfo->video_ram);

	if (backlight)
		radeonfb_bl_init(rinfo);

	printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name);

	if (rinfo->bios_seg)
		radeon_unmap_ROM(rinfo, pdev);
	pr_debug("radeonfb_pci_register END\n");

	return 0;
err_unmap_fb:
	iounmap(rinfo->fb_base);
err_unmap_rom:
	kfree(rinfo->mon1_EDID);
	kfree(rinfo->mon2_EDID);
	if (rinfo->mon1_modedb)
		fb_destroy_modedb(rinfo->mon1_modedb);
	fb_dealloc_cmap(&info->cmap);
#ifdef CONFIG_FB_RADEON_I2C
	radeon_delete_i2c_busses(rinfo);
#endif
	if (rinfo->bios_seg)
		radeon_unmap_ROM(rinfo, pdev);
	iounmap(rinfo->mmio_base);
err_release_pci2:
	pci_release_region(pdev, 2);
err_release_pci0:
	pci_release_region(pdev, 0);
err_release_fb:
        framebuffer_release(info);
err_disable:
err_out:
	return ret;
}