Merge "USB: Debugfs: Fix compilation issues when debugfs is disabled"
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index bccc504..effe0fd 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -837,17 +837,28 @@
 struct dentry *dent_diag;
 static void fdiag_debugfs_init(void)
 {
+	struct dentry *dent_diag_status;
 	dent_diag = debugfs_create_dir("usb_diag", 0);
-	if (IS_ERR(dent_diag))
+	if (!dent_diag || IS_ERR(dent_diag))
 		return;
 
-	debugfs_create_file("status", 0444, dent_diag, 0, &debug_fdiag_ops);
+	dent_diag_status = debugfs_create_file("status", 0444, dent_diag, 0,
+			&debug_fdiag_ops);
+
+	if (!dent_diag_status || IS_ERR(dent_diag_status)) {
+		debugfs_remove(dent_diag);
+		dent_diag = NULL;
+		return;
+	}
+}
+
+static void fdiag_debugfs_remove(void)
+{
+	debugfs_remove_recursive(dent_diag);
 }
 #else
-static void fdiag_debugfs_init(void)
-{
-	return;
-}
+static inline void fdiag_debugfs_init(void) {}
+static inline void fdiag_debugfs_remove(void) {}
 #endif
 
 static void diag_cleanup(void)
@@ -856,7 +867,7 @@
 	struct usb_diag_ch *_ch;
 	unsigned long flags;
 
-	debugfs_remove_recursive(dent_diag);
+	fdiag_debugfs_remove();
 
 	list_for_each_safe(act, tmp, &usb_diag_ch_list) {
 		_ch = list_entry(act, struct usb_diag_ch, list);
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 6bfa203..2fa8c63 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -1219,6 +1219,7 @@
 	for (i = 0; i < nr_rmnet_ports; i++)
 		kfree(rmnet_ports[i].port);
 
+	gbam_cleanup();
 	nr_rmnet_ports = 0;
 	no_ctrl_smd_ports = 0;
 	no_ctrl_qti_ports = 0;
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index 8aec34f..74a8062 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1267,19 +1267,17 @@
 };
 
 struct dentry *dent_smd;
-struct dentry *dent_smd_status;
-
 static void rmnet_smd_debugfs_init(struct rmnet_smd_dev *dev)
 {
-
+	struct dentry *dent_smd_status;
 	dent_smd = debugfs_create_dir("usb_rmnet_smd", 0);
-	if (IS_ERR(dent_smd))
+	if (!dent_smd || IS_ERR(dent_smd))
 		return;
 
 	dent_smd_status = debugfs_create_file("status", 0444, dent_smd, dev,
 			&rmnet_smd_debug_stats_ops);
 
-	if (!dent_smd_status) {
+	if (!dent_smd_status || IS_ERR(dent_smd_status)) {
 		debugfs_remove(dent_smd);
 		dent_smd = NULL;
 		return;
@@ -1287,8 +1285,14 @@
 
 	return;
 }
+
+static void rmnet_smd_debugfs_remove(void)
+{
+	debugfs_remove_recursive(dent_smd);
+}
 #else
-static void rmnet_smd_debugfs_init(struct rmnet_smd_dev *dev) {}
+static inline void rmnet_smd_debugfs_init(struct rmnet_smd_dev *dev) {}
+static inline void rmnet_smd_debugfs_remove(void){}
 #endif
 
 static void
@@ -1307,7 +1311,9 @@
 	dev->epout = dev->epin = dev->epnotify = NULL; /* release endpoints */
 
 	destroy_workqueue(dev->wq);
-	debugfs_remove_recursive(dent_smd);
+
+	rmnet_smd_debugfs_remove();
+
 	kfree(dev);
 
 }
diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c
index aa6c99a..2fc758d 100644
--- a/drivers/usb/gadget/f_rmnet_smd_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2011 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011,2013 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1758,16 +1758,28 @@
 
 static void rmnet_mux_debugfs_init(struct rmnet_mux_dev *dev)
 {
-
+	struct dentry *dent_rmnet_mux_status;
 	dent_rmnet_mux = debugfs_create_dir("usb_rmnet_mux", 0);
-	if (IS_ERR(dent_rmnet_mux))
+	if (!dent_rmnet_mux || IS_ERR(dent_rmnet_mux))
 		return;
 
-	debugfs_create_file("status", 0444, dent_rmnet_mux, dev,
+	dent_rmnet_mux_status = debugfs_create_file("status",
+			0444, dent_rmnet_mux, dev,
 			&rmnet_mux_svlte_debug_stats_ops);
+	if (!dent_rmnet_mux_status) {
+		debugfs_remove(dent_rmnet_mux);
+		dent_rmnet_mux = NULL;
+		return;
+	}
+}
+
+static void rmnet_mux_debugfs_remove(void)
+{
+	debugfs_remove_recursive(dent_rmnet_mux);
 }
 #else
-static void rmnet_mux_debugfs_init(struct rmnet_mux_dev *dev) {}
+static inline void rmnet_mux_debugfs_init(struct rmnet_mux_dev *dev) {}
+static inline void rmnet_mux_debugfs_remove(void) {}
 #endif
 
 int usb_rmnet_mux_ctrl_open(struct inode *inode, struct file *fp)
@@ -2037,7 +2049,7 @@
 	struct rmnet_mux_dev *dev = rmux_dev;
 	struct rmnet_mux_smd_dev *smd_dev = &dev->smd_dev;
 
-	debugfs_remove_recursive(dent_rmnet_mux);
+	rmnet_mux_debugfs_remove();
 	misc_deregister(&rmnet_mux_ctrl_dev);
 	smd_close(smd_dev->smd_data.ch);
 	destroy_workqueue(dev->wq);
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index b0b2f56..843c207 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -1281,22 +1281,30 @@
 	.write = gbam_reset_stats,
 };
 
+struct dentry *gbam_dent;
 static void gbam_debugfs_init(void)
 {
-	struct dentry *dent;
 	struct dentry *dfile;
 
-	dent = debugfs_create_dir("usb_rmnet", 0);
-	if (IS_ERR(dent))
+	gbam_dent = debugfs_create_dir("usb_rmnet", 0);
+	if (!gbam_dent || IS_ERR(gbam_dent))
 		return;
 
-	/* TODO: Implement cleanup function to remove created file */
-	dfile = debugfs_create_file("status", 0444, dent, 0, &gbam_stats_ops);
-	if (!dfile || IS_ERR(dfile))
-		debugfs_remove(dent);
+	dfile = debugfs_create_file("status", 0444, gbam_dent, 0,
+			&gbam_stats_ops);
+	if (!dfile || IS_ERR(dfile)) {
+		debugfs_remove(gbam_dent);
+		gbam_dent = NULL;
+		return;
+	}
+}
+static void gbam_debugfs_remove(void)
+{
+	debugfs_remove_recursive(gbam_dent);
 }
 #else
-static void gam_debugfs_init(void) { }
+static inline void gbam_debugfs_init(void) {}
+static inline void gbam_debugfs_remove(void) {}
 #endif
 
 void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
@@ -1445,7 +1453,6 @@
 
 	d->trans = trans;
 	queue_work(gbam_wq, &port->connect_w);
-
 	return 0;
 }
 
