mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			129 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 29fee00424556cbc998b4536f1553358d9fbea50 Mon Sep 17 00:00:00 2001
 | |
| From: Phil Elwell <phil@raspberrypi.com>
 | |
| Date: Wed, 12 Oct 2022 13:24:51 +0100
 | |
| Subject: [PATCH] serial: pl011: rp1 uart support
 | |
| 
 | |
| Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | |
| ---
 | |
|  drivers/tty/serial/amba-pl011.c | 96 +++++++++++++++++++++++++++++++++
 | |
|  1 file changed, 96 insertions(+)
 | |
| 
 | |
| --- a/drivers/tty/serial/amba-pl011.c
 | |
| +++ b/drivers/tty/serial/amba-pl011.c
 | |
| @@ -152,6 +152,20 @@ static const struct vendor_data vendor_s
 | |
|  	.fixed_options		= true,
 | |
|  };
 | |
|  
 | |
| +static struct vendor_data vendor_arm_axi = {
 | |
| +	.reg_offset		= pl011_std_offsets,
 | |
| +	.ifls			= UART011_IFLS_RX4_8 | UART011_IFLS_TX4_8,
 | |
| +	.fr_busy		= UART01x_FR_BUSY,
 | |
| +	.fr_dsr			= UART01x_FR_DSR,
 | |
| +	.fr_cts			= UART01x_FR_CTS,
 | |
| +	.fr_ri			= UART011_FR_RI,
 | |
| +	.oversampling		= false,
 | |
| +	.dma_threshold		= false,
 | |
| +	.cts_event_workaround	= false,
 | |
| +	.always_enabled		= false,
 | |
| +	.fixed_options		= false,
 | |
| +};
 | |
| +
 | |
|  #ifdef CONFIG_ACPI_SPCR_TABLE
 | |
|  static const struct vendor_data vendor_qdt_qdf2400_e44 = {
 | |
|  	.reg_offset		= pl011_std_offsets,
 | |
| @@ -2976,6 +2990,86 @@ static struct platform_driver arm_sbsa_u
 | |
|  	},
 | |
|  };
 | |
|  
 | |
| +static int pl011_axi_probe(struct platform_device *pdev)
 | |
| +{
 | |
| +	struct uart_amba_port *uap;
 | |
| +	struct vendor_data *vendor =  &vendor_arm_axi;
 | |
| +	struct resource *r;
 | |
| +	unsigned int periphid;
 | |
| +	int portnr, ret, irq;
 | |
| +
 | |
| +	portnr = pl011_find_free_port();
 | |
| +	if (portnr < 0)
 | |
| +		return portnr;
 | |
| +
 | |
| +	uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port),
 | |
| +			   GFP_KERNEL);
 | |
| +	if (!uap)
 | |
| +		return -ENOMEM;
 | |
| +
 | |
| +	uap->clk = devm_clk_get(&pdev->dev, NULL);
 | |
| +	if (IS_ERR(uap->clk))
 | |
| +		return PTR_ERR(uap->clk);
 | |
| +
 | |
| +	if (of_property_read_bool(pdev->dev.of_node, "cts-event-workaround")) {
 | |
| +		vendor->cts_event_workaround = true;
 | |
| +		dev_info(&pdev->dev, "cts_event_workaround enabled\n");
 | |
| +	}
 | |
| +
 | |
| +	irq = platform_get_irq(pdev, 0);
 | |
| +	if (irq < 0)
 | |
| +		return irq;
 | |
| +
 | |
| +	periphid = 0x00241011; /* A safe default */
 | |
| +	of_property_read_u32(pdev->dev.of_node, "arm,primecell-periphid",
 | |
| +			     &periphid);
 | |
| +
 | |
| +	uap->reg_offset = vendor->reg_offset;
 | |
| +	uap->vendor = vendor;
 | |
| +	uap->fifosize = (AMBA_REV_BITS(periphid) < 3) ? 16 : 32;
 | |
| +	uap->port.iotype = vendor->access_32b ? UPIO_MEM32 : UPIO_MEM;
 | |
| +	uap->port.irq = irq;
 | |
| +	uap->port.ops = &amba_pl011_pops;
 | |
| +
 | |
| +	snprintf(uap->type, sizeof(uap->type), "PL011 AXI");
 | |
| +
 | |
| +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | |
| +
 | |
| +	ret = pl011_setup_port(&pdev->dev, uap, r, portnr);
 | |
| +	if (ret)
 | |
| +		return ret;
 | |
| +
 | |
| +	platform_set_drvdata(pdev, uap);
 | |
| +
 | |
| +	return pl011_register_port(uap);
 | |
| +}
 | |
| +
 | |
| +static int pl011_axi_remove(struct platform_device *pdev)
 | |
| +{
 | |
| +	struct uart_amba_port *uap = platform_get_drvdata(pdev);
 | |
| +
 | |
| +	uart_remove_one_port(&amba_reg, &uap->port);
 | |
| +	pl011_unregister_port(uap);
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static const struct of_device_id pl011_axi_of_match[] = {
 | |
| +	{ .compatible = "arm,pl011-axi" },
 | |
| +	{},
 | |
| +};
 | |
| +MODULE_DEVICE_TABLE(of, pl011_axi_of_match);
 | |
| +
 | |
| +static struct platform_driver pl011_axi_platform_driver = {
 | |
| +	.probe		= pl011_axi_probe,
 | |
| +	.remove		= pl011_axi_remove,
 | |
| +	.driver	= {
 | |
| +		.name	= "pl011-axi",
 | |
| +		.pm	= &pl011_dev_pm_ops,
 | |
| +		.of_match_table = of_match_ptr(pl011_axi_of_match),
 | |
| +		.suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011),
 | |
| +	},
 | |
| +};
 | |
| +
 | |
|  static const struct amba_id pl011_ids[] = {
 | |
|  	{
 | |
|  		.id	= 0x00041011,
 | |
| @@ -3009,6 +3103,8 @@ static int __init pl011_init(void)
 | |
|  
 | |
|  	if (platform_driver_register(&arm_sbsa_uart_platform_driver))
 | |
|  		pr_warn("could not register SBSA UART platform driver\n");
 | |
| +	if (platform_driver_register(&pl011_axi_platform_driver))
 | |
| +		pr_warn("could not register PL011 AXI platform driver\n");
 | |
|  	return amba_driver_register(&pl011_driver);
 | |
|  }
 | |
|  
 |