Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers/tty/serial/8250: Make Aspeed VUART SIRQ polarity configurable

Make the SIRQ polarity for Aspeed AST24xx/25xx VUART configurable via
sysfs. This setting need to be changed on specific host platforms
depending on the selected host interface (LPC / eSPI).

The setting is configurable via sysfs rather than device-tree to stay in
line with other related configurable settings.

On AST2500 the VUART SIRQ polarity can be auto-configured by reading a
bit from a configuration register, e.g. the LPC/eSPI interface
configuration bit.

Tested: Verified on TYAN S7106 mainboard.
Signed-off-by: Oskar Senft <osk@google.com>
Link: https://lore.kernel.org/r/20190905144130.220713-1-osk@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Oskar Senft and committed by
Greg Kroah-Hartman
8d310c91 a8afc193

+95 -1
+10 -1
Documentation/ABI/stable/sysfs-driver-aspeed-vuart
··· 6 6 Users: OpenBMC. Proposed changes should be mailed to 7 7 openbmc@lists.ozlabs.org 8 8 9 - What: /sys/bus/platform/drivers/aspeed-vuart*/sirq 9 + What: /sys/bus/platform/drivers/aspeed-vuart/*/sirq 10 10 Date: April 2017 11 11 Contact: Jeremy Kerr <jk@ozlabs.org> 12 12 Description: Configures which interrupt number the host side of 13 13 the UART will appear on the host <-> BMC LPC bus. 14 + Users: OpenBMC. Proposed changes should be mailed to 15 + openbmc@lists.ozlabs.org 16 + 17 + What: /sys/bus/platform/drivers/aspeed-vuart/*/sirq_polarity 18 + Date: July 2019 19 + Contact: Oskar Senft <osk@google.com> 20 + Description: Configures the polarity of the serial interrupt to the 21 + host via the BMC LPC bus. 22 + Set to 0 for active-low or 1 for active-high. 14 23 Users: OpenBMC. Proposed changes should be mailed to 15 24 openbmc@lists.ozlabs.org
+84
drivers/tty/serial/8250/8250_aspeed_vuart.c
··· 14 14 #include <linux/of_address.h> 15 15 #include <linux/of_irq.h> 16 16 #include <linux/of_platform.h> 17 + #include <linux/regmap.h> 18 + #include <linux/mfd/syscon.h> 17 19 #include <linux/tty.h> 18 20 #include <linux/tty_flip.h> 19 21 #include <linux/clk.h> ··· 24 22 25 23 #define ASPEED_VUART_GCRA 0x20 26 24 #define ASPEED_VUART_GCRA_VUART_EN BIT(0) 25 + #define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY BIT(1) 27 26 #define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5) 28 27 #define ASPEED_VUART_GCRB 0x24 29 28 #define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4) ··· 134 131 135 132 static DEVICE_ATTR_RW(sirq); 136 133 134 + static ssize_t sirq_polarity_show(struct device *dev, 135 + struct device_attribute *attr, char *buf) 136 + { 137 + struct aspeed_vuart *vuart = dev_get_drvdata(dev); 138 + u8 reg; 139 + 140 + reg = readb(vuart->regs + ASPEED_VUART_GCRA); 141 + reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; 142 + 143 + return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0); 144 + } 145 + 146 + static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart, 147 + bool polarity) 148 + { 149 + u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA); 150 + 151 + if (polarity) 152 + reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; 153 + else 154 + reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; 155 + 156 + writeb(reg, vuart->regs + ASPEED_VUART_GCRA); 157 + } 158 + 159 + static ssize_t sirq_polarity_store(struct device *dev, 160 + struct device_attribute *attr, 161 + const char *buf, size_t count) 162 + { 163 + struct aspeed_vuart *vuart = dev_get_drvdata(dev); 164 + unsigned long val; 165 + int err; 166 + 167 + err = kstrtoul(buf, 0, &val); 168 + if (err) 169 + return err; 170 + 171 + aspeed_vuart_set_sirq_polarity(vuart, val != 0); 172 + 173 + return count; 174 + } 175 + 176 + static DEVICE_ATTR_RW(sirq_polarity); 177 + 137 178 static struct attribute *aspeed_vuart_attrs[] = { 138 179 &dev_attr_sirq.attr, 180 + &dev_attr_sirq_polarity.attr, 139 181 &dev_attr_lpc_address.attr, 140 182 NULL, 141 183 }; ··· 350 302 return 1; 351 303 } 352 304 305 + static void aspeed_vuart_auto_configure_sirq_polarity( 306 + struct aspeed_vuart *vuart, struct device_node *syscon_np, 307 + u32 reg_offset, u32 reg_mask) 308 + { 309 + struct regmap *regmap; 310 + u32 value; 311 + 312 + regmap = syscon_node_to_regmap(syscon_np); 313 + if (IS_ERR(regmap)) { 314 + dev_warn(vuart->dev, 315 + "could not get regmap for aspeed,sirq-polarity-sense\n"); 316 + return; 317 + } 318 + if (regmap_read(regmap, reg_offset, &value)) { 319 + dev_warn(vuart->dev, "could not read hw strap table\n"); 320 + return; 321 + } 322 + 323 + aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0); 324 + } 325 + 353 326 static int aspeed_vuart_probe(struct platform_device *pdev) 354 327 { 328 + struct of_phandle_args sirq_polarity_sense_args; 355 329 struct uart_8250_port port; 356 330 struct aspeed_vuart *vuart; 357 331 struct device_node *np; ··· 471 401 goto err_clk_disable; 472 402 473 403 vuart->line = rc; 404 + 405 + rc = of_parse_phandle_with_fixed_args( 406 + np, "aspeed,sirq-polarity-sense", 2, 0, 407 + &sirq_polarity_sense_args); 408 + if (rc < 0) { 409 + dev_dbg(&pdev->dev, 410 + "aspeed,sirq-polarity-sense property not found\n"); 411 + } else { 412 + aspeed_vuart_auto_configure_sirq_polarity( 413 + vuart, sirq_polarity_sense_args.np, 414 + sirq_polarity_sense_args.args[0], 415 + BIT(sirq_polarity_sense_args.args[1])); 416 + of_node_put(sirq_polarity_sense_args.np); 417 + } 474 418 475 419 aspeed_vuart_set_enabled(vuart, true); 476 420 aspeed_vuart_set_host_tx_discard(vuart, true);
+1
drivers/tty/serial/8250/Kconfig
··· 243 243 tristate "Aspeed Virtual UART" 244 244 depends on SERIAL_8250 245 245 depends on OF 246 + depends on REGMAP && MFD_SYSCON 246 247 help 247 248 If you want to use the virtual UART (VUART) device on Aspeed 248 249 BMC platforms, enable this option. This enables the 16550A-