@@ -1490,6 +1497,7 @@
 			goto free_bam_ports;
 		}
 	}
+
 	gbam_debugfs_init();
 	return 0;
 
@@ -1503,6 +1511,11 @@
 	return ret;
 }
 
+void gbam_cleanup(void)
+{
+	gbam_debugfs_remove();
+}
+
 void gbam_suspend(struct grmnet *gr, u8 port_num, enum transport_type trans)
 {
 	struct gbam_port	*port;
diff --git a/drivers/usb/gadget/u_ctrl_hsuart.c b/drivers/usb/gadget/u_ctrl_hsuart.c
index 3443d12..b57e4e3 100644
--- a/drivers/usb/gadget/u_ctrl_hsuart.c
+++ b/drivers/usb/gadget/u_ctrl_hsuart.c
@@ -479,6 +479,7 @@
 	return ret;
 }
 
+#if defined(CONFIG_DEBUG_FS)
 #define DEBUG_BUF_SIZE	1024
 static ssize_t ghsuart_ctrl_read_stats(struct file *file, char __user *ubuf,
 		size_t count, loff_t *ppos)
@@ -558,7 +559,7 @@
 
 	ghsuart_ctrl_dfile =
 		debugfs_create_file("status", S_IRUGO | S_IWUSR,
-				ghsuart_ctrl_dent, 0, &gctrl_stats_ops);
+				ghsuart_ctrl_dent, 0, &ghsuart_ctrl_stats_ops);
 	if (!ghsuart_ctrl_dfile || IS_ERR(ghsuart_ctrl_dfile)) {
 		debugfs_remove(ghsuart_ctrl_dent);
 		ghsuart_ctrl_dent = NULL;
@@ -571,6 +572,10 @@
 {
 	debugfs_remove_recursive(ghsuart_ctrl_dent);
 }
+#else
+static int ghsuart_ctrl_debugfs_init(void) { return 0; }
+static void ghsuart_ctrl_debugfs_exit(void) {}
+#endif
 
 static int __init ghsuart_ctrl_init(void)
 {
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index 06471a4..6a80529 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -54,6 +54,7 @@
 };
 
 int gbam_setup(unsigned int no_bam_port, unsigned int no_bam2bam_port);
+void gbam_cleanup(void);
 int gbam_connect(struct grmnet *gr, u8 port_num,
 	enum transport_type trans, u8 src_connection_idx,
 	u8 dst_connection_idx);
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 350e723..299f620c 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 David Brownell
  * Copyright (C) 2008 by Nokia Corporation
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
  *
  * This code also borrows from usbserial.c, which is
  * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
@@ -1294,22 +1295,29 @@
 	.read = debug_read_status,
 };
 
+struct dentry *gs_dent;
 static void usb_debugfs_init(struct gs_port *ui_dev, int port_num)
 {
-	struct dentry *dent;
 	char buf[48];
 
 	snprintf(buf, 48, "usb_serial%d", port_num);
-	dent = debugfs_create_dir(buf, 0);
-	if (IS_ERR(dent))
+	gs_dent = debugfs_create_dir(buf, 0);
+	if (!gs_dent || IS_ERR(gs_dent))
 		return;
 
-	debugfs_create_file("readstatus", 0444, dent, ui_dev, &debug_adb_ops);
+	debugfs_create_file("readstatus", 0444, gs_dent, ui_dev,
+			&debug_adb_ops);
 	debugfs_create_file("reset", S_IRUGO | S_IWUSR,
-			dent, ui_dev, &debug_rst_ops);
+			gs_dent, ui_dev, &debug_rst_ops);
+}
+
+static void usb_debugfs_remove(void)
+{
+	debugfs_remove_recursive(gs_dent);
 }
 #else
-static void usb_debugfs_init(struct gs_port *ui_dev) {}
+static inline void usb_debugfs_init(struct gs_port *ui_dev, int port_num) {}
+static inline void usb_debugfs_remove(void) {}
 #endif
 
 /**
@@ -1474,6 +1482,7 @@
 	}
 	n_ports = 0;
 
+	usb_debugfs_remove();
 	destroy_workqueue(gserial_wq);
 	tty_unregister_driver(gs_tty_driver);
 	put_tty_driver(gs_tty_driver);