[PATCH] usb: renesas_usbhs: bugfix: don't modify platform data

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

 



renesas_usbhs has default callback functions and settings.
And it tried overwrite to platform private data
if platform doesn't have them.
So, if renesas_usbhs was compiled as module,
it will be hung-up on 2nd insmod.
This patch fixup it.
Special thanks to Bastian

Reported-by: Bastian Hecht <hechtb@xxxxxxxxxxxxxx>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx>
---
 drivers/usb/renesas_usbhs/common.c |   24 ++++++++++++++----------
 drivers/usb/renesas_usbhs/common.h |    6 +++---
 drivers/usb/renesas_usbhs/mod.c    |    2 +-
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index c3aef40..d2e2efa 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -61,8 +61,8 @@
  */
 #define usbhs_platform_call(priv, func, args...)\
 	(!(priv) ? -ENODEV :			\
-	 !((priv)->pfunc->func) ? 0 :		\
-	 (priv)->pfunc->func(args))
+	 !((priv)->pfunc.func) ? 0 :		\
+	 (priv)->pfunc.func(args))
 
 /*
  *		common functions
@@ -446,24 +446,28 @@ static int __devinit usbhs_probe(struct platform_device *pdev)
 	/*
 	 * care platform info
 	 */
-	priv->pfunc	= &info->platform_callback;
-	priv->dparam	= &info->driver_param;
+	memcpy(&priv->pfunc,
+	       &info->platform_callback,
+	       sizeof(struct renesas_usbhs_platform_callback));
+	memcpy(&priv->dparam,
+	       &info->driver_param,
+	       sizeof(struct renesas_usbhs_driver_param));
 
 	/* set driver callback functions for platform */
 	dfunc			= &info->driver_callback;
 	dfunc->notify_hotplug	= usbhsc_drvcllbck_notify_hotplug;
 
 	/* set default param if platform doesn't have */
-	if (!priv->dparam->pipe_type) {
-		priv->dparam->pipe_type = usbhsc_default_pipe_type;
-		priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type);
+	if (!priv->dparam.pipe_type) {
+		priv->dparam.pipe_type = usbhsc_default_pipe_type;
+		priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type);
 	}
-	if (!priv->dparam->pio_dma_border)
-		priv->dparam->pio_dma_border = 64; /* 64byte */
+	if (!priv->dparam.pio_dma_border)
+		priv->dparam.pio_dma_border = 64; /* 64byte */
 
 	/* FIXME */
 	/* runtime power control ? */
-	if (priv->pfunc->get_vbus)
+	if (priv->pfunc.get_vbus)
 		usbhsc_flags_set(priv, USBHSF_RUNTIME_PWCTRL);
 
 	/*
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index dc9490d..8729da5 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -242,8 +242,8 @@ struct usbhs_priv {
 	void __iomem *base;
 	unsigned int irq;
 
-	struct renesas_usbhs_platform_callback	*pfunc;
-	struct renesas_usbhs_driver_param	*dparam;
+	struct renesas_usbhs_platform_callback	pfunc;
+	struct renesas_usbhs_driver_param	dparam;
 
 	struct delayed_work notify_hotplug_work;
 	struct platform_device *pdev;
@@ -318,7 +318,7 @@ int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum, u16 upphub,
  * data
  */
 struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev);
-#define usbhs_get_dparam(priv, param)	(priv->dparam->param)
+#define usbhs_get_dparam(priv, param)	(priv->dparam.param)
 #define usbhs_priv_to_pdev(priv)	(priv->pdev)
 #define usbhs_priv_to_dev(priv)		(&priv->pdev->dev)
 #define usbhs_priv_to_lock(priv)	(&priv->lock)
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c
index a8a0ba2..5b99632 100644
--- a/drivers/usb/renesas_usbhs/mod.c
+++ b/drivers/usb/renesas_usbhs/mod.c
@@ -58,7 +58,7 @@ void usbhs_mod_autonomy_mode(struct usbhs_priv *priv)
 	struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);
 
 	info->irq_vbus		= usbhsm_autonomy_irq_vbus;
-	priv->pfunc->get_vbus	= usbhsm_autonomy_get_vbus;
+	priv->pfunc.get_vbus	= usbhsm_autonomy_get_vbus;
 
 	usbhs_irq_callback_update(priv, NULL);
 }
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux