From: Kuninori Morimoto Date: Thu, 13 Oct 2011 04:02:22 +0000 (-0700) Subject: usb: gadget: renesas_usbhs: bugfix: don't modify platform data X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=482982062f1bc25ffb5383ab724d73d1a7af07cf;p=linux-beck.git usb: gadget: renesas_usbhs: bugfix: don't modify platform data 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 Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index c3aef40fa9e5..d2e2efaba658 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 dc9490d1f42f..8729da5c3be6 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 2d3b09d0d846..053f86d70009 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); }