[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#826629: Possible offb unload fix.



On Tue, Oct 4, 2016 at 9:13 PM, Lennart Sorensen
<lsorense@csclub.uwaterloo.ca> wrote:
> On Tue, Oct 04, 2016 at 08:41:45PM +0200, Mathieu Malaterre wrote:
>> Hi Len,
>>
>> Here is the release function I am using:
>>
>> static void offb_destroy(struct fb_info *info)
>> {
>>         struct offb_par *par = (struct offb_par *) info->par;
>>         if (info->screen_base)
>>                 iounmap(info->screen_base);
>>         if (par->cmap_adr != NULL) {
>>                 iounmap(par->cmap_adr);
>>                 par->cmap_adr = NULL;
>>         }
>>         release_mem_region(info->apertures->ranges[0].base,
>> info->apertures->ranges[0].size);
>>         framebuffer_release(info);
>> }
>>
>>
>> (you need the cast to avoid warning about deref of void*).
>>
>> And if I do `modprobe radeonfb`:
>>
>> [   72.163546] bus: 'pci': add driver radeonfb
>> [   72.163618] bus: 'pci': driver_probe_device: matched device
>> 0000:00:10.0 with driver radeonfb
>> [   72.163627] bus: 'pci': really_probe: probing driver radeonfb with
>> device 0000:00:10.0
>> [   72.163651] devices_kset: Moving 0000:00:10.0 to end of list
>> [   72.163659] radeonfb_pci_register BEGIN
>> [   72.163680] radeonfb 0000:00:10.0: enabling device (0006 -> 0007)
>> [   72.163721] radeonfb 0000:00:10.0: BAR 0: can't reserve [mem
>> 0x98000000-0x9fffffff pref]
>> [   72.163726] radeonfb (0000:00:10.0): cannot request region 0.
>> [   72.163746] radeonfb: probe of 0000:00:10.0 failed with error -16
>
> Could you put a print statement in offb_destroy to make sure that is
> actually being called?
>
> And this is radeonfb with code added to actually try to kick out offb,
> right?

Here is what I see:

[   52.270154] bus: 'pci': add driver radeonfb
[   52.270224] bus: 'pci': driver_probe_device: matched device
0000:00:10.0 with driver radeonfb
[   52.270233] bus: 'pci': really_probe: probing driver radeonfb with
device 0000:00:10.0
[   52.270256] devices_kset: Moving 0000:00:10.0 to end of list
[   52.270264] radeonfb_pci_register BEGIN
[   52.270267] radeonfb: MM1
[   52.275001] radeonfb 0000:00:10.0: enabling device (0006 -> 0007)
[   52.279727] radeonfb: MM2
[   52.295202] radeonfb: MM3
[   52.299816] radeonfb: MM4
[   52.304934] radeonfb: MM0 98000000 8000000 radeonfb
[   52.309768] checking generic (9c008000 96000) vs hw (98000000 8000000)
[   52.309776] fb: switching to radeonfb from OFfb ATY,RockHo
[   52.315075] Console: switching to colour dummy device 80x25
[   52.315595] device: 'fb0': device_unregister
[   52.315736] PM: Removing info for No Bus:fb0
[   52.317348] device: 'fb0': device_create_release
[   52.317407] radeonfb: MM5 0
[   52.317447] device: 'vtcon1': device_unregister
[   52.317500] PM: Removing info for No Bus:vtcon1
[   52.317565] device: 'vtcon1': device_create_release
[   52.318992] radeonfb 0000:00:10.0: BAR 0: can't reserve [mem
0x98000000-0x9fffffff pref]
[   52.319029] radeonfb (0000:00:10.0): cannot request region 0.
[   52.319066] radeonfb: probe of 0000:00:10.0 failed with error -16

With patch attached.
diff -ru tmp/linux-4.7.5/drivers/video/fbdev/aty/radeon_base.c linux-4.7.5/drivers/video/fbdev/aty/radeon_base.c
--- tmp/linux-4.7.5/drivers/video/fbdev/aty/radeon_base.c	2016-09-24 10:10:18.000000000 +0200
+++ linux-4.7.5/drivers/video/fbdev/aty/radeon_base.c	2016-10-04 21:17:09.864838492 +0200
@@ -2259,6 +2259,43 @@
 	.read	= radeon_show_edid2,
 };
 
