Commit 482982062f1bc25ffb5383ab724d73d1a7af07cf
Committed by
Felipe Balbi
1 parent
034d7c13a7
Exists in
master
and in
6 other branches
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 <hechtb@googlemail.com> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Showing 3 changed files with 18 additions and 14 deletions Side-by-side Diff
drivers/usb/renesas_usbhs/common.c
... | ... | @@ -61,8 +61,8 @@ |
61 | 61 | */ |
62 | 62 | #define usbhs_platform_call(priv, func, args...)\ |
63 | 63 | (!(priv) ? -ENODEV : \ |
64 | - !((priv)->pfunc->func) ? 0 : \ | |
65 | - (priv)->pfunc->func(args)) | |
64 | + !((priv)->pfunc.func) ? 0 : \ | |
65 | + (priv)->pfunc.func(args)) | |
66 | 66 | |
67 | 67 | /* |
68 | 68 | * common functions |
69 | 69 | |
70 | 70 | |
71 | 71 | |
... | ... | @@ -446,24 +446,28 @@ |
446 | 446 | /* |
447 | 447 | * care platform info |
448 | 448 | */ |
449 | - priv->pfunc = &info->platform_callback; | |
450 | - priv->dparam = &info->driver_param; | |
449 | + memcpy(&priv->pfunc, | |
450 | + &info->platform_callback, | |
451 | + sizeof(struct renesas_usbhs_platform_callback)); | |
452 | + memcpy(&priv->dparam, | |
453 | + &info->driver_param, | |
454 | + sizeof(struct renesas_usbhs_driver_param)); | |
451 | 455 | |
452 | 456 | /* set driver callback functions for platform */ |
453 | 457 | dfunc = &info->driver_callback; |
454 | 458 | dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; |
455 | 459 | |
456 | 460 | /* set default param if platform doesn't have */ |
457 | - if (!priv->dparam->pipe_type) { | |
458 | - priv->dparam->pipe_type = usbhsc_default_pipe_type; | |
459 | - priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type); | |
461 | + if (!priv->dparam.pipe_type) { | |
462 | + priv->dparam.pipe_type = usbhsc_default_pipe_type; | |
463 | + priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type); | |
460 | 464 | } |
461 | - if (!priv->dparam->pio_dma_border) | |
462 | - priv->dparam->pio_dma_border = 64; /* 64byte */ | |
465 | + if (!priv->dparam.pio_dma_border) | |
466 | + priv->dparam.pio_dma_border = 64; /* 64byte */ | |
463 | 467 | |
464 | 468 | /* FIXME */ |
465 | 469 | /* runtime power control ? */ |
466 | - if (priv->pfunc->get_vbus) | |
470 | + if (priv->pfunc.get_vbus) | |
467 | 471 | usbhsc_flags_set(priv, USBHSF_RUNTIME_PWCTRL); |
468 | 472 | |
469 | 473 | /* |
drivers/usb/renesas_usbhs/common.h
... | ... | @@ -242,8 +242,8 @@ |
242 | 242 | void __iomem *base; |
243 | 243 | unsigned int irq; |
244 | 244 | |
245 | - struct renesas_usbhs_platform_callback *pfunc; | |
246 | - struct renesas_usbhs_driver_param *dparam; | |
245 | + struct renesas_usbhs_platform_callback pfunc; | |
246 | + struct renesas_usbhs_driver_param dparam; | |
247 | 247 | |
248 | 248 | struct delayed_work notify_hotplug_work; |
249 | 249 | struct platform_device *pdev; |
... | ... | @@ -318,7 +318,7 @@ |
318 | 318 | * data |
319 | 319 | */ |
320 | 320 | struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev); |
321 | -#define usbhs_get_dparam(priv, param) (priv->dparam->param) | |
321 | +#define usbhs_get_dparam(priv, param) (priv->dparam.param) | |
322 | 322 | #define usbhs_priv_to_pdev(priv) (priv->pdev) |
323 | 323 | #define usbhs_priv_to_dev(priv) (&priv->pdev->dev) |
324 | 324 | #define usbhs_priv_to_lock(priv) (&priv->lock) |
drivers/usb/renesas_usbhs/mod.c
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); |
59 | 59 | |
60 | 60 | info->irq_vbus = usbhsm_autonomy_irq_vbus; |
61 | - priv->pfunc->get_vbus = usbhsm_autonomy_get_vbus; | |
61 | + priv->pfunc.get_vbus = usbhsm_autonomy_get_vbus; | |
62 | 62 | |
63 | 63 | usbhs_irq_callback_update(priv, NULL); |
64 | 64 | } |