From: "Antonino A. Daplas" <adaplas@hotpop.com>

The driver nvidiafb fails to delete the i2c bus on load failure or unload. 
Fix

From: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/video/nvidia/nv_i2c.c   |    2 --
 25-akpm/drivers/video/nvidia/nv_of.c    |    1 +
 25-akpm/drivers/video/nvidia/nv_proto.h |    2 ++
 25-akpm/drivers/video/nvidia/nvidia.c   |    6 ++++--
 4 files changed, 7 insertions(+), 4 deletions(-)

diff -puN drivers/video/nvidia/nv_i2c.c~nvidiafb-delete-i2c-bus-on-driver-unload drivers/video/nvidia/nv_i2c.c
--- 25/drivers/video/nvidia/nv_i2c.c~nvidiafb-delete-i2c-bus-on-driver-unload	2005-03-20 16:05:02.000000000 -0800
+++ 25-akpm/drivers/video/nvidia/nv_i2c.c	2005-03-20 16:05:02.000000000 -0800
@@ -146,7 +146,6 @@ void nvidia_create_i2c_busses(struct nvi
 	nvidia_setup_i2c_bus(&par->chan[2], "BUS3");
 }
 
-#if 0
 void nvidia_delete_i2c_busses(struct nvidia_par *par)
 {
 	if (par->chan[0].par)
@@ -162,7 +161,6 @@ void nvidia_delete_i2c_busses(struct nvi
 	par->chan[2].par = NULL;
 
 }
-#endif  /*  0  */
 
 static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
 {
diff -puN drivers/video/nvidia/nvidia.c~nvidiafb-delete-i2c-bus-on-driver-unload drivers/video/nvidia/nvidia.c
--- 25/drivers/video/nvidia/nvidia.c~nvidiafb-delete-i2c-bus-on-driver-unload	2005-03-20 16:05:02.000000000 -0800
+++ 25-akpm/drivers/video/nvidia/nvidia.c	2005-03-20 16:05:02.000000000 -0800
@@ -1566,8 +1566,9 @@ static int __devinit nvidiafb_probe(stru
 
       err_out_iounmap_fb:
 	iounmap(info->screen_base);
-      err_out_free_base1:
 	fb_destroy_modedb(info->monspecs.modedb);
+	nvidia_delete_i2c_busses(par);
+      err_out_free_base1:
 	iounmap(par->REGS);
       err_out_free_base0:
 	pci_release_regions(pd);
@@ -1597,9 +1598,10 @@ static void __exit nvidiafb_remove(struc
 			 info->fix.smem_len);
 #endif				/* CONFIG_MTRR */
 
+	iounmap(info->screen_base);
 	fb_destroy_modedb(info->monspecs.modedb);
+	nvidia_delete_i2c_busses(par);
 	iounmap(par->REGS);
-	iounmap(info->screen_base);
 	pci_release_regions(pd);
 	pci_disable_device(pd);
 	kfree(info->pixmap.addr);
diff -puN drivers/video/nvidia/nv_of.c~nvidiafb-delete-i2c-bus-on-driver-unload drivers/video/nvidia/nv_of.c
--- 25/drivers/video/nvidia/nv_of.c~nvidiafb-delete-i2c-bus-on-driver-unload	2005-03-20 16:05:02.000000000 -0800
+++ 25-akpm/drivers/video/nvidia/nv_of.c	2005-03-20 16:05:02.000000000 -0800
@@ -28,6 +28,7 @@
 #include "nv_proto.h"
 
 void nvidia_create_i2c_busses(struct nvidia_par *par) {}
+void nvidia_delete_i2c_busses(struct nvidia_par *par) {}
 
 int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid)
 {
diff -puN drivers/video/nvidia/nv_proto.h~nvidiafb-delete-i2c-bus-on-driver-unload drivers/video/nvidia/nv_proto.h
--- 25/drivers/video/nvidia/nv_proto.h~nvidiafb-delete-i2c-bus-on-driver-unload	2005-03-20 16:05:02.000000000 -0800
+++ 25-akpm/drivers/video/nvidia/nv_proto.h	2005-03-20 16:05:02.000000000 -0800
@@ -33,10 +33,12 @@ void NVLockUnlock(struct nvidia_par *par
 /* in nvidia-i2c.c */
 #if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
 void nvidia_create_i2c_busses(struct nvidia_par *par);
+void nvidia_delete_i2c_busses(struct nvidia_par *par);
 int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn,
 			       u8 ** out_edid);
 #else
 #define nvidia_create_i2c_busses(...)
+#define nvidia_delete_i2c_busses(...)
 #define nvidia_probe_i2c_connector(p, c, edid) \
 do {                                           \
 	*(edid) = NULL;                        \
_