+static int radeon_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+	struct apertures_struct *ap;
+
+	ap = alloc_apertures(1);
+	if (!ap)
+		return -ENOMEM;
+
+	ap->ranges[0].base = pci_resource_start(pdev, 0);
+	ap->ranges[0].size = pci_resource_len(pdev, 0);
+
+		printk(KERN_INFO "radeonfb: MM0 %x %x %s\n", ap->ranges[0].base, ap->ranges[0].size, KBUILD_MODNAME);
+	remove_conflicting_framebuffers(ap, KBUILD_MODNAME, false);
+	//remove_conflicting_framebuffers(ap, KBUILD_MODNAME, true);
+	kfree(ap);
+
+	return 0;
+}
+
+/*static int radeon_kick_out_firmware_fb2(struct pci_dev *pdev)
+{
+	struct apertures_struct *ap;
+
+	ap = alloc_apertures(1);
+	if (!ap)
+		return -ENOMEM;
+
+	ap->ranges[0].base = pci_resource_start(pdev, 0);
+	ap->ranges[0].size = pci_resource_len(pdev, 0);
+
+		printk(KERN_INFO "radeonfb: MM1 %d %d %s\n", ap->ranges[0].base, ap->ranges[0].size, KBUILD_MODNAME);
+	remove_conflicting_framebuffers(ap, KBUILD_MODNAME, false);
+	//remove_conflicting_framebuffers(ap, KBUILD_MODNAME, true);
+	kfree(ap);
+
+	return 0;
+}*/
 
 static int radeonfb_pci_register(struct pci_dev *pdev,
 				 const struct pci_device_id *ent)
@@ -2270,6 +2307,7 @@
 	int err = 0;
 
 	pr_debug("radeonfb_pci_register BEGIN\n");
+		printk(KERN_INFO "radeonfb: MM1\n");
 	
 	/* Enable device in PCI config */
 	ret = pci_enable_device(pdev);
@@ -2278,6 +2316,7 @@
 		       pci_name(pdev));
 		goto err_out;
 	}
+		printk(KERN_INFO "radeonfb: MM2\n");
 
 	info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
 	if (!info) {
@@ -2286,6 +2325,7 @@
 		ret = -ENOMEM;
 		goto err_disable;
 	}
+		printk(KERN_INFO "radeonfb: MM3\n");
 	rinfo = info->par;
 	rinfo->info = info;	
 	rinfo->pdev = pdev;
@@ -2313,6 +2353,13 @@
 	/* Set base addrs */
 	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
 	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+		printk(KERN_INFO "radeonfb: MM4\n");
+
+	//radeon_kick_out_firmware_fb(pdev);
+	ret = radeon_kick_out_firmware_fb(pdev);
+		printk(KERN_INFO "radeonfb: MM5 %d \n", ret);
+	if (ret) return ret;
+
 
 	/* request the mem regions */
 	ret = pci_request_region(pdev, 0, "radeonfb framebuffer");
diff -ru tmp/linux-4.7.5/drivers/video/fbdev/offb.c linux-4.7.5/drivers/video/fbdev/offb.c
--- tmp/linux-4.7.5/drivers/video/fbdev/offb.c	2016-09-24 10:10:18.000000000 +0200
+++ linux-4.7.5/drivers/video/fbdev/offb.c	2016-10-04 21:19:10.002185027 +0200
@@ -133,9 +133,9 @@
 	switch (par->cmap_type) {
 	case cmap_simple:
 		writeb(regno, par->cmap_adr);
-		writeb(red, par->cmap_data);
-		writeb(green, par->cmap_data);
 		writeb(blue, par->cmap_data);
+		writeb(green, par->cmap_data);
+		writeb(red, par->cmap_data);
 		break;
 	case cmap_M3A:
 		/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
@@ -159,6 +159,7 @@
 		/* Set palette index & data (could be smarter) */
 		out_8(par->cmap_adr + 0xb0, regno);
 		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
+		//out_le32(par->cmap_adr + 0xb4, (blue << 16 | green << 8 | red));
 		break;
 	case cmap_gxt2000:
 		out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
@@ -277,8 +278,16 @@
 
 static void offb_destroy(struct fb_info *info)
 {
+	struct offb_par *par = (struct offb_par *) info->par;
+	printk(KERN_INFO " DBG MM4 RockH" );
 	if (info->screen_base)
 		iounmap(info->screen_base);
+	printk(KERN_INFO " DBG MM5 RockH" );
+	if (par->cmap_adr != NULL) {
+		iounmap(par->cmap_adr);
+		par->cmap_adr = NULL;
+	}
+	printk(KERN_INFO " DBG MM6 RockH" );
 	release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
 	framebuffer_release(info);
 }
@@ -338,6 +347,11 @@
 		par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
 		if (par->cmap_adr)
 			par->cmap_type = cmap_radeon;
+	} else if (dp && !strncmp(name, "ATY,RockH", 9)) {
+	printk(KERN_INFO " DBG MM1 RockH" );
+		par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
+		if (par->cmap_adr)
+			par->cmap_type = cmap_radeon;
 	} else if (!strncmp(name, "ATY,", 4)) {
 		unsigned long base = address & 0xff000000UL;
 		par->cmap_adr =


Reply to: