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