From 04dd17822334871b23ea2862f7798fb0e0007777 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Sat, 11 May 2024 08:53:19 +0000 Subject: [PATCH] change otg to host mode --- kernel/drivers/tty/serial/8250/8250_aspeed_vuart.c | 88 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 87 insertions(+), 1 deletions(-) diff --git a/kernel/drivers/tty/serial/8250/8250_aspeed_vuart.c b/kernel/drivers/tty/serial/8250/8250_aspeed_vuart.c index 2d5c364..ec0d1da 100644 --- a/kernel/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/kernel/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -10,6 +10,8 @@ #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_platform.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> #include <linux/tty.h> #include <linux/tty_flip.h> #include <linux/clk.h> @@ -18,6 +20,7 @@ #define ASPEED_VUART_GCRA 0x20 #define ASPEED_VUART_GCRA_VUART_EN BIT(0) +#define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY BIT(1) #define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5) #define ASPEED_VUART_GCRB 0x24 #define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4) @@ -127,8 +130,53 @@ static DEVICE_ATTR_RW(sirq); +static ssize_t sirq_polarity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aspeed_vuart *vuart = dev_get_drvdata(dev); + u8 reg; + + reg = readb(vuart->regs + ASPEED_VUART_GCRA); + reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; + + return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0); +} + +static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart, + bool polarity) +{ + u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA); + + if (polarity) + reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; + else + reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; + + writeb(reg, vuart->regs + ASPEED_VUART_GCRA); +} + +static ssize_t sirq_polarity_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aspeed_vuart *vuart = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 0, &val); + if (err) + return err; + + aspeed_vuart_set_sirq_polarity(vuart, val != 0); + + return count; +} + +static DEVICE_ATTR_RW(sirq_polarity); + static struct attribute *aspeed_vuart_attrs[] = { &dev_attr_sirq.attr, + &dev_attr_sirq_polarity.attr, &dev_attr_lpc_address.attr, NULL, }; @@ -293,13 +341,35 @@ if (lsr & UART_LSR_THRE) serial8250_tx_chars(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_unlock_and_check_sysrq(port, flags); return 1; } +static void aspeed_vuart_auto_configure_sirq_polarity( + struct aspeed_vuart *vuart, struct device_node *syscon_np, + u32 reg_offset, u32 reg_mask) +{ + struct regmap *regmap; + u32 value; + + regmap = syscon_node_to_regmap(syscon_np); + if (IS_ERR(regmap)) { + dev_warn(vuart->dev, + "could not get regmap for aspeed,sirq-polarity-sense\n"); + return; + } + if (regmap_read(regmap, reg_offset, &value)) { + dev_warn(vuart->dev, "could not read hw strap table\n"); + return; + } + + aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0); +} + static int aspeed_vuart_probe(struct platform_device *pdev) { + struct of_phandle_args sirq_polarity_sense_args; struct uart_8250_port port; struct aspeed_vuart *vuart; struct device_node *np; @@ -332,6 +402,8 @@ port.port.unthrottle = aspeed_vuart_unthrottle; port.port.status = UPSTAT_SYNC_FIFO; port.port.dev = &pdev->dev; + port.port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE); + port.bugs |= UART_BUG_TXRACE; rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); if (rc < 0) @@ -397,6 +469,20 @@ vuart->line = rc; + rc = of_parse_phandle_with_fixed_args( + np, "aspeed,sirq-polarity-sense", 2, 0, + &sirq_polarity_sense_args); + if (rc < 0) { + dev_dbg(&pdev->dev, + "aspeed,sirq-polarity-sense property not found\n"); + } else { + aspeed_vuart_auto_configure_sirq_polarity( + vuart, sirq_polarity_sense_args.np, + sirq_polarity_sense_args.args[0], + BIT(sirq_polarity_sense_args.args[1])); + of_node_put(sirq_polarity_sense_args.np); + } + aspeed_vuart_set_enabled(vuart, true); aspeed_vuart_set_host_tx_discard(vuart, true); platform_set_drvdata(pdev, vuart); -- Gitblit v1.6.2