mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 09:14:19 +08:00
serial: ucc_uart: factor out soft_uart initialization
The "soft uart" mechanism is a workaround for a silicon bug which (as far as I know) only affects some PPC-based SOCs. The code that determines which microcode blob to request relies on some powerpc-specific bits (e.g. the mfspr(SPRN_SVR) and hence also the asm/reg.h header). This makes it a little awkward to allow this driver to be built for non-PPC based SOCs with a QE, even if they are not affected by that silicon bug and thus don't need any of the Soft UART logic. There's no way around guarding those bits with some ifdeffery, so to keep that isolated, factor out the do-we-need-soft-uart-and-if-so-handle-the-firmware to a separate function, which we can then easily stub out for non-PPC. Reviewed-by: Timur Tabi <timur@kernel.org> Acked-by: Timur Tabi <timur@kernel.org> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Li Yang <leoyang.li@nxp.com>
This commit is contained in:
parent
8b1cdc4033
commit
96b6b6aaac
@ -1183,6 +1183,61 @@ static void uart_firmware_cont(const struct firmware *fw, void *context)
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
static int soft_uart_init(struct platform_device *ofdev)
|
||||
{
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
struct qe_firmware_info *qe_fw_info;
|
||||
int ret;
|
||||
|
||||
if (of_find_property(np, "soft-uart", NULL)) {
|
||||
dev_dbg(&ofdev->dev, "using Soft-UART mode\n");
|
||||
soft_uart = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
qe_fw_info = qe_get_firmware_info();
|
||||
|
||||
/* Check if the firmware has been uploaded. */
|
||||
if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) {
|
||||
firmware_loaded = 1;
|
||||
} else {
|
||||
char filename[32];
|
||||
unsigned int soc;
|
||||
unsigned int rev_h;
|
||||
unsigned int rev_l;
|
||||
|
||||
soc = soc_info(&rev_h, &rev_l);
|
||||
if (!soc) {
|
||||
dev_err(&ofdev->dev, "unknown CPU model\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin",
|
||||
soc, rev_h, rev_l);
|
||||
|
||||
dev_info(&ofdev->dev, "waiting for firmware %s\n",
|
||||
filename);
|
||||
|
||||
/*
|
||||
* We call request_firmware_nowait instead of
|
||||
* request_firmware so that the driver can load and
|
||||
* initialize the ports without holding up the rest of
|
||||
* the kernel. If hotplug support is enabled in the
|
||||
* kernel, then we use it.
|
||||
*/
|
||||
ret = request_firmware_nowait(THIS_MODULE,
|
||||
FW_ACTION_HOTPLUG, filename, &ofdev->dev,
|
||||
GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
|
||||
if (ret) {
|
||||
dev_err(&ofdev->dev,
|
||||
"could not load firmware %s\n",
|
||||
filename);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ucc_uart_probe(struct platform_device *ofdev)
|
||||
{
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
@ -1195,58 +1250,9 @@ static int ucc_uart_probe(struct platform_device *ofdev)
|
||||
/*
|
||||
* Determine if we need Soft-UART mode
|
||||
*/
|
||||
if (of_find_property(np, "soft-uart", NULL)) {
|
||||
dev_dbg(&ofdev->dev, "using Soft-UART mode\n");
|
||||
soft_uart = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are using Soft-UART, determine if we need to upload the
|
||||
* firmware, too.
|
||||
*/
|
||||
if (soft_uart) {
|
||||
struct qe_firmware_info *qe_fw_info;
|
||||
|
||||
qe_fw_info = qe_get_firmware_info();
|
||||
|
||||
/* Check if the firmware has been uploaded. */
|
||||
if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) {
|
||||
firmware_loaded = 1;
|
||||
} else {
|
||||
char filename[32];
|
||||
unsigned int soc;
|
||||
unsigned int rev_h;
|
||||
unsigned int rev_l;
|
||||
|
||||
soc = soc_info(&rev_h, &rev_l);
|
||||
if (!soc) {
|
||||
dev_err(&ofdev->dev, "unknown CPU model\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin",
|
||||
soc, rev_h, rev_l);
|
||||
|
||||
dev_info(&ofdev->dev, "waiting for firmware %s\n",
|
||||
filename);
|
||||
|
||||
/*
|
||||
* We call request_firmware_nowait instead of
|
||||
* request_firmware so that the driver can load and
|
||||
* initialize the ports without holding up the rest of
|
||||
* the kernel. If hotplug support is enabled in the
|
||||
* kernel, then we use it.
|
||||
*/
|
||||
ret = request_firmware_nowait(THIS_MODULE,
|
||||
FW_ACTION_HOTPLUG, filename, &ofdev->dev,
|
||||
GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
|
||||
if (ret) {
|
||||
dev_err(&ofdev->dev,
|
||||
"could not load firmware %s\n",
|
||||
filename);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = soft_uart_init(ofdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL);
|
||||
if (!qe_port) {
|
||||
|
Loading…
Reference in New Issue
Block a user