Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: emxx_udc: allow modular build

A change to the usb gadget core allowed certain API functions to be
part of a loadable module, which breaks having emxx_udc built-in:

drivers/staging/built-in.o: In function `nbu2ss_drv_probe':
(.text+0x2428): undefined reference to `usb_ep_set_maxpacket_limit'

The original patch already fixed tons of other cases that have the
added dependency but apparently missed this one that now appears
in an ARM allmodconfig build.

This patch makes the symbol "tristate", which lets the Kconfig
dependency tracking handle it correctly. To make the module
actually usable, I also revert 0af61e66ee16 ("drivers/staging:
make emxx_udc.c explicitly non-modular"), which Paul Gortmaker
added after noticing that the Kconfig symbol was 'bool'.
Compared to the original version however, I leave out the
'__exit' annotation on the remove callback, as Paul pointed
out that this was incorrect.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Fixes: 5a8d651a2bde ("usb: gadget: move gadget API functions to udc-core")
Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Arnd Bergmann and committed by
Greg Kroah-Hartman
0bf048ab 71da2ba2

+33 -5
+1 -1
drivers/staging/emxx_udc/Kconfig
··· 1 1 config USB_EMXX 2 - bool "EMXX USB Function Device Controller" 2 + tristate "EMXX USB Function Device Controller" 3 3 depends on USB_GADGET && (ARCH_SHMOBILE || (ARM && COMPILE_TEST)) 4 4 help 5 5 The Emma Mobile series of SoCs from Renesas Electronics and
+32 -4
drivers/staging/emxx_udc/emxx_udc.c
··· 15 15 */ 16 16 17 17 #include <linux/kernel.h> 18 - #include <linux/init.h> 18 + #include <linux/module.h> 19 19 #include <linux/platform_device.h> 20 20 #include <linux/delay.h> 21 21 #include <linux/ioport.h> ··· 39 39 40 40 #include "emxx_udc.h" 41 41 42 + #define DRIVER_DESC "EMXX UDC driver" 42 43 #define DMA_ADDR_INVALID (~(dma_addr_t)0) 43 44 44 45 static const char driver_name[] = "emxx_udc"; 46 + static const char driver_desc[] = DRIVER_DESC; 45 47 46 48 /*===========================================================================*/ 47 49 /* Prototype */ ··· 3298 3296 } 3299 3297 3300 3298 /*-------------------------------------------------------------------------*/ 3299 + static int nbu2ss_drv_remove(struct platform_device *pdev) 3300 + { 3301 + struct nbu2ss_udc *udc; 3302 + struct nbu2ss_ep *ep; 3303 + int i; 3304 + 3305 + udc = &udc_controller; 3306 + 3307 + for (i = 0; i < NUM_ENDPOINTS; i++) { 3308 + ep = &udc->ep[i]; 3309 + if (ep->virt_buf) 3310 + dma_free_coherent(NULL, PAGE_SIZE, 3311 + (void *)ep->virt_buf, ep->phys_buf); 3312 + } 3313 + 3314 + /* Interrupt Handler - Release */ 3315 + free_irq(INT_VBUS, udc); 3316 + 3317 + return 0; 3318 + } 3319 + 3320 + /*-------------------------------------------------------------------------*/ 3301 3321 static int nbu2ss_drv_suspend(struct platform_device *pdev, pm_message_t state) 3302 3322 { 3303 3323 struct nbu2ss_udc *udc; ··· 3371 3347 static struct platform_driver udc_driver = { 3372 3348 .probe = nbu2ss_drv_probe, 3373 3349 .shutdown = nbu2ss_drv_shutdown, 3350 + .remove = nbu2ss_drv_remove, 3374 3351 .suspend = nbu2ss_drv_suspend, 3375 3352 .resume = nbu2ss_drv_resume, 3376 3353 .driver = { 3377 - .name = driver_name, 3378 - .suppress_bind_attrs = true, 3354 + .name = driver_name, 3379 3355 }, 3380 3356 }; 3381 3357 3382 - builtin_platform_driver(udc_driver); 3358 + module_platform_driver(udc_driver); 3359 + 3360 + MODULE_DESCRIPTION(DRIVER_DESC); 3361 + MODULE_AUTHOR("Renesas Electronics Corporation"); 3362 + MODULE_LICENSE("GPL");