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

Configure Feed

Select the types of activity you want to include in your feed.

USB: pxa27x_udc: check return value of clk_enable

clk_enable() may fail according to the API contract.
Previously, udc_enable() ignored its return value and returned void.

Modify udc_enable() to return the error code. Additionally, update
all of its callers (pxa_udc_pullup, pxa_udc_vbus_session,
pxa27x_udc_start, pxa_udc_probe, and pxa_udc_resume) to check
this return value and handle the failure properly with necessary
cleanups or rollbacks.

Signed-off-by: Zhaoyang Yu <2426767509@qq.com>
Link: https://patch.msgid.link/tencent_46693FE6DB434ACFB7412B16F6078AC01A06@qq.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Zhaoyang Yu and committed by
Greg Kroah-Hartman
f2e9bc03 0c8ee850

+53 -15
+53 -15
drivers/usb/gadget/udc/pxa27x_udc.c
··· 1462 1462 return 0; 1463 1463 } 1464 1464 1465 - static void udc_enable(struct pxa_udc *udc); 1465 + static int udc_enable(struct pxa_udc *udc); 1466 1466 static void udc_disable(struct pxa_udc *udc); 1467 1467 1468 1468 /** ··· 1519 1519 static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) 1520 1520 { 1521 1521 struct pxa_udc *udc = to_gadget_udc(_gadget); 1522 + int ret; 1522 1523 1523 1524 if (!udc->gpiod && !udc->udc_command) 1524 1525 return -EOPNOTSUPP; 1525 1526 1526 1527 dplus_pullup(udc, is_active); 1527 1528 1528 - if (should_enable_udc(udc)) 1529 - udc_enable(udc); 1529 + if (should_enable_udc(udc)) { 1530 + ret = udc_enable(udc); 1531 + if (ret) { 1532 + dplus_pullup(udc, !is_active); 1533 + return ret; 1534 + } 1535 + } 1530 1536 if (should_disable_udc(udc)) 1531 1537 udc_disable(udc); 1532 1538 return 0; ··· 1551 1545 static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active) 1552 1546 { 1553 1547 struct pxa_udc *udc = to_gadget_udc(_gadget); 1548 + int ret; 1554 1549 1555 1550 udc->vbus_sensed = is_active; 1556 - if (should_enable_udc(udc)) 1557 - udc_enable(udc); 1551 + if (should_enable_udc(udc)) { 1552 + ret = udc_enable(udc); 1553 + if (ret) { 1554 + udc->vbus_sensed = !is_active; 1555 + return ret; 1556 + } 1557 + } 1558 1558 if (should_disable_udc(udc)) 1559 1559 udc_disable(udc); 1560 1560 ··· 1703 1691 * Enables the udc device : enables clocks, udc interrupts, control endpoint 1704 1692 * interrupts, sets usb as UDC client and setups endpoints. 1705 1693 */ 1706 - static void udc_enable(struct pxa_udc *udc) 1694 + static int udc_enable(struct pxa_udc *udc) 1707 1695 { 1708 - if (udc->enabled) 1709 - return; 1696 + int ret; 1710 1697 1711 - clk_enable(udc->clk); 1698 + if (udc->enabled) 1699 + return 0; 1700 + 1701 + ret = clk_enable(udc->clk); 1702 + if (ret) { 1703 + dev_err(udc->dev, "clk_enable failed: %d\n", ret); 1704 + return ret; 1705 + } 1712 1706 udc_writel(udc, UDCICR0, 0); 1713 1707 udc_writel(udc, UDCICR1, 0); 1714 1708 udc_clear_mask_UDCCR(udc, UDCCR_UDE); ··· 1744 1726 pio_irq_enable(&udc->pxa_ep[0]); 1745 1727 1746 1728 udc->enabled = 1; 1729 + 1730 + return 0; 1747 1731 } 1748 1732 1749 1733 /** ··· 1781 1761 } 1782 1762 } 1783 1763 1784 - if (should_enable_udc(udc)) 1785 - udc_enable(udc); 1764 + if (should_enable_udc(udc)) { 1765 + retval = udc_enable(udc); 1766 + if (retval) 1767 + goto fail_enable; 1768 + } 1786 1769 return 0; 1787 1770 1771 + fail_enable: 1772 + if (!IS_ERR_OR_NULL(udc->transceiver)) 1773 + otg_set_peripheral(udc->transceiver->otg, NULL); 1788 1774 fail: 1789 1775 udc->driver = NULL; 1790 1776 return retval; ··· 2456 2430 goto err_add_gadget; 2457 2431 2458 2432 pxa_init_debugfs(udc); 2459 - if (should_enable_udc(udc)) 2460 - udc_enable(udc); 2433 + if (should_enable_udc(udc)) { 2434 + retval = udc_enable(udc); 2435 + if (retval) 2436 + goto err_enable; 2437 + } 2461 2438 return 0; 2462 2439 2440 + err_enable: 2441 + usb_del_gadget_udc(&udc->gadget); 2442 + pxa_cleanup_debugfs(udc); 2463 2443 err_add_gadget: 2464 2444 if (!IS_ERR_OR_NULL(udc->transceiver)) 2465 2445 usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy); ··· 2541 2509 { 2542 2510 struct pxa_udc *udc = platform_get_drvdata(_dev); 2543 2511 struct pxa_ep *ep; 2512 + int ret; 2544 2513 2545 2514 ep = &udc->pxa_ep[0]; 2546 2515 udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); 2547 2516 2548 2517 dplus_pullup(udc, udc->pullup_resume); 2549 - if (should_enable_udc(udc)) 2550 - udc_enable(udc); 2518 + if (should_enable_udc(udc)) { 2519 + ret = udc_enable(udc); 2520 + if (ret) { 2521 + dplus_pullup(udc, !udc->pullup_resume); 2522 + return ret; 2523 + } 2524 + } 2551 2525 /* 2552 2526 * We do not handle OTG yet. 2553 2527 *