Lines Matching +full:ast2500 +full:- +full:vuart
1 // SPDX-License-Identifier: GPL-2.0+
3 * Serial Port driver for Aspeed VUART device
50 * The VUART is basically two UART 'front ends' connected by their FIFO
61 * to the host on the Host <-> BMC LPC bus. It could be different on a
65 static inline u8 aspeed_vuart_readb(struct aspeed_vuart *vuart, u8 reg) in aspeed_vuart_readb() argument
67 return readb(vuart->port->port.membase + reg); in aspeed_vuart_readb()
70 static inline void aspeed_vuart_writeb(struct aspeed_vuart *vuart, u8 val, u8 reg) in aspeed_vuart_writeb() argument
72 writeb(val, vuart->port->port.membase + reg); in aspeed_vuart_writeb()
78 struct aspeed_vuart *vuart = dev_get_drvdata(dev); in lpc_address_show() local
81 addr = (aspeed_vuart_readb(vuart, ASPEED_VUART_ADDRH) << 8) | in lpc_address_show()
82 (aspeed_vuart_readb(vuart, ASPEED_VUART_ADDRL)); in lpc_address_show()
87 static int aspeed_vuart_set_lpc_address(struct aspeed_vuart *vuart, u32 addr) in aspeed_vuart_set_lpc_address() argument
90 return -EINVAL; in aspeed_vuart_set_lpc_address()
92 aspeed_vuart_writeb(vuart, addr >> 8, ASPEED_VUART_ADDRH); in aspeed_vuart_set_lpc_address()
93 aspeed_vuart_writeb(vuart, addr >> 0, ASPEED_VUART_ADDRL); in aspeed_vuart_set_lpc_address()
102 struct aspeed_vuart *vuart = dev_get_drvdata(dev); in lpc_address_store() local
110 err = aspeed_vuart_set_lpc_address(vuart, val); in lpc_address_store()
119 struct aspeed_vuart *vuart = dev_get_drvdata(dev); in sirq_show() local
122 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRB); in sirq_show()
129 static int aspeed_vuart_set_sirq(struct aspeed_vuart *vuart, u32 sirq) in aspeed_vuart_set_sirq() argument
134 return -EINVAL; in aspeed_vuart_set_sirq()
139 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRB); in aspeed_vuart_set_sirq()
142 aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRB); in aspeed_vuart_set_sirq()
150 struct aspeed_vuart *vuart = dev_get_drvdata(dev); in sirq_store() local
158 err = aspeed_vuart_set_sirq(vuart, val); in sirq_store()
167 struct aspeed_vuart *vuart = dev_get_drvdata(dev); in sirq_polarity_show() local
170 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); in sirq_polarity_show()
176 static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart, in aspeed_vuart_set_sirq_polarity() argument
179 u8 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); in aspeed_vuart_set_sirq_polarity()
186 aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRA); in aspeed_vuart_set_sirq_polarity()
193 struct aspeed_vuart *vuart = dev_get_drvdata(dev); in sirq_polarity_store() local
201 aspeed_vuart_set_sirq_polarity(vuart, val != 0); in sirq_polarity_store()
219 static void aspeed_vuart_set_enabled(struct aspeed_vuart *vuart, bool enabled) in aspeed_vuart_set_enabled() argument
221 u8 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); in aspeed_vuart_set_enabled()
228 aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRA); in aspeed_vuart_set_enabled()
231 static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart, in aspeed_vuart_set_host_tx_discard() argument
236 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); in aspeed_vuart_set_host_tx_discard()
244 aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRA); in aspeed_vuart_set_host_tx_discard()
250 struct aspeed_vuart *vuart = uart_8250_port->port.private_data; in aspeed_vuart_startup() local
257 aspeed_vuart_set_host_tx_discard(vuart, false); in aspeed_vuart_startup()
265 struct aspeed_vuart *vuart = uart_8250_port->port.private_data; in aspeed_vuart_shutdown() local
267 aspeed_vuart_set_host_tx_discard(vuart, true); in aspeed_vuart_shutdown()
278 lockdep_assert_held_once(&up->port.lock); in __aspeed_vuart_set_throttle()
280 up->ier &= ~irqs; in __aspeed_vuart_set_throttle()
282 up->ier |= irqs; in __aspeed_vuart_set_throttle()
283 serial_out(up, UART_IER, up->ier); in __aspeed_vuart_set_throttle()
307 struct aspeed_vuart *vuart = from_timer(vuart, timer, unthrottle_timer); in aspeed_vuart_unthrottle_exp() local
308 struct uart_8250_port *up = vuart->port; in aspeed_vuart_unthrottle_exp()
310 if (!tty_buffer_space_avail(&up->port.state->port)) { in aspeed_vuart_unthrottle_exp()
311 mod_timer(&vuart->unthrottle_timer, in aspeed_vuart_unthrottle_exp()
316 aspeed_vuart_unthrottle(&up->port); in aspeed_vuart_unthrottle_exp()
320 * Custom interrupt handler to manage finer-grained flow control. Although we
321 * have throttle/unthrottle callbacks, we've seen that the VUART device can
347 space = tty_buffer_space_avail(&port->state->port); in aspeed_vuart_handle_irq()
351 struct aspeed_vuart *vuart = port->private_data; in aspeed_vuart_handle_irq() local
354 if (!timer_pending(&vuart->unthrottle_timer)) in aspeed_vuart_handle_irq()
355 mod_timer(&vuart->unthrottle_timer, in aspeed_vuart_handle_irq()
364 if (--count == 0) in aspeed_vuart_handle_irq()
368 tty_flip_buffer_push(&port->state->port); in aspeed_vuart_handle_irq()
382 struct aspeed_vuart *vuart, struct device_node *syscon_np, in aspeed_vuart_auto_configure_sirq_polarity() argument
390 dev_warn(vuart->dev, in aspeed_vuart_auto_configure_sirq_polarity()
391 "could not get regmap for aspeed,sirq-polarity-sense\n"); in aspeed_vuart_auto_configure_sirq_polarity()
395 dev_warn(vuart->dev, "could not read hw strap table\n"); in aspeed_vuart_auto_configure_sirq_polarity()
399 aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0); in aspeed_vuart_auto_configure_sirq_polarity()
410 return -EINVAL; in aspeed_vuart_map_irq_polarity()
417 struct device *dev = &pdev->dev; in aspeed_vuart_probe()
419 struct aspeed_vuart *vuart; in aspeed_vuart_probe() local
426 np = pdev->dev.of_node; in aspeed_vuart_probe()
428 vuart = devm_kzalloc(&pdev->dev, sizeof(*vuart), GFP_KERNEL); in aspeed_vuart_probe()
429 if (!vuart) in aspeed_vuart_probe()
430 return -ENOMEM; in aspeed_vuart_probe()
432 vuart->dev = &pdev->dev; in aspeed_vuart_probe()
433 timer_setup(&vuart->unthrottle_timer, aspeed_vuart_unthrottle_exp, 0); in aspeed_vuart_probe()
437 return -EINVAL; in aspeed_vuart_probe()
440 port.port.private_data = vuart; in aspeed_vuart_probe()
441 port.port.mapbase = res->start; in aspeed_vuart_probe()
448 port.port.dev = &pdev->dev; in aspeed_vuart_probe()
454 rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); in aspeed_vuart_probe()
466 rc = dev_err_probe(dev, PTR_ERR(vclk), "clk or clock-frequency not defined\n"); in aspeed_vuart_probe()
473 /* If current-speed was set, then try not to change it. */ in aspeed_vuart_probe()
474 if (of_property_read_u32(np, "current-speed", &prop) == 0) in aspeed_vuart_probe()
483 if (of_property_read_bool(np, "auto-flow-control")) in aspeed_vuart_probe()
490 vuart->line = rc; in aspeed_vuart_probe()
491 vuart->port = serial8250_get_port(vuart->line); in aspeed_vuart_probe()
494 np, "aspeed,sirq-polarity-sense", 2, 0, in aspeed_vuart_probe()
497 dev_dbg(&pdev->dev, in aspeed_vuart_probe()
498 "aspeed,sirq-polarity-sense property not found\n"); in aspeed_vuart_probe()
501 vuart, sirq_polarity_sense_args.np, in aspeed_vuart_probe()
507 rc = of_property_read_u32(np, "aspeed,lpc-io-reg", &prop); in aspeed_vuart_probe()
511 rc = aspeed_vuart_set_lpc_address(vuart, prop); in aspeed_vuart_probe()
513 dev_err_probe(dev, rc, "invalid value in aspeed,lpc-io-reg property\n"); in aspeed_vuart_probe()
517 rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", sirq, 2); in aspeed_vuart_probe()
523 rc = aspeed_vuart_set_sirq(vuart, sirq[0]); in aspeed_vuart_probe()
525 dev_err_probe(dev, rc, "invalid sirq number in aspeed,lpc-interrupts property\n"); in aspeed_vuart_probe()
532 "invalid sirq polarity in aspeed,lpc-interrupts property\n"); in aspeed_vuart_probe()
536 aspeed_vuart_set_sirq_polarity(vuart, sirq_polarity); in aspeed_vuart_probe()
538 aspeed_vuart_set_enabled(vuart, true); in aspeed_vuart_probe()
539 aspeed_vuart_set_host_tx_discard(vuart, true); in aspeed_vuart_probe()
540 platform_set_drvdata(pdev, vuart); in aspeed_vuart_probe()
545 sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); in aspeed_vuart_probe()
551 struct aspeed_vuart *vuart = platform_get_drvdata(pdev); in aspeed_vuart_remove() local
553 del_timer_sync(&vuart->unthrottle_timer); in aspeed_vuart_remove()
554 aspeed_vuart_set_enabled(vuart, false); in aspeed_vuart_remove()
555 serial8250_unregister_port(vuart->line); in aspeed_vuart_remove()
556 sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); in aspeed_vuart_remove()
560 { .compatible = "aspeed,ast2400-vuart" },
561 { .compatible = "aspeed,ast2500-vuart" },
568 .name = "aspeed-vuart",
579 MODULE_DESCRIPTION("Driver for Aspeed VUART device");