18bd5741eSChristian Lamparter // SPDX-License-Identifier: GPL-2.0 28bd5741eSChristian Lamparter /* Copyright (C) 2019-2020 Linaro Limited */ 38bd5741eSChristian Lamparter 48bd5741eSChristian Lamparter #include <linux/acpi.h> 58bd5741eSChristian Lamparter #include <linux/firmware.h> 68bd5741eSChristian Lamparter #include <linux/module.h> 78bd5741eSChristian Lamparter #include <linux/pci.h> 88bd5741eSChristian Lamparter #include <linux/slab.h> 98bd5741eSChristian Lamparter #include <linux/unaligned/access_ok.h> 108bd5741eSChristian Lamparter 118bd5741eSChristian Lamparter #include "xhci.h" 128bd5741eSChristian Lamparter #include "xhci-trace.h" 138bd5741eSChristian Lamparter #include "xhci-pci.h" 148bd5741eSChristian Lamparter 158bd5741eSChristian Lamparter #define RENESAS_FW_VERSION 0x6C 168bd5741eSChristian Lamparter #define RENESAS_ROM_CONFIG 0xF0 178bd5741eSChristian Lamparter #define RENESAS_FW_STATUS 0xF4 188bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_MSB 0xF5 198bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS 0xF6 208bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_MSB 0xF7 218bd5741eSChristian Lamparter #define RENESAS_DATA0 0xF8 228bd5741eSChristian Lamparter #define RENESAS_DATA1 0xFC 238bd5741eSChristian Lamparter 248bd5741eSChristian Lamparter #define RENESAS_FW_VERSION_FIELD GENMASK(23, 7) 258bd5741eSChristian Lamparter #define RENESAS_FW_VERSION_OFFSET 8 268bd5741eSChristian Lamparter 278bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_DOWNLOAD_ENABLE BIT(0) 288bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_LOCK BIT(1) 298bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_RESULT GENMASK(6, 4) 308bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_INVALID 0 318bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_SUCCESS BIT(4) 328bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_ERROR BIT(5) 338bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_SET_DATA0 BIT(8) 348bd5741eSChristian Lamparter #define RENESAS_FW_STATUS_SET_DATA1 BIT(9) 358bd5741eSChristian Lamparter 368bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_ACCESS BIT(0) 378bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_ERASE BIT(1) 388bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_RELOAD BIT(2) 398bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_RESULT GENMASK(6, 4) 408bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_NO_RESULT 0 418bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_SUCCESS BIT(4) 428bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_ERROR BIT(5) 438bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_SET_DATA0 BIT(8) 448bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_SET_DATA1 BIT(9) 458bd5741eSChristian Lamparter #define RENESAS_ROM_STATUS_ROM_EXISTS BIT(15) 468bd5741eSChristian Lamparter 478bd5741eSChristian Lamparter #define RENESAS_ROM_ERASE_MAGIC 0x5A65726F 488bd5741eSChristian Lamparter #define RENESAS_ROM_WRITE_MAGIC 0x53524F4D 498bd5741eSChristian Lamparter 508bd5741eSChristian Lamparter #define RENESAS_RETRY 10000 518bd5741eSChristian Lamparter #define RENESAS_DELAY 10 528bd5741eSChristian Lamparter 538bd5741eSChristian Lamparter static int renesas_fw_download_image(struct pci_dev *dev, 548bd5741eSChristian Lamparter const u32 *fw, size_t step) 558bd5741eSChristian Lamparter { 568bd5741eSChristian Lamparter size_t i; 578bd5741eSChristian Lamparter int err; 588bd5741eSChristian Lamparter u8 fw_status; 598bd5741eSChristian Lamparter bool data0_or_data1; 608bd5741eSChristian Lamparter 618bd5741eSChristian Lamparter /* 628bd5741eSChristian Lamparter * The hardware does alternate between two 32-bit pages. 638bd5741eSChristian Lamparter * (This is because each row of the firmware is 8 bytes). 648bd5741eSChristian Lamparter * 658bd5741eSChristian Lamparter * for even steps we use DATA0, for odd steps DATA1. 668bd5741eSChristian Lamparter */ 678bd5741eSChristian Lamparter data0_or_data1 = (step & 1) == 1; 688bd5741eSChristian Lamparter 698bd5741eSChristian Lamparter /* step+1. Read "Set DATAX" and confirm it is cleared. */ 708bd5741eSChristian Lamparter for (i = 0; i < RENESAS_RETRY; i++) { 718bd5741eSChristian Lamparter err = pci_read_config_byte(dev, RENESAS_FW_STATUS_MSB, 728bd5741eSChristian Lamparter &fw_status); 738bd5741eSChristian Lamparter if (err) { 748bd5741eSChristian Lamparter dev_err(&dev->dev, "Read Status failed: %d\n", 758bd5741eSChristian Lamparter pcibios_err_to_errno(err)); 768bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 778bd5741eSChristian Lamparter } 788bd5741eSChristian Lamparter if (!(fw_status & BIT(data0_or_data1))) 798bd5741eSChristian Lamparter break; 808bd5741eSChristian Lamparter 818bd5741eSChristian Lamparter udelay(RENESAS_DELAY); 828bd5741eSChristian Lamparter } 838bd5741eSChristian Lamparter if (i == RENESAS_RETRY) { 848bd5741eSChristian Lamparter dev_err(&dev->dev, "Timeout for Set DATAX step: %zd\n", step); 858bd5741eSChristian Lamparter return -ETIMEDOUT; 868bd5741eSChristian Lamparter } 878bd5741eSChristian Lamparter 888bd5741eSChristian Lamparter /* 898bd5741eSChristian Lamparter * step+2. Write FW data to "DATAX". 908bd5741eSChristian Lamparter * "LSB is left" => force little endian 918bd5741eSChristian Lamparter */ 928bd5741eSChristian Lamparter err = pci_write_config_dword(dev, data0_or_data1 ? 938bd5741eSChristian Lamparter RENESAS_DATA1 : RENESAS_DATA0, 948bd5741eSChristian Lamparter (__force u32)cpu_to_le32(fw[step])); 958bd5741eSChristian Lamparter if (err) { 968bd5741eSChristian Lamparter dev_err(&dev->dev, "Write to DATAX failed: %d\n", 978bd5741eSChristian Lamparter pcibios_err_to_errno(err)); 988bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 998bd5741eSChristian Lamparter } 1008bd5741eSChristian Lamparter 1018bd5741eSChristian Lamparter udelay(100); 1028bd5741eSChristian Lamparter 1038bd5741eSChristian Lamparter /* step+3. Set "Set DATAX". */ 1048bd5741eSChristian Lamparter err = pci_write_config_byte(dev, RENESAS_FW_STATUS_MSB, 1058bd5741eSChristian Lamparter BIT(data0_or_data1)); 1068bd5741eSChristian Lamparter if (err) { 1078bd5741eSChristian Lamparter dev_err(&dev->dev, "Write config for DATAX failed: %d\n", 1088bd5741eSChristian Lamparter pcibios_err_to_errno(err)); 1098bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 1108bd5741eSChristian Lamparter } 1118bd5741eSChristian Lamparter 1128bd5741eSChristian Lamparter return 0; 1138bd5741eSChristian Lamparter } 1148bd5741eSChristian Lamparter 1158bd5741eSChristian Lamparter static int renesas_fw_verify(const void *fw_data, 1168bd5741eSChristian Lamparter size_t length) 1178bd5741eSChristian Lamparter { 1188bd5741eSChristian Lamparter u16 fw_version_pointer; 1198bd5741eSChristian Lamparter u16 fw_version; 1208bd5741eSChristian Lamparter 1218bd5741eSChristian Lamparter /* 1228bd5741eSChristian Lamparter * The Firmware's Data Format is describe in 1238bd5741eSChristian Lamparter * "6.3 Data Format" R19UH0078EJ0500 Rev.5.00 page 124 1248bd5741eSChristian Lamparter */ 1258bd5741eSChristian Lamparter 1268bd5741eSChristian Lamparter /* 1278bd5741eSChristian Lamparter * The bootrom chips of the big brother have sizes up to 64k, let's 1288bd5741eSChristian Lamparter * assume that's the biggest the firmware can get. 1298bd5741eSChristian Lamparter */ 1308bd5741eSChristian Lamparter if (length < 0x1000 || length >= 0x10000) { 1318bd5741eSChristian Lamparter pr_err("firmware is size %zd is not (4k - 64k).", 1328bd5741eSChristian Lamparter length); 1338bd5741eSChristian Lamparter return -EINVAL; 1348bd5741eSChristian Lamparter } 1358bd5741eSChristian Lamparter 1368bd5741eSChristian Lamparter /* The First 2 bytes are fixed value (55aa). "LSB on Left" */ 1378bd5741eSChristian Lamparter if (get_unaligned_le16(fw_data) != 0x55aa) { 1388bd5741eSChristian Lamparter pr_err("no valid firmware header found."); 1398bd5741eSChristian Lamparter return -EINVAL; 1408bd5741eSChristian Lamparter } 1418bd5741eSChristian Lamparter 1428bd5741eSChristian Lamparter /* verify the firmware version position and print it. */ 1438bd5741eSChristian Lamparter fw_version_pointer = get_unaligned_le16(fw_data + 4); 1448bd5741eSChristian Lamparter if (fw_version_pointer + 2 >= length) { 1458bd5741eSChristian Lamparter pr_err("fw ver pointer is outside of the firmware image"); 1468bd5741eSChristian Lamparter return -EINVAL; 1478bd5741eSChristian Lamparter } 1488bd5741eSChristian Lamparter 1498bd5741eSChristian Lamparter fw_version = get_unaligned_le16(fw_data + fw_version_pointer); 1508bd5741eSChristian Lamparter pr_err("got firmware version: %02x.", fw_version); 1518bd5741eSChristian Lamparter 1528bd5741eSChristian Lamparter return 0; 1538bd5741eSChristian Lamparter } 1548bd5741eSChristian Lamparter 1558bd5741eSChristian Lamparter static int renesas_fw_check_running(struct pci_dev *pdev) 1568bd5741eSChristian Lamparter { 1578bd5741eSChristian Lamparter int err; 1588bd5741eSChristian Lamparter u8 fw_state; 1598bd5741eSChristian Lamparter 1608bd5741eSChristian Lamparter /* 1618bd5741eSChristian Lamparter * Test if the device is actually needing the firmware. As most 1628bd5741eSChristian Lamparter * BIOSes will initialize the device for us. If the device is 1638bd5741eSChristian Lamparter * initialized. 1648bd5741eSChristian Lamparter */ 1658bd5741eSChristian Lamparter err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_state); 1668bd5741eSChristian Lamparter if (err) 1678bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 1688bd5741eSChristian Lamparter 1698bd5741eSChristian Lamparter /* 1708bd5741eSChristian Lamparter * Check if "FW Download Lock" is locked. If it is and the FW is 1718bd5741eSChristian Lamparter * ready we can simply continue. If the FW is not ready, we have 1728bd5741eSChristian Lamparter * to give up. 1738bd5741eSChristian Lamparter */ 1748bd5741eSChristian Lamparter if (fw_state & RENESAS_FW_STATUS_LOCK) { 1758bd5741eSChristian Lamparter dev_dbg(&pdev->dev, "FW Download Lock is engaged."); 1768bd5741eSChristian Lamparter 1778bd5741eSChristian Lamparter if (fw_state & RENESAS_FW_STATUS_SUCCESS) 1788bd5741eSChristian Lamparter return 0; 1798bd5741eSChristian Lamparter 1808bd5741eSChristian Lamparter dev_err(&pdev->dev, 1818bd5741eSChristian Lamparter "FW Download Lock is set and FW is not ready. Giving Up."); 1828bd5741eSChristian Lamparter return -EIO; 1838bd5741eSChristian Lamparter } 1848bd5741eSChristian Lamparter 1858bd5741eSChristian Lamparter /* 1868bd5741eSChristian Lamparter * Check if "FW Download Enable" is set. If someone (us?) tampered 1878bd5741eSChristian Lamparter * with it and it can't be reset, we have to give up too... and 1888bd5741eSChristian Lamparter * ask for a forgiveness and a reboot. 1898bd5741eSChristian Lamparter */ 1908bd5741eSChristian Lamparter if (fw_state & RENESAS_FW_STATUS_DOWNLOAD_ENABLE) { 1918bd5741eSChristian Lamparter dev_err(&pdev->dev, 1928bd5741eSChristian Lamparter "FW Download Enable is stale. Giving Up (poweroff/reboot needed)."); 1938bd5741eSChristian Lamparter return -EIO; 1948bd5741eSChristian Lamparter } 1958bd5741eSChristian Lamparter 1968bd5741eSChristian Lamparter /* Otherwise, Check the "Result Code" Bits (6:4) and act accordingly */ 1978bd5741eSChristian Lamparter switch (fw_state & RENESAS_FW_STATUS_RESULT) { 1988bd5741eSChristian Lamparter case 0: /* No result yet */ 1998bd5741eSChristian Lamparter dev_dbg(&pdev->dev, "FW is not ready/loaded yet."); 2008bd5741eSChristian Lamparter 2018bd5741eSChristian Lamparter /* tell the caller, that this device needs the firmware. */ 2028bd5741eSChristian Lamparter return 1; 2038bd5741eSChristian Lamparter 2048bd5741eSChristian Lamparter case RENESAS_FW_STATUS_SUCCESS: /* Success, device should be working. */ 2058bd5741eSChristian Lamparter dev_dbg(&pdev->dev, "FW is ready."); 2068bd5741eSChristian Lamparter return 0; 2078bd5741eSChristian Lamparter 2088bd5741eSChristian Lamparter case RENESAS_FW_STATUS_ERROR: /* Error State */ 2098bd5741eSChristian Lamparter dev_err(&pdev->dev, 2108bd5741eSChristian Lamparter "hardware is in an error state. Giving up (poweroff/reboot needed)."); 2118bd5741eSChristian Lamparter return -ENODEV; 2128bd5741eSChristian Lamparter 2138bd5741eSChristian Lamparter default: /* All other states are marked as "Reserved states" */ 2148bd5741eSChristian Lamparter dev_err(&pdev->dev, 2158bd5741eSChristian Lamparter "hardware is in an invalid state %lx. Giving up (poweroff/reboot needed).", 2168bd5741eSChristian Lamparter (fw_state & RENESAS_FW_STATUS_RESULT) >> 4); 2178bd5741eSChristian Lamparter return -EINVAL; 2188bd5741eSChristian Lamparter } 2198bd5741eSChristian Lamparter } 2208bd5741eSChristian Lamparter 2218bd5741eSChristian Lamparter static int renesas_fw_download(struct pci_dev *pdev, 2228bd5741eSChristian Lamparter const struct firmware *fw) 2238bd5741eSChristian Lamparter { 2248bd5741eSChristian Lamparter const u32 *fw_data = (const u32 *)fw->data; 2258bd5741eSChristian Lamparter size_t i; 2268bd5741eSChristian Lamparter int err; 2278bd5741eSChristian Lamparter u8 fw_status; 2288bd5741eSChristian Lamparter 2298bd5741eSChristian Lamparter /* 2308bd5741eSChristian Lamparter * For more information and the big picture: please look at the 2318bd5741eSChristian Lamparter * "Firmware Download Sequence" in "7.1 FW Download Interface" 2328bd5741eSChristian Lamparter * of R19UH0078EJ0500 Rev.5.00 page 131 2338bd5741eSChristian Lamparter */ 2348bd5741eSChristian Lamparter 2358bd5741eSChristian Lamparter /* 2368bd5741eSChristian Lamparter * 0. Set "FW Download Enable" bit in the 2378bd5741eSChristian Lamparter * "FW Download Control & Status Register" at 0xF4 2388bd5741eSChristian Lamparter */ 2398bd5741eSChristian Lamparter err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, 2408bd5741eSChristian Lamparter RENESAS_FW_STATUS_DOWNLOAD_ENABLE); 2418bd5741eSChristian Lamparter if (err) 2428bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 2438bd5741eSChristian Lamparter 2448bd5741eSChristian Lamparter /* 1 - 10 follow one step after the other. */ 2458bd5741eSChristian Lamparter for (i = 0; i < fw->size / 4; i++) { 2468bd5741eSChristian Lamparter err = renesas_fw_download_image(pdev, fw_data, i); 2478bd5741eSChristian Lamparter if (err) { 2488bd5741eSChristian Lamparter dev_err(&pdev->dev, 2498bd5741eSChristian Lamparter "Firmware Download Step %zd failed at position %zd bytes with (%d).", 2508bd5741eSChristian Lamparter i, i * 4, err); 2518bd5741eSChristian Lamparter return err; 2528bd5741eSChristian Lamparter } 2538bd5741eSChristian Lamparter } 2548bd5741eSChristian Lamparter 2558bd5741eSChristian Lamparter /* 2568bd5741eSChristian Lamparter * This sequence continues until the last data is written to 2578bd5741eSChristian Lamparter * "DATA0" or "DATA1". Naturally, we wait until "SET DATA0/1" 2588bd5741eSChristian Lamparter * is cleared by the hardware beforehand. 2598bd5741eSChristian Lamparter */ 2608bd5741eSChristian Lamparter for (i = 0; i < RENESAS_RETRY; i++) { 2618bd5741eSChristian Lamparter err = pci_read_config_byte(pdev, RENESAS_FW_STATUS_MSB, 2628bd5741eSChristian Lamparter &fw_status); 2638bd5741eSChristian Lamparter if (err) 2648bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 2658bd5741eSChristian Lamparter if (!(fw_status & (BIT(0) | BIT(1)))) 2668bd5741eSChristian Lamparter break; 2678bd5741eSChristian Lamparter 2688bd5741eSChristian Lamparter udelay(RENESAS_DELAY); 2698bd5741eSChristian Lamparter } 2708bd5741eSChristian Lamparter if (i == RENESAS_RETRY) 2718bd5741eSChristian Lamparter dev_warn(&pdev->dev, "Final Firmware Download step timed out."); 2728bd5741eSChristian Lamparter 2738bd5741eSChristian Lamparter /* 2748bd5741eSChristian Lamparter * 11. After finishing writing the last data of FW, the 2758bd5741eSChristian Lamparter * System Software must clear "FW Download Enable" 2768bd5741eSChristian Lamparter */ 2778bd5741eSChristian Lamparter err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, 0); 2788bd5741eSChristian Lamparter if (err) 2798bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 2808bd5741eSChristian Lamparter 2818bd5741eSChristian Lamparter /* 12. Read "Result Code" and confirm it is good. */ 2828bd5741eSChristian Lamparter for (i = 0; i < RENESAS_RETRY; i++) { 2838bd5741eSChristian Lamparter err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_status); 2848bd5741eSChristian Lamparter if (err) 2858bd5741eSChristian Lamparter return pcibios_err_to_errno(err); 2868bd5741eSChristian Lamparter if (fw_status & RENESAS_FW_STATUS_SUCCESS) 2878bd5741eSChristian Lamparter break; 2888bd5741eSChristian Lamparter 2898bd5741eSChristian Lamparter udelay(RENESAS_DELAY); 2908bd5741eSChristian Lamparter } 2918bd5741eSChristian Lamparter if (i == RENESAS_RETRY) { 2928bd5741eSChristian Lamparter /* Timed out / Error - let's see if we can fix this */ 2938bd5741eSChristian Lamparter err = renesas_fw_check_running(pdev); 2948bd5741eSChristian Lamparter switch (err) { 2958bd5741eSChristian Lamparter case 0: /* 2968bd5741eSChristian Lamparter * we shouldn't end up here. 2978bd5741eSChristian Lamparter * maybe it took a little bit longer. 2988bd5741eSChristian Lamparter * But all should be well? 2998bd5741eSChristian Lamparter */ 3008bd5741eSChristian Lamparter break; 3018bd5741eSChristian Lamparter 3028bd5741eSChristian Lamparter case 1: /* (No result yet! */ 3038bd5741eSChristian Lamparter dev_err(&pdev->dev, "FW Load timedout"); 3048bd5741eSChristian Lamparter return -ETIMEDOUT; 3058bd5741eSChristian Lamparter 3068bd5741eSChristian Lamparter default: 3078bd5741eSChristian Lamparter return err; 3088bd5741eSChristian Lamparter } 3098bd5741eSChristian Lamparter } 3108bd5741eSChristian Lamparter 3118bd5741eSChristian Lamparter return 0; 3128bd5741eSChristian Lamparter } 3138bd5741eSChristian Lamparter 3148bd5741eSChristian Lamparter static int renesas_load_fw(struct pci_dev *pdev, const struct firmware *fw) 3158bd5741eSChristian Lamparter { 3168bd5741eSChristian Lamparter int err = 0; 3178bd5741eSChristian Lamparter 3188bd5741eSChristian Lamparter err = renesas_fw_download(pdev, fw); 3198bd5741eSChristian Lamparter if (err) 3208bd5741eSChristian Lamparter dev_err(&pdev->dev, "firmware failed to download (%d).", err); 3218bd5741eSChristian Lamparter return err; 3228bd5741eSChristian Lamparter } 3238bd5741eSChristian Lamparter 3248bd5741eSChristian Lamparter int renesas_xhci_check_request_fw(struct pci_dev *pdev, 3258bd5741eSChristian Lamparter const struct pci_device_id *id) 3268bd5741eSChristian Lamparter { 3278bd5741eSChristian Lamparter struct xhci_driver_data *driver_data = 3288bd5741eSChristian Lamparter (struct xhci_driver_data *)id->driver_data; 3298bd5741eSChristian Lamparter const char *fw_name = driver_data->firmware; 3308bd5741eSChristian Lamparter const struct firmware *fw; 3318bd5741eSChristian Lamparter int err; 3328bd5741eSChristian Lamparter 3338bd5741eSChristian Lamparter err = renesas_fw_check_running(pdev); 3348bd5741eSChristian Lamparter /* Continue ahead, if the firmware is already running. */ 3358bd5741eSChristian Lamparter if (err == 0) 3368bd5741eSChristian Lamparter return 0; 3378bd5741eSChristian Lamparter 3388bd5741eSChristian Lamparter if (err != 1) 3398bd5741eSChristian Lamparter return err; 3408bd5741eSChristian Lamparter 3418bd5741eSChristian Lamparter pci_dev_get(pdev); 3428bd5741eSChristian Lamparter err = request_firmware(&fw, fw_name, &pdev->dev); 3438bd5741eSChristian Lamparter pci_dev_put(pdev); 3448bd5741eSChristian Lamparter if (err) { 3458bd5741eSChristian Lamparter dev_err(&pdev->dev, "request_firmware failed: %d\n", err); 3468bd5741eSChristian Lamparter return err; 3478bd5741eSChristian Lamparter } 3488bd5741eSChristian Lamparter 3498bd5741eSChristian Lamparter err = renesas_fw_verify(fw->data, fw->size); 3508bd5741eSChristian Lamparter if (err) 3518bd5741eSChristian Lamparter goto exit; 3528bd5741eSChristian Lamparter 3538bd5741eSChristian Lamparter err = renesas_load_fw(pdev, fw); 3548bd5741eSChristian Lamparter exit: 3558bd5741eSChristian Lamparter release_firmware(fw); 3568bd5741eSChristian Lamparter return err; 3578bd5741eSChristian Lamparter } 3588bd5741eSChristian Lamparter EXPORT_SYMBOL_GPL(renesas_xhci_check_request_fw); 3598bd5741eSChristian Lamparter 3608bd5741eSChristian Lamparter void renesas_xhci_pci_exit(struct pci_dev *dev) 3618bd5741eSChristian Lamparter { 3628bd5741eSChristian Lamparter } 3638bd5741eSChristian Lamparter EXPORT_SYMBOL_GPL(renesas_xhci_pci_exit); 3648bd5741eSChristian Lamparter 3658bd5741eSChristian Lamparter MODULE_LICENSE("GPL v2"); 366