* [patch 1/5] AST2500 DMA UART driver
From: sudheer.v @ 2019-06-21 11:17 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <1561115855-4186-1-git-send-email-open.sudheer@gmail.com>
From: sudheer veliseti <sudheer.open@gmail.com>
UART driver for Aspeed's bmc chip AST2500
Design approch:
AST2500 has dedicated Uart DMA controller which has 12 sets of Tx and RX channels
connected to UART controller directly.
Since the DMA controller have dedicated buffers and registers,
there would be little benifit in adding DMA framework overhead.
So the software for DMA controller is included within the UART driver itself.
implementation details:
'struct uart_8250_port' serial port is populated and registered with 8250_core.
Rx and Tx dma channels are requested from DMA controller software Layer, which
is part of uart driver itself.
Interrupt service routine for DMA controller is the crucial one for Handling all
the tx and rx data. ISRs installed for individual uarts are just dummy,and are helpful
only to report any spurious interrupts in hardware.
Signed-off-by: sudheer veliseti <sudheer.open@gmail.com>
---
.../tty/serial/8250/8250_ast2500_uart_dma.c | 1879 +++++++++++++++++
1 file changed, 1879 insertions(+)
create mode 100644 drivers/tty/serial/8250/8250_ast2500_uart_dma.c
diff --git a/drivers/tty/serial/8250/8250_ast2500_uart_dma.c b/drivers/tty/serial/8250/8250_ast2500_uart_dma.c
new file mode 100644
index 000000000000..13911a0a745a
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_ast2500_uart_dma.c
@@ -0,0 +1,1879 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMA UART Driver for ASPEED BMC chip: AST2500
+ *
+ * Copyright (C) 2019 sudheer Kumar veliseti, Aspeed technology Inc.
+ * <open.sudheer@gmail.com>
+ *
+ */
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/nmi.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#include "8250.h"
+
+#define DMA_BUFF_SIZE 0x1000 // 4096
+#define SDMA_RX_BUFF_SIZE 0x10000 // 65536
+
+#define SDDMA_RX_FIX 1
+/* enum ast_uart_chan_op
+ * operation codes passed to the DMA code by the user, and also used
+ * to inform the current channel owner of any changes to the system state
+ */
+
+enum ast_uart_chan_op {
+ AST_UART_DMAOP_TRIGGER,
+ AST_UART_DMAOP_STOP,
+ AST_UART_DMAOP_PAUSE,
+};
+
+/* ast_uart_dma_cbfn_t * * buffer callback routine type */
+typedef void (*ast_uart_dma_cbfn_t)(void *dev_id, u16 len);
+
+struct ast_sdma_info {
+ u8 ch_no;
+ u8 direction;
+ u8 enable;
+ void *priv;
+ char *sdma_virt_addr;
+ dma_addr_t dma_phy_addr;
+ /* cdriver callbacks */
+ ast_uart_dma_cbfn_t callback_fn; /* buffer done callback */
+};
+
+#define AST_UART_SDMA_CH 12
+
+struct ast_sdma_ch {
+ struct ast_sdma_info tx_dma_info[AST_UART_SDMA_CH];
+ struct ast_sdma_info rx_dma_info[AST_UART_SDMA_CH];
+};
+
+struct ast_sdma {
+ void __iomem *reg_base;
+ int dma_irq;
+ struct ast_sdma_ch *dma_ch;
+ struct regmap *map;
+};
+
+
+
+#define UART_TX_SDMA_EN 0x00
+#define UART_RX_SDMA_EN 0x04
+#define UART_SDMA_CONF 0x08
+#define UART_SDMA_TIMER 0x0C
+#define UART_TX_SDMA_REST 0x20
+#define UART_RX_SDMA_REST 0x24
+#define UART_TX_SDMA_IER 0x30
+#define UART_TX_SDMA_ISR 0x34
+#define UART_RX_SDMA_IER 0x38
+#define UART_RX_SDMA_ISR 0x3C
+#define UART_TX_R_POINT(x) (0x40 + (x * 0x20))
+#define UART_TX_W_POINT(x) (0x44 + (x * 0x20))
+#define UART_TX_SDMA_ADDR(x) (0x48 + (x * 0x20))
+#define UART_RX_R_POINT(x) (0x50 + (x * 0x20))
+#define UART_RX_W_POINT(x) (0x54 + (x * 0x20))
+#define UART_RX_SDMA_ADDR(x) (0x58 + (x * 0x20))
+
+/* UART_TX_SDMA_EN-0x00 : UART TX DMA Enable */
+/* UART_RX_SDMA_EN-0x04 : UART RX DMA Enable */
+#define SDMA_CH_EN(x) (0x1 << (x))
+
+/* UART_SDMA_CONF - 0x08 : Misc, Buffer size */
+#define SDMA_TX_BUFF_SIZE_MASK (0x3)
+#define SDMA_SET_TX_BUFF_SIZE(x) (x)
+#define SDMA_BUFF_SIZE_1KB (0x0)
+#define SDMA_BUFF_SIZE_4KB (0x1)
+#define SDMA_BUFF_SIZE_16KB (0x2)
+#define SDMA_BUFF_SIZE_64KB (0x3)
+#define SDMA_RX_BUFF_SIZE_MASK (0x3 << 2)
+#define SDMA_SET_RX_BUFF_SIZE(x) (x << 2)
+#define SDMA_TIMEOUT_DIS (0x1 << 4)
+
+/* UART_SDMA_TIMER-0x0C : UART DMA time out timer */
+
+/* UART_TX_SDMA_IER 0x30 */
+/* UART_TX_SDMA_ISR 0x34 */
+
+#define UART_SDMA11_INT (1 << 11)
+#define UART_SDMA10_INT (1 << 10)
+#define UART_SDMA9_INT (1 << 9)
+#define UART_SDMA8_INT (1 << 8)
+#define UART_SDMA7_INT (1 << 7)
+#define UART_SDMA6_INT (1 << 6)
+#define UART_SDMA5_INT (1 << 5)
+#define UART_SDMA4_INT (1 << 4)
+#define UART_SDMA3_INT (1 << 3)
+#define UART_SDMA2_INT (1 << 2)
+#define UART_SDMA1_INT (1 << 1)
+#define UART_SDMA0_INT (1 << 0)
+
+
+/*
+ * Configuration:
+ * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
+ * is unsafe when used on edge-triggered interrupts.
+ */
+static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+
+static unsigned int nr_uarts = CONFIG_AST_RUNTIME_DMA_UARTS;
+
+
+#define PASS_LIMIT 256
+
+#include <asm/serial.h>
+
+#define UART_DMA_NR CONFIG_AST_NR_DMA_UARTS
+
+
+struct ast_uart_priv_data {
+
+ unsigned short line; //index of uart port
+ struct uart_8250_port *up;
+ u8 dma_ch; // dma channel number
+ struct circ_buf rx_dma_buf;
+ struct circ_buf tx_dma_buf;
+ dma_addr_t dma_rx_addr; /* Mapped ADMA descr. table */
+ dma_addr_t dma_tx_addr; /* Mapped ADMA descr. table */
+#ifdef SDDMA_RX_FIX
+ struct tasklet_struct rx_tasklet;
+#else
+ struct timer_list rx_timer;
+#endif
+ struct tasklet_struct tx_tasklet;
+ spinlock_t lock;
+ int tx_done;
+ int tx_count;
+};
+
+
+static inline struct uart_8250_port *
+to_uart_8250_port(struct uart_port *uart) {
+ return container_of(uart, struct uart_8250_port, port);
+}
+
+struct irq_info {
+ spinlock_t lock;
+ struct uart_8250_port *up;
+};
+
+static struct irq_info ast_uart_irq[1];
+static DEFINE_MUTEX(ast_uart_mutex);
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial8250_config uart_config[] = {
+ [PORT_UNKNOWN] = {
+ .name = "unknown",
+ .fifo_size = 1,
+ .tx_loadsz = 1,
+ },
+ [PORT_8250] = {
+ .name = "8250",
+ .fifo_size = 1,
+ .tx_loadsz = 1,
+ },
+ [PORT_16450] = {
+ .name = "16450",
+ .fifo_size = 1,
+ .tx_loadsz = 1,
+ },
+ [PORT_16550] = {
+ .name = "16550",
+ .fifo_size = 1,
+ .tx_loadsz = 1,
+ },
+ [PORT_16550A] = {
+ .name = "16550A",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10
+ | UART_FCR_DMA_SELECT,
+ .flags = UART_CAP_FIFO,
+ },
+};
+
+/* sane hardware needs no mapping */
+#define map_8250_in_reg(up, offset) (offset)
+#define map_8250_out_reg(up, offset) (offset)
+
+// SDMA - software Layer : (previously was in ast-uart-sdma.c)
+static inline void ast_uart_sdma_write(struct ast_sdma *sdma,
+ u32 val, u32 reg)
+{
+ pr_debug("uart dma write:val:%x,reg:%x\n", val, reg);
+ writel(val, sdma->reg_base + reg);
+}
+
+static inline u32 ast_uart_sdma_read(struct ast_sdma *sdma, u32 reg)
+{
+ return readl(sdma->reg_base + reg);
+}
+
+struct ast_sdma ast_uart_sdma;
+
+int ast_uart_rx_sdma_enqueue(u8 ch, dma_addr_t rx_buff)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ pr_debug("ch = %d, rx buff = %x\n", ch, rx_buff);
+
+ local_irq_save(flags);
+ ast_uart_sdma_write(sdma, rx_buff, UART_RX_SDMA_ADDR(ch));
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+int ast_uart_tx_sdma_enqueue(u8 ch, dma_addr_t tx_buff)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ pr_debug("ch = %d, tx buff = %x\n", ch, tx_buff);
+
+ local_irq_save(flags);
+ ast_uart_sdma_write(sdma, tx_buff, UART_TX_SDMA_ADDR(ch));
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+int ast_uart_rx_sdma_ctrl(u8 ch, enum ast_uart_chan_op op)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+ struct ast_sdma_info *dma_ch = &(sdma->dma_ch->rx_dma_info[ch]);
+
+ pr_debug("RX DMA CTRL [ch %d]\n", ch);
+
+ local_irq_save(flags);
+
+ switch (op) {
+ case AST_UART_DMAOP_TRIGGER:
+ pr_debug("Trigger\n");
+ dma_ch->enable = 1;
+#ifdef SDDMA_RX_FIX
+#else
+ ast_uart_set_sdma_time_out(0xffff);
+#endif
+ // set enable
+ ast_uart_sdma_write(sdma,
+ ast_uart_sdma_read(sdma, UART_RX_SDMA_EN) | (0x1 << ch),
+ UART_RX_SDMA_EN);
+ break;
+ case AST_UART_DMAOP_STOP:
+ // disable engine
+ pr_debug("STOP\n");
+ dma_ch->enable = 0;
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_RX_SDMA_EN) &
+ ~(0x1 << ch),
+ UART_RX_SDMA_EN);
+ // set reset
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_RX_SDMA_REST) |
+ (0x1 << ch),
+ UART_RX_SDMA_REST);
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_RX_SDMA_REST) &
+ ~(0x1 << ch),
+ UART_RX_SDMA_REST);
+
+ ast_uart_sdma_write(sdma, 0, UART_RX_R_POINT(ch));
+ ast_uart_sdma_write(sdma, dma_ch->dma_phy_addr, UART_RX_SDMA_ADDR(ch));
+ break;
+ case AST_UART_DMAOP_PAUSE:
+ // disable engine
+ dma_ch->enable = 0;
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_RX_SDMA_EN) &
+ ~(0x1 << ch),
+ UART_RX_SDMA_EN);
+ break;
+ }
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+int ast_uart_tx_sdma_ctrl(u8 ch, enum ast_uart_chan_op op)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+ struct ast_sdma_info *dma_ch = &(sdma->dma_ch->tx_dma_info[ch]);
+
+ pr_debug("TX DMA CTRL [ch %d]\n", ch);
+
+ local_irq_save(flags);
+
+ switch (op) {
+ case AST_UART_DMAOP_TRIGGER:
+ pr_debug("TRIGGER : Enable\n");
+ dma_ch->enable = 1;
+ // set enable
+ ast_uart_sdma_write(sdma,
+ ast_uart_sdma_read(sdma, UART_TX_SDMA_EN) | (0x1 << ch),
+ UART_TX_SDMA_EN);
+ break;
+ case AST_UART_DMAOP_STOP:
+ pr_debug("STOP : DISABLE & RESET\n");
+ dma_ch->enable = 0;
+ // disable engine
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_TX_SDMA_EN) &
+ ~(0x1 << ch),
+ UART_TX_SDMA_EN);
+ // set reset
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_TX_SDMA_REST) |
+ (0x1 << ch),
+ UART_TX_SDMA_REST);
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_TX_SDMA_REST) &
+ ~(0x1 << ch),
+ UART_TX_SDMA_REST);
+
+ ast_uart_sdma_write(sdma, 0, UART_TX_W_POINT(ch));
+ break;
+ case AST_UART_DMAOP_PAUSE:
+ pr_debug("PAUSE : DISABLE\n");
+ dma_ch->enable = 0;
+ // disable engine
+ ast_uart_sdma_write(sdma, ast_uart_sdma_read(sdma, UART_TX_SDMA_EN) &
+ ~(0x1 << ch),
+ UART_TX_SDMA_EN);
+ }
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+u32 ast_uart_get_tx_sdma_pt(u8 ch)
+{
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ return ast_uart_sdma_read(sdma, UART_TX_R_POINT(ch));
+}
+
+int ast_uart_tx_sdma_update(u8 ch, u16 point)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ pr_debug("TX DMA CTRL [ch %d] point %d\n", ch, point);
+ local_irq_save(flags);
+ ast_uart_sdma_write(sdma, point, UART_TX_W_POINT(ch));
+ local_irq_restore(flags);
+ return 0;
+}
+
+int ast_uart_tx_sdma_request(u8 ch, ast_uart_dma_cbfn_t rtn, void *id)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+ struct ast_sdma_info *dma_ch = &(sdma->dma_ch->tx_dma_info[ch]);
+
+ pr_debug("TX DMA REQUEST ch = %d\n", ch);
+
+ local_irq_save(flags);
+
+ if (dma_ch->enable) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+ dma_ch->priv = id;
+ dma_ch->callback_fn = rtn;
+
+ // DMA IRQ En
+ ast_uart_sdma_write(sdma,
+ ast_uart_sdma_read(sdma, UART_TX_SDMA_IER) | (1 << ch),
+ UART_TX_SDMA_IER);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+int ast_uart_rx_sdma_update(u8 ch, u16 point)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ pr_debug("RX DMA CTRL [ch %d] point %x\n", ch, point);
+
+ local_irq_save(flags);
+ ast_uart_sdma_write(sdma, point, UART_RX_R_POINT(ch));
+ local_irq_restore(flags);
+ return 0;
+}
+
+#ifdef SDDMA_RX_FIX
+char *ast_uart_rx_sdma_request(u8 ch, ast_uart_dma_cbfn_t rtn, void *id)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+ struct ast_sdma_info *dma_ch = &(sdma->dma_ch->rx_dma_info[ch]);
+
+ pr_debug("RX DMA REQUEST ch = %d\n", ch);
+
+ local_irq_save(flags);
+
+ if (dma_ch->enable) {
+ local_irq_restore(flags);
+ return 0;
+ }
+ dma_ch->priv = id;
+
+ dma_ch->callback_fn = rtn;
+
+ // DMA IRQ En
+ ast_uart_sdma_write(sdma,
+ ast_uart_sdma_read(sdma, UART_RX_SDMA_IER) | (1 << ch),
+ UART_RX_SDMA_IER);
+
+ local_irq_restore(flags);
+
+ return dma_ch->sdma_virt_addr;
+}
+
+#else
+char *ast_uart_rx_sdma_request(u8 ch, void *id)
+{
+ unsigned long flags;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+ struct ast_sdma_info *dma_ch = &(sdma->dma_ch->rx_dma_info[ch]);
+
+ pr_debug("RX DMA REQUEST ch = %d\n", ch);
+
+ local_irq_save(flags);
+
+ if (dma_ch->enable) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+ dma_ch->priv = id;
+
+ local_irq_restore(flags);
+ return dma_ch->sdma_virt_addr;
+}
+#endif
+
+u16 ast_uart_get_rx_sdma_pt(u8 ch)
+{
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ return ast_uart_sdma_read(sdma, UART_RX_W_POINT(ch));
+}
+
+void ast_uart_set_sdma_time_out(u16 val)
+{
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ ast_uart_sdma_write(sdma, val, UART_SDMA_TIMER);
+}
+
+static inline void ast_sdma_bufffdone(struct ast_sdma_info *sdma_ch)
+{
+ u32 len;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+
+ if (sdma_ch->enable == 0) {
+ pr_debug("sdma Please check ch_no %x %s!!!!!\n",
+ sdma_ch->ch_no, sdma_ch->direction ? "TX" : "RX");
+ if (sdma_ch->direction) {
+ ast_uart_sdma_write(sdma,
+ ast_uart_sdma_read(sdma, UART_TX_SDMA_EN)
+ & ~(0x1 << sdma_ch->ch_no), UART_TX_SDMA_EN);
+ } else {
+ ast_uart_sdma_write(sdma,
+ ast_uart_sdma_read(sdma, UART_RX_SDMA_EN) &
+ ~(0x1 << sdma_ch->ch_no), UART_RX_SDMA_EN);
+ ast_uart_rx_sdma_update(sdma_ch->ch_no,
+ ast_uart_get_rx_sdma_pt(sdma_ch->ch_no));
+ pr_debug("OFFSET : UART_RX_SDMA_EN = %x\n ",
+ ast_uart_sdma_read(sdma, UART_RX_SDMA_EN));
+ }
+ return;
+ }
+
+ if (sdma_ch->direction) {
+ len = ast_uart_sdma_read(sdma, UART_TX_R_POINT(sdma_ch->ch_no));
+ pr_debug("tx rp %x , wp %x\n",
+ ast_uart_sdma_read(sdma, UART_TX_R_POINT(sdma_ch->ch_no)),
+ ast_uart_sdma_read(sdma, UART_TX_W_POINT(sdma_ch->ch_no))
+ );
+ } else {
+ pr_debug("rx rp %x , wp %x\n",
+ ast_uart_sdma_read(sdma, UART_RX_R_POINT(sdma_ch->ch_no)),
+ ast_uart_sdma_read(sdma, UART_RX_W_POINT(sdma_ch->ch_no))
+ );
+ len = ast_uart_sdma_read(sdma, UART_RX_W_POINT(sdma_ch->ch_no));
+ }
+
+ pr_debug("<dma dwn>: ch[%d] : %s ,len : %d\n", sdma_ch->ch_no,
+ sdma_ch->direction ? "tx" : "rx", len);
+
+ if (sdma_ch->callback_fn != NULL)
+ (sdma_ch->callback_fn)(sdma_ch->priv, len);
+}
+
+static irqreturn_t ast_uart_sdma_isr(int irq, void *dev_id)
+{
+ struct ast_sdma *sdma = (struct ast_sdma *)dev_id;
+
+ u32 tx_sts = ast_uart_sdma_read(sdma, UART_TX_SDMA_ISR);
+ u32 rx_sts = ast_uart_sdma_read(sdma, UART_RX_SDMA_ISR);
+
+ pr_debug("tx sts : %x, rx sts : %x\n", tx_sts, rx_sts);
+
+ if ((tx_sts == 0) && (rx_sts == 0)) {
+ pr_debug("SDMA IRQ ERROR !!!\n");
+ return IRQ_HANDLED;
+ }
+
+ if (rx_sts & UART_SDMA0_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA0_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[0]));
+ } else if (rx_sts & UART_SDMA1_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA1_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[1]));
+ } else if (rx_sts & UART_SDMA2_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA2_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[2]));
+ } else if (rx_sts & UART_SDMA3_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA3_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[3]));
+ } else if (rx_sts & UART_SDMA4_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA4_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[4]));
+ } else if (rx_sts & UART_SDMA5_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA5_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[5]));
+ } else if (rx_sts & UART_SDMA6_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA6_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[6]));
+ } else if (rx_sts & UART_SDMA7_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA7_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[7]));
+ } else if (rx_sts & UART_SDMA8_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA8_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[8]));
+ } else if (rx_sts & UART_SDMA9_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA9_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[9]));
+ } else if (rx_sts & UART_SDMA10_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA10_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[10]));
+ } else if (rx_sts & UART_SDMA11_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA11_INT, UART_RX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->rx_dma_info[11]));
+ } else {
+
+ }
+
+ if (tx_sts & UART_SDMA0_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA0_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[0]));
+ } else if (tx_sts & UART_SDMA1_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA1_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[1]));
+ } else if (tx_sts & UART_SDMA2_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA2_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[2]));
+ } else if (tx_sts & UART_SDMA3_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA3_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[3]));
+ } else if (tx_sts & UART_SDMA4_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA4_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[4]));
+ } else if (tx_sts & UART_SDMA5_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA5_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[5]));
+ } else if (tx_sts & UART_SDMA6_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA6_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[6]));
+ } else if (tx_sts & UART_SDMA7_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA7_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[7]));
+ } else if (tx_sts & UART_SDMA8_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA8_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[8]));
+ } else if (tx_sts & UART_SDMA9_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA9_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[9]));
+ } else if (tx_sts & UART_SDMA10_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA10_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[10]));
+ } else if (tx_sts & UART_SDMA11_INT) {
+ ast_uart_sdma_write(sdma, UART_SDMA11_INT, UART_TX_SDMA_ISR);
+ ast_sdma_bufffdone(&(sdma->dma_ch->tx_dma_info[11]));
+ } else {
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ast_uart_sdma_probe(void)
+{
+ int i;
+ struct device_node *node;
+ int ret;
+ struct ast_sdma *sdma = &ast_uart_sdma;
+ char *rx_dma_virt_addr;
+ dma_addr_t rx_dma_phy_addr;
+
+ sdma->dma_ch = kzalloc(sizeof(struct ast_sdma_ch), GFP_KERNEL);
+ if (!sdma->dma_ch)
+ return -ENOMEM;
+
+ // sdma memory mapping
+ node = of_find_compatible_node(NULL, NULL, "aspeed,ast-uart-sdma");
+ if (!node)
+ return -ENODEV;
+
+ sdma->reg_base = of_iomap(node, 0);
+ if (IS_ERR(sdma->reg_base))
+ return PTR_ERR(sdma->map);
+ rx_dma_virt_addr = dma_alloc_coherent(NULL,
+ SDMA_RX_BUFF_SIZE * AST_UART_SDMA_CH, &rx_dma_phy_addr, GFP_KERNEL);
+
+ if (!rx_dma_virt_addr) {
+ pr_debug("rx_dma_virt_addr Err:dma alloc Failed\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < AST_UART_SDMA_CH; i++) {
+ // TX ------------------------
+ sdma->dma_ch->tx_dma_info[i].enable = 0;
+ sdma->dma_ch->tx_dma_info[i].ch_no = i;
+ sdma->dma_ch->tx_dma_info[i].direction = 1;
+ ast_uart_sdma_write(sdma, 0, UART_TX_W_POINT(i));
+ // RX ------------------------
+ sdma->dma_ch->rx_dma_info[i].enable = 0;
+ sdma->dma_ch->rx_dma_info[i].ch_no = i;
+ sdma->dma_ch->rx_dma_info[i].direction = 0;
+ sdma->dma_ch->rx_dma_info[i].sdma_virt_addr =
+ rx_dma_virt_addr + (SDMA_RX_BUFF_SIZE * i);
+ sdma->dma_ch->rx_dma_info[i].dma_phy_addr =
+ rx_dma_phy_addr + (SDMA_RX_BUFF_SIZE * i);
+ ast_uart_sdma_write(sdma,
+ sdma->dma_ch->rx_dma_info[i].dma_phy_addr,
+ UART_RX_SDMA_ADDR(i));
+ ast_uart_sdma_write(sdma, 0, UART_RX_R_POINT(i));
+ }
+
+ ast_uart_sdma_write(sdma, 0xffffffff, UART_TX_SDMA_REST);
+ ast_uart_sdma_write(sdma, 0x0, UART_TX_SDMA_REST);
+
+ ast_uart_sdma_write(sdma, 0xffffffff, UART_RX_SDMA_REST);
+ ast_uart_sdma_write(sdma, 0x0, UART_RX_SDMA_REST);
+
+ ast_uart_sdma_write(sdma, 0, UART_TX_SDMA_EN);
+ ast_uart_sdma_write(sdma, 0, UART_RX_SDMA_EN);
+
+#ifdef SDDMA_RX_FIX
+ ast_uart_sdma_write(sdma, 0x200, UART_SDMA_TIMER);
+#else
+ ast_uart_sdma_write(sdma, 0xffff, UART_SDMA_TIMER);
+#endif
+
+ // TX
+ ast_uart_sdma_write(sdma, 0xfff, UART_TX_SDMA_ISR);
+ ast_uart_sdma_write(sdma, 0, UART_TX_SDMA_IER);
+
+ // RX
+ ast_uart_sdma_write(sdma, 0xfff, UART_RX_SDMA_ISR);
+ ast_uart_sdma_write(sdma, 0, UART_RX_SDMA_IER);
+
+ sdma->dma_irq = of_irq_get(node, 0);
+ ret = request_irq(sdma->dma_irq, ast_uart_sdma_isr, 0,
+ "sdma-intr", sdma);
+ if (ret) {
+ pr_debug("Unable to get UART SDMA IRQ %x\n", ret);
+ return -ENODEV;
+ }
+
+ ast_uart_sdma_write(sdma, SDMA_SET_TX_BUFF_SIZE(SDMA_BUFF_SIZE_4KB) |
+ SDMA_SET_RX_BUFF_SIZE(SDMA_BUFF_SIZE_64KB),
+ UART_SDMA_CONF);
+ return 0;
+}
+
+// END of SDMA Layer
+
+// UART Driver Layer
+
+static unsigned int ast_serial_in(struct uart_8250_port *up, int offset)
+{
+ offset = map_8250_in_reg(up, offset) << up->port.regshift;
+ return readb(up->port.membase + offset);
+}
+
+static void ast_serial_out(struct uart_8250_port *up, int offset, int value)
+{
+ /* Save the offset before it's remapped */
+ offset = map_8250_out_reg(up, offset) << up->port.regshift;
+ writeb(value, up->port.membase + offset);
+}
+
+/*
+ * We used to support using pause I/O for certain machines. We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(up, offset) ast_serial_in(up, offset)
+#define serial_outp(up, offset, value) ast_serial_out(up, offset, value)
+
+/* Uart divisor latch read */
+static inline int _serial_dl_read(struct uart_8250_port *up)
+{
+ return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static inline void _serial_dl_write(struct uart_8250_port *up, int value)
+{
+ serial_outp(up, UART_DLL, value & 0xff);
+ serial_outp(up, UART_DLM, value >> 8 & 0xff);
+}
+
+#define serial_dl_read(up) _serial_dl_read(up)
+#define serial_dl_write(up, value) _serial_dl_write(up, value)
+
+static void ast_uart_tx_sdma_tasklet_func(unsigned long data)
+{
+
+ struct ast_uart_priv_data *priv = (struct ast_uart_priv_data *)data;
+ struct uart_8250_port *up = priv->up;
+ struct circ_buf *xmit = NULL;
+ u32 tx_pt;
+
+
+ if (!up)
+ return;
+ xmit = &up->port.state->xmit;
+ spin_lock(&up->port.lock);
+ priv->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
+ dma_sync_single_for_device(up->port.dev, priv->dma_tx_addr,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ tx_pt = ast_uart_get_tx_sdma_pt(priv->dma_ch);
+
+ if (tx_pt > xmit->head) {
+ if ((tx_pt & 0xfffc) == 0)
+ ast_uart_tx_sdma_update(priv->dma_ch, 0xffff);
+ else
+ ast_uart_tx_sdma_update(priv->dma_ch, 0);
+ } else {
+ ast_uart_tx_sdma_update(priv->dma_ch, xmit->head);
+ }
+ ast_uart_tx_sdma_update(priv->dma_ch, xmit->head);
+ spin_unlock(&up->port.lock);
+}
+
+static void ast_uart_tx_buffdone(void *dev_id, u16 len)
+{
+
+ struct ast_uart_priv_data *priv = (struct ast_uart_priv_data *)dev_id;
+ struct uart_8250_port *up = priv->up;
+ struct circ_buf *xmit;
+
+ if (!up)
+ return;
+ xmit = &(up->port.state->xmit);
+
+ pr_debug("line[%d] : tx len = % d\n", priv->line, len);
+ spin_lock(&up->port.lock);
+ xmit->tail = len;
+ pr_debug(" line[%d], xmit->head = %d, xmit->tail = % d\n",
+ priv->line, xmit->head, xmit->tail);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&up->port);
+
+ if (xmit->head != xmit->tail)
+ tasklet_schedule(&priv->tx_tasklet);
+
+ spin_unlock(&up->port.lock);
+}
+
+#ifdef SDDMA_RX_FIX
+static void ast_uart_rx_sdma_tasklet_func(unsigned long data)
+{
+ struct ast_uart_priv_data *priv = (struct ast_uart_priv_data *)data;
+ struct circ_buf *rx_ring = &priv->rx_dma_buf;
+ struct tty_port *ttyport;
+ int count;
+ int copy = 0;
+ struct uart_8250_port *up = priv->up;
+
+ if (!up)
+ return;
+
+ ttyport = &up->port.state->port;
+
+ pr_debug("line[%d], rx_ring->head = % d, rx_ring->tail = % d\n",
+ up->port.line, rx_ring->head, rx_ring->tail);
+ spin_lock(&up->port.lock);
+ if (rx_ring->head > rx_ring->tail) {
+ count = rx_ring->head - rx_ring->tail;
+ copy = tty_insert_flip_string(ttyport,
+ rx_ring->buf + rx_ring->tail, count);
+ } else if (rx_ring->head < rx_ring->tail) {
+ count = SDMA_RX_BUFF_SIZE - rx_ring->tail;
+ copy = tty_insert_flip_string(ttyport,
+ rx_ring->buf + rx_ring->tail, count);
+ } else {
+ count = 0;
+ }
+
+ if (copy != count)
+ pr_debug(" !!!!!!!!ERROR 111\n");
+ if (count) {
+ rx_ring->tail += count;
+ rx_ring->tail &= (SDMA_RX_BUFF_SIZE - 1);
+ up->port.icount.rx += count;
+ tty_flip_buffer_push(ttyport);
+ ast_uart_rx_sdma_update(priv->dma_ch, rx_ring->tail);
+ }
+ spin_unlock(&up->port.lock);
+}
+
+static void ast_uart_rx_buffdone(void *dev_id, u16 len)
+{
+ struct ast_uart_priv_data *priv = (struct ast_uart_priv_data *)dev_id;
+ struct circ_buf *rx_ring = &priv->rx_dma_buf;
+ struct uart_8250_port *up = priv->up;
+
+ if (!up)
+ return;
+ pr_debug("line[%d], head = %d,len:%d\n",
+ priv->line, priv->rx_dma_buf.head, len);
+ spin_lock(&up->port.lock);
+ rx_ring->head = len;
+ spin_unlock(&up->port.lock);
+ tasklet_schedule(&priv->rx_tasklet);
+}
+
+#else
+static void ast_uart_rx_timer_func(unsigned long data)
+{
+ struct ast_uart_priv_data *priv = (struct ast_uart_priv_data *)data;
+ struct uart_8250_port *up = priv->up;
+ struct tty_port *ttyport;
+ struct circ_buf *rx_ring;
+ struct tty_struct *tty;
+ char flag;
+ int count;
+ int copy;
+
+
+ if (!up)
+ return;
+ ttyport = &up->port.state->port;
+ rx_ring = &up->rx_dma_buf;
+ tty = up->port.state->port.tty;
+
+ pr_debug("line[%d], rx_ring->head = % d, rx_ring->tail = % d\n",
+ up->port.line, rx_ring->head, rx_ring->tail);
+ rx_ring->head = ast_uart_get_rx_sdma_pt(priv->dma_ch);
+ del_timer(&up->rx_timer);
+
+ if (rx_ring->head > rx_ring->tail) {
+ ast_uart_set_sdma_time_out(0xffff);
+ count = rx_ring->head - rx_ring->tail;
+ copy = tty_insert_flip_string(ttyport,
+ rx_ring->buf + rx_ring->tail, count);
+ } else if (rx_ring->head < rx_ring->tail) {
+ ast_uart_set_sdma_time_out(0xffff);
+ count = SDMA_RX_BUFF_SIZE - rx_ring->tail;
+ copy = tty_insert_flip_string(ttyport,
+ rx_ring->buf + rx_ring->tail, count);
+ } else {
+ count = 0;
+ // pr_debug("@@--%s-- ch = 0x%x\n", __func__, ch);
+ }
+
+ if (copy != count)
+ pr_debug(" !!!!!!!!ERROR 111\n");
+ rx_ring->tail += count;
+ rx_ring->tail &= (SDMA_RX_BUFF_SIZE - 1);
+
+ if (count) {
+ //pr_debug("\n count = % d\n", count);
+ up->port.icount.rx += count;
+ spin_lock(&up->port.lock);
+ tty_flip_buffer_push(ttyport);
+ spin_unlock(&up->port.lock);
+ //pr_debug("update rx_ring->tail % x\n", rx_ring->tail);
+ ast_uart_rx_sdma_update(priv->dma_ch, rx_ring->tail);
+ priv->workaround = 1;
+ } else {
+ if (priv->workaround) {
+ priv->workaround++;
+ if (priv->workaround > 1)
+ ast_uart_set_sdma_time_out(0);
+ else
+ ast_uart_set_sdma_time_out(0xffff);
+ }
+ }
+ add_timer(&up->rx_timer);
+}
+#endif
+
+/*
+ * FIFO support.
+ */
+static inline void ast25xx_uart_clear_fifos(struct uart_8250_port *p)
+{
+ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_outp(p, UART_FCR,
+ UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+ serial_outp(p, UART_FCR, 0);
+}
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.
+ */
+static void autoconfig(struct uart_8250_port *up)
+{
+ unsigned long flags;
+
+ pr_debug("line[%d]\n", up->port.line);
+ if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
+ return;
+
+ pr_debug("ttyDMA%d : autoconf (0x%04lx, 0x%p) : ", up->port.line,
+ up->port.iobase, up->port.membase);
+
+ spin_lock_irqsave(&up->port.lock, flags);
+
+ up->capabilities = 0;
+ up->bugs = 0;
+
+ up->port.type = PORT_16550A;
+ up->capabilities |= UART_CAP_FIFO;
+
+ up->port.fifosize = uart_config[up->port.type].fifo_size;
+ up->capabilities = uart_config[up->port.type].flags;
+ up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
+
+ if (up->port.type == PORT_UNKNOWN)
+ goto out;
+
+ /*
+ * Reset the UART.
+ */
+ ast25xx_uart_clear_fifos(up);
+ ast_serial_in(up, UART_RX);
+ serial_outp(up, UART_IER, 0);
+
+out:
+ spin_unlock_irqrestore(&up->port.lock, flags);
+ pr_debug("type=%s\n", uart_config[up->port.type].name);
+}
+
+static inline void __stop_tx(struct uart_8250_port *p)
+{
+ if (p->ier & UART_IER_THRI) {
+ p->ier &= ~UART_IER_THRI;
+ ast_serial_out(p, UART_IER, p->ier);
+ }
+}
+
+static void ast25xx_uart_stop_tx(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+
+ pr_debug("line[%d]\n", up->port.line);
+ __stop_tx(up);
+}
+
+static void transmit_chars(struct uart_8250_port *up);
+
+static void ast25xx_uart_start_tx(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ struct ast_uart_priv_data *priv = up->port.private_data;
+
+ pr_debug("line[%d]\n", port->line);
+ tasklet_schedule(&priv->tx_tasklet);
+}
+
+static void ast25xx_uart_stop_rx(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+
+ pr_debug("line[%d]\n", port->line);
+ up->ier &= ~UART_IER_RLSI;
+ up->port.read_status_mask &= ~UART_LSR_DR;
+ ast_serial_out(up, UART_IER, up->ier);
+}
+
+static void ast25xx_uart_enable_ms(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+
+ pr_debug("line[%d]\n", port->line);
+ up->ier |= UART_IER_MSI;
+ ast_serial_out(up, UART_IER, up->ier);
+}
+
+static void transmit_chars(struct uart_8250_port *up)
+{
+ struct circ_buf *xmit = &up->port.state->xmit;
+ int count;
+
+ if (up->port.x_char) {
+ serial_outp(up, UART_TX, up->port.x_char);
+ up->port.icount.tx++;
+ up->port.x_char = 0;
+ return;
+ }
+ if (uart_tx_stopped(&up->port)) {
+ ast25xx_uart_stop_tx(&up->port);
+ return;
+ }
+ if (uart_circ_empty(xmit)) {
+ __stop_tx(up);
+ return;
+ }
+
+ count = up->tx_loadsz;
+ do {
+ ast_serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ up->port.icount.tx++;
+ if (uart_circ_empty(xmit))
+ break;
+ } while (--count > 0);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&up->port);
+
+ if (uart_circ_empty(xmit))
+ __stop_tx(up);
+}
+
+static unsigned int check_modem_status(struct uart_8250_port *up)
+{
+ unsigned int status = ast_serial_in(up, UART_MSR);
+
+ pr_debug("line[%d]\n", up->port.line);
+ status |= up->msr_saved_flags;
+ up->msr_saved_flags = 0;
+ if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI
+ && up->port.state != NULL) {
+ if (status & UART_MSR_TERI)
+ up->port.icount.rng++;
+ if (status & UART_MSR_DDSR)
+ up->port.icount.dsr++;
+ if (status & UART_MSR_DDCD)
+ uart_handle_dcd_change(&up->port,
+ status & UART_MSR_DCD);
+ if (status & UART_MSR_DCTS)
+ uart_handle_cts_change(&up->port,
+ status & UART_MSR_CTS);
+
+ wake_up_interruptible(&up->port.state->port.delta_msr_wait);
+ }
+
+ return status;
+}
+
+/*
+ * This handles the interrupt from one port.
+ */
+static inline void ast25xx_uart_handle_port(struct uart_8250_port *up)
+{
+ unsigned int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+
+ status = serial_inp(up, UART_LSR);
+
+ pr_debug("status = %x\n", status);
+
+ check_modem_status(up);
+ if (status & UART_LSR_THRE)
+ transmit_chars(up);
+
+ spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/*
+ * This is the serial driver's interrupt routine.
+ */
+static irqreturn_t ast_uart_interrupt(int irq, void *dev_id)
+{
+ struct irq_info *i = dev_id;
+ int pass_counter = 0, handled = 0, end = 0;
+
+ pr_debug("(%d)-", irq);
+ spin_lock(&i->lock);
+
+ do {
+ struct uart_8250_port *up;
+ unsigned int iir;
+
+ up = (struct uart_8250_port *)(i->up);
+
+ iir = ast_serial_in(up, UART_IIR);
+ if (!(iir & UART_IIR_NO_INT)) {
+ ast25xx_uart_handle_port(up);
+ handled = 1;
+
+ } else
+ end = 1;
+
+ if (pass_counter++ > PASS_LIMIT) {
+ /* If we hit this, we're dead. */
+ pr_err("ast-uart-dma:too much work for irq%d\n", irq);
+ break;
+ }
+ } while (end);
+
+ spin_unlock(&i->lock);
+
+ pr_debug("-(%d)\n", irq);
+
+ return IRQ_RETVAL(handled);
+}
+
+static unsigned int ast25xx_uart_tx_empty(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ unsigned long flags;
+ unsigned int lsr;
+
+ pr_debug("line[%d]\n", up->port.line);
+
+ spin_lock_irqsave(&up->port.lock, flags);
+ lsr = ast_serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int ast25xx_uart_get_mctrl(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ unsigned int status;
+ unsigned int ret;
+
+ status = check_modem_status(up);
+
+ ret = 0;
+ if (status & UART_MSR_DCD)
+ ret |= TIOCM_CAR;
+ if (status & UART_MSR_RI)
+ ret |= TIOCM_RNG;
+ if (status & UART_MSR_DSR)
+ ret |= TIOCM_DSR;
+ if (status & UART_MSR_CTS)
+ ret |= TIOCM_CTS;
+ return ret;
+}
+
+static void ast25xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ unsigned char mcr = 0;
+
+ mctrl = 0;
+
+ if (mctrl & TIOCM_RTS)
+ mcr |= UART_MCR_RTS;
+ if (mctrl & TIOCM_DTR)
+ mcr |= UART_MCR_DTR;
+ if (mctrl & TIOCM_OUT1)
+ mcr |= UART_MCR_OUT1;
+ if (mctrl & TIOCM_OUT2)
+ mcr |= UART_MCR_OUT2;
+ if (mctrl & TIOCM_LOOP)
+ mcr |= UART_MCR_LOOP;
+
+ mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
+
+ ast_serial_out(up, UART_MCR, mcr);
+
+}
+
+static void ast25xx_uart_break_ctl(struct uart_port *port, int break_state)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ unsigned long flags;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+ if (break_state == -1)
+ up->lcr |= UART_LCR_SBC;
+ else
+ up->lcr &= ~UART_LCR_SBC;
+ ast_serial_out(up, UART_LCR, up->lcr);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int ast25xx_uart_startup(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ // TX DMA
+ struct circ_buf *xmit = &up->port.state->xmit;
+ struct ast_uart_priv_data *priv = up->port.private_data;
+ unsigned long flags;
+ unsigned char lsr, iir;
+ int retval;
+ int irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+
+ priv->up = up;
+ pr_debug("line[%d]\n", port->line);
+ up->capabilities = uart_config[up->port.type].flags;
+ up->mcr = 0;
+ /*
+ * Clear the FIFO buffers and disable them.
+ * (they will be reenabled in set_termios())
+ */
+ ast25xx_uart_clear_fifos(up);
+ /*
+ * Clear the interrupt registers.
+ */
+ (void)serial_inp(up, UART_LSR);
+ (void)serial_inp(up, UART_RX);
+ (void)serial_inp(up, UART_IIR);
+ (void)serial_inp(up, UART_MSR);
+
+ ast_uart_irq[0].up = up;
+ retval = request_irq(up->port.irq, ast_uart_interrupt, irq_flags,
+ "ast-uart-dma", ast_uart_irq);
+ if (retval)
+ return retval;
+
+ /*
+ * Now, initialize the UART
+ */
+ serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+
+ spin_lock_irqsave(&up->port.lock, flags);
+ up->port.mctrl |= TIOCM_OUT2;
+
+ ast25xx_uart_set_mctrl(&up->port, up->port.mctrl);
+
+ /*
+ * Do a quick test to see if we receive an
+ * interrupt when we enable the TX irq.
+ */
+ serial_outp(up, UART_IER, UART_IER_THRI);
+ lsr = ast_serial_in(up, UART_LSR);
+ iir = ast_serial_in(up, UART_IIR);
+ serial_outp(up, UART_IER, 0);
+
+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+ if (!(up->bugs & UART_BUG_TXEN)) {
+ up->bugs |= UART_BUG_TXEN;
+ pr_debug("ttyDMA%d-enabling bad tx status\n",
+ port->line);
+ }
+ } else {
+ up->bugs &= ~UART_BUG_TXEN;
+ }
+
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ /*
+ * Clear the interrupt registers again for luck, and clear the
+ * saved flags to avoid getting false values from polling
+ * routines or the previous session.
+ */
+ serial_inp(up, UART_LSR);
+ serial_inp(up, UART_RX);
+ serial_inp(up, UART_IIR);
+ serial_inp(up, UART_MSR);
+ up->lsr_saved_flags = 0;
+ up->msr_saved_flags = 0;
+
+ // RX DMA
+ priv->rx_dma_buf.head = 0;
+ priv->rx_dma_buf.tail = 0;
+ up->port.icount.rx = 0;
+
+ priv->tx_done = 1;
+ priv->tx_count = 0;
+
+ priv->rx_dma_buf.head = 0;
+ priv->rx_dma_buf.tail = 0;
+#ifdef SDDMA_RX_FIX
+#else
+ priv->workaround = 0;
+#endif
+ // pr_debug("Sending trigger for % x\n", priv->dma_ch);
+ ast_uart_rx_sdma_ctrl(priv->dma_ch, AST_UART_DMAOP_STOP);
+ ast_uart_rx_sdma_ctrl(priv->dma_ch, AST_UART_DMAOP_TRIGGER);
+#ifdef SDDMA_RX_FIX
+#else
+ add_timer(&priv->rx_timer);
+#endif
+ priv->tx_dma_buf.head = 0;
+ priv->tx_dma_buf.tail = 0;
+ priv->tx_dma_buf.buf = xmit->buf;
+
+ pr_debug("head:0x%x tail:0x%x\n", xmit->head, xmit->tail);
+ xmit->head = 0;
+ xmit->tail = 0;
+
+ priv->dma_tx_addr = dma_map_single(port->dev, priv->tx_dma_buf.buf,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+
+ ast_uart_tx_sdma_ctrl(priv->dma_ch, AST_UART_DMAOP_STOP);
+ ast_uart_tx_sdma_enqueue(priv->dma_ch, priv->dma_tx_addr);
+ ast_uart_tx_sdma_update(priv->dma_ch, 0);
+ ast_uart_tx_sdma_ctrl(priv->dma_ch, AST_UART_DMAOP_TRIGGER);
+ return 0;
+}
+
+static void ast25xx_uart_shutdown(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ struct ast_uart_priv_data *priv = up->port.private_data;
+ unsigned long flags;
+
+ pr_debug("line[%d]\n", port->line);
+ priv->up = NULL;
+
+ up->ier = 0;
+ serial_outp(up, UART_IER, 0);
+
+ spin_lock_irqsave(&up->port.lock, flags);
+ up->port.mctrl &= ~TIOCM_OUT2;
+
+ ast25xx_uart_set_mctrl(&up->port, up->port.mctrl);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ /*
+ * Disable break condition and FIFOs
+ */
+ ast_serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
+ ast25xx_uart_clear_fifos(up);
+
+ (void)ast_serial_in(up, UART_RX);
+
+ ast_uart_rx_sdma_ctrl(priv->dma_ch, AST_UART_DMAOP_PAUSE);
+ ast_uart_tx_sdma_ctrl(priv->dma_ch, AST_UART_DMAOP_PAUSE);
+#ifdef SDDMA_RX_FIX
+#else
+ del_timer_sync(&up->rx_timer);
+#endif
+
+ // Tx buffer will free by serial_core.c
+ free_irq(up->port.irq, ast_uart_irq);
+}
+
+static unsigned int ast25xx_uart_get_divisor(struct uart_port *port,
+ unsigned int baud)
+{
+ unsigned int quot;
+
+ quot = uart_get_divisor(port, baud);
+
+ return quot;
+}
+
+static void ast25xx_uart_set_termios(struct uart_port *port,
+ struct ktermios *termios,
+ struct ktermios *old)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ unsigned char cval, fcr = 0;
+ unsigned long flags;
+ unsigned int baud, quot;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ cval = UART_LCR_WLEN5;
+ break;
+ case CS6:
+ cval = UART_LCR_WLEN6;
+ break;
+ case CS7:
+ cval = UART_LCR_WLEN7;
+ break;
+ default:
+ case CS8:
+ cval = UART_LCR_WLEN8;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ cval |= UART_LCR_STOP;
+ if (termios->c_cflag & PARENB)
+ cval |= UART_LCR_PARITY;
+ if (!(termios->c_cflag & PARODD))
+ cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ cval |= UART_LCR_SPAR;
+#endif
+
+ /*
+ * Ask the core to calculate the divisor for us.
+ */
+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
+ quot = ast25xx_uart_get_divisor(port, baud);
+
+ if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
+ if (baud < 2400)
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+ else
+ fcr = uart_config[up->port.type].fcr;
+ }
+
+ /*
+ * Ok, we're now changing the port state. Do it with
+ * interrupts disabled.
+ */
+ spin_lock_irqsave(&up->port.lock, flags);
+
+ /*
+ * Update the per-port timeout.
+ */
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+ if (termios->c_iflag & INPCK)
+ up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ up->port.read_status_mask |= UART_LSR_BI;
+
+ /*
+ * Characteres to ignore
+ */
+ up->port.ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+ if (termios->c_iflag & IGNBRK) {
+ up->port.ignore_status_mask |= UART_LSR_BI;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns too (for real raw support).
+ */
+ if (termios->c_iflag & IGNPAR)
+ up->port.ignore_status_mask |= UART_LSR_OE;
+ }
+
+ /*
+ * ignore all characters if CREAD is not set
+ */
+ if ((termios->c_cflag & CREAD) == 0)
+ up->port.ignore_status_mask |= UART_LSR_DR;
+
+ /*
+ * CTS flow control flag and modem status interrupts
+ */
+ up->ier &= ~UART_IER_MSI;
+ if (UART_ENABLE_MS(&up->port, termios->c_cflag))
+ up->ier |= UART_IER_MSI;
+
+ ast_serial_out(up, UART_IER, up->ier);
+
+ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
+
+ serial_dl_write(up, quot);
+
+ /*
+ * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
+ * is written without DLAB set, this mode will be disabled.
+ */
+
+ serial_outp(up, UART_LCR, cval); /* reset DLAB */
+ up->lcr = cval; /* Save LCR */
+ if (fcr & UART_FCR_ENABLE_FIFO) {
+ /* emulated UARTs (Lucent Venus 167x) need two steps */
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ }
+ serial_outp(up, UART_FCR, fcr); /* set fcr */
+ ast25xx_uart_set_mctrl(&up->port, up->port.mctrl);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+ /* Don't rewrite B0 */
+ if (tty_termios_baud_rate(termios))
+ tty_termios_encode_baud_rate(termios, baud, baud);
+}
+
+/*
+ * Resource handling.
+ */
+static int ast25xx_uart_request_std_resource(struct uart_8250_port *up)
+{
+ unsigned int size = 8 << up->port.regshift;
+ int ret = 0;
+
+ if (!up->port.mapbase)
+ return ret;
+
+ if (!request_mem_region(up->port.mapbase, size, "ast-uart-dma")) {
+ ret = -EBUSY;
+ return ret;
+ }
+
+ if (up->port.flags & UPF_IOREMAP) {
+ up->port.membase = ioremap_nocache(up->port.mapbase, size);
+ if (!up->port.membase) {
+ release_mem_region(up->port.mapbase, size);
+ ret = -ENOMEM;
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static void ast25xx_uart_release_std_resource(struct uart_8250_port *up)
+{
+ unsigned int size = 8 << up->port.regshift;
+
+ if (!up->port.mapbase)
+ return;
+
+ if (up->port.flags & UPF_IOREMAP) {
+ iounmap(up->port.membase);
+ up->port.membase = NULL;
+ }
+
+ release_mem_region(up->port.mapbase, size);
+}
+
+static void ast25xx_uart_release_port(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+
+ ast25xx_uart_release_std_resource(up);
+}
+
+static int ast25xx_uart_request_port(struct uart_port *port)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ int ret;
+
+ ret = ast25xx_uart_request_std_resource(up);
+ if (ret == 0)
+ ast25xx_uart_release_std_resource(up);
+
+ return ret;
+}
+
+static void ast25xx_uart_config_port(struct uart_port *port, int flags)
+{
+ struct uart_8250_port *up = to_uart_8250_port(port);
+ int ret;
+
+ /*
+ * Find the region that we can probe for. This in turn
+ * tells us whether we can probe for the type of port.
+ */
+ ret = ast25xx_uart_request_std_resource(up);
+ if (ret < 0)
+ return;
+
+ if (flags & UART_CONFIG_TYPE)
+ autoconfig(up);
+
+ if (up->port.type == PORT_UNKNOWN)
+ ast25xx_uart_release_std_resource(up);
+}
+
+static int ast25xx_uart_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ return 0;
+}
+
+static const char *ast25xx_uart_type(struct uart_port *port)
+{
+ int type = port->type;
+
+ if (type >= ARRAY_SIZE(uart_config))
+ type = 0;
+ return uart_config[type].name;
+}
+
+
+
+static unsigned int ast25xx_uart_serial_in(struct uart_port *port, int offset)
+{
+ offset = offset << port->regshift;
+ return readb(port->membase + offset);
+
+}
+
+
+static void ast25xx_uart_serial_out(struct uart_port *port,
+ int offset, int value)
+{
+ offset = offset << port->regshift;
+ writeb(value, port->membase + offset);
+}
+
+static const struct uart_ops ast25xx_uart_pops = {
+ .tx_empty = ast25xx_uart_tx_empty,
+ .set_mctrl = ast25xx_uart_set_mctrl,
+ .get_mctrl = ast25xx_uart_get_mctrl,
+ .stop_tx = ast25xx_uart_stop_tx,
+ .start_tx = ast25xx_uart_start_tx,
+ .stop_rx = ast25xx_uart_stop_rx,
+ .enable_ms = ast25xx_uart_enable_ms,
+ .break_ctl = ast25xx_uart_break_ctl,
+ .startup = ast25xx_uart_startup,
+ .shutdown = ast25xx_uart_shutdown,
+ .set_termios = ast25xx_uart_set_termios,
+ .type = ast25xx_uart_type,
+ .release_port = ast25xx_uart_release_port,
+ .request_port = ast25xx_uart_request_port,
+ .config_port = ast25xx_uart_config_port,
+ .verify_port = ast25xx_uart_verify_port,
+};
+
+
+
+/*
+ * Register a set of serial devices attached to a platform device. The
+ * list is terminated with a zero flags entry, which means we expect
+ * all entries to have at least UPF_BOOT_AUTOCONF set.
+ */
+struct clk *clk;
+
+static int ast25xx_uart_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ast_uart_priv_data *priv;
+ struct uart_8250_port port_8250;
+ struct uart_8250_port *up;
+ int ret;
+ u32 read, dma_channel = 0;
+ struct resource *res;
+
+ if (UART_XMIT_SIZE > DMA_BUFF_SIZE)
+ pr_debug("UART_XMIT_SIZE > DMA_BUFF_SIZE : Please Check\n");
+
+ priv = (struct ast_uart_priv_data *)devm_kzalloc(&pdev->dev,
+ sizeof(struct ast_uart_priv_data), GFP_KERNEL);
+ if (priv == NULL)
+ return -ENOMEM;
+
+ up = &port_8250;
+ memset(up, 0, sizeof(struct uart_8250_port));
+ up->port.flags = UPF_IOREMAP;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "IRQ resource not found");
+ return -ENODEV;
+ }
+ up->port.irq = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Register base not found");
+ return -ENODEV;
+ }
+ up->port.mapbase = res->start;
+
+ ret = ast25xx_uart_request_std_resource(up);
+ if (ret) {
+ dev_err(&pdev->dev, "ioremap_nocache Failed");
+ return ret;
+ }
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk))
+ dev_err(&pdev->dev, "missing controller clock");
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ dev_err(&pdev->dev, "failed to enable DMA UART Clk");
+
+ up->port.uartclk = clk_get_rate(clk);
+
+ if (of_property_read_u32(np, "reg-shift", &read) == 0)
+ up->port.regshift = read;
+ if (of_property_read_u32(np, "dma-channel", &read) == 0) {
+ dma_channel = read;
+ priv->dma_ch = dma_channel;
+ }
+ up->port.iotype = UPIO_MEM;
+ up->port.flags |= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ up->port.dev = &pdev->dev;
+ if (share_irqs)
+ up->port.flags |= UPF_SHARE_IRQ;
+ up->port.fifosize = uart_config[up->port.type].fifo_size;
+ up->port.type = PORT_16550;
+ up->port.iotype = UPIO_MEM;
+ up->port.flags = UPF_FIXED_TYPE;
+ up->port.startup = ast25xx_uart_startup;
+ up->port.shutdown = ast25xx_uart_shutdown;
+ up->port.set_termios = ast25xx_uart_set_termios;
+ up->port.set_mctrl = ast25xx_uart_set_mctrl;
+ up->port.serial_in = ast25xx_uart_serial_in;
+ up->port.serial_out = ast25xx_uart_serial_out;
+ up->capabilities = uart_config[up->port.type].flags;
+ up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
+ up->capabilities |= UART_CAP_FIFO;
+
+ up->port.private_data = priv;
+
+ ret = serial8250_register_8250_port(up);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "unable to registr port (IO%lx MEM%llx IRQ%d):%d\n",
+ up->port.iobase, (unsigned long long)up->port.mapbase,
+ up->port.irq, ret);
+ return ret;
+ }
+ priv->line = ret;
+
+ tasklet_init(&priv->tx_tasklet, ast_uart_tx_sdma_tasklet_func,
+ (unsigned long)priv);
+#ifdef SDDMA_RX_FIX
+ tasklet_init(&priv->rx_tasklet, ast_uart_rx_sdma_tasklet_func,
+ (unsigned long)priv);
+#else
+ uart->rx_timer.data = (unsigned long)port;
+ uart->rx_timer.expires = jiffies + (HZ);
+ uart->rx_timer.function = ast_uart_rx_timer_func;
+ init_timer(&priv->rx_timer);
+#endif
+
+//DMA request
+#ifdef SDDMA_RX_FIX
+ priv->rx_dma_buf.buf =
+ ast_uart_rx_sdma_request(priv->dma_ch, ast_uart_rx_buffdone,
+ priv);
+ if (priv->rx_dma_buf.buf < 0) {
+ pr_debug("Error : failed to get rx dma channel[%d]\n",
+ priv->dma_ch);
+ return -EBUSY;
+}
+#else
+ priv->rx_dma_buf.buf = ast_uart_rx_sdma_request(
+ priv->dma_ch, priv);
+ if (priv->rx_dma_buf.buf < 0) {
+ pr_debug("Error : failed to get rx dma channel[%d]\n",
+ priv->dma_ch);
+ return -EBUSY;
+ }
+#endif
+ if (ast_uart_tx_sdma_request(
+ priv->dma_ch, ast_uart_tx_buffdone, priv) < 0) {
+ pr_debug("Error : failed to get tx dma channel[%d]\n",
+ priv->dma_ch);
+ return -EBUSY;
+ }
+
+ platform_set_drvdata(pdev, priv);
+ return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int ast25xx_uart_remove(struct platform_device *pdev)
+{
+ struct ast_uart_priv_data *priv;
+
+ priv = platform_get_drvdata(pdev);
+ serial8250_unregister_port(priv->line);
+ return 0;
+}
+
+static int ast25xx_uart_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ast_uart_priv_data *priv;
+
+ priv = platform_get_drvdata(pdev);
+ serial8250_suspend_port(priv->line);
+ return 0;
+}
+
+static int ast25xx_uart_resume(struct platform_device *pdev)
+{
+ struct ast_uart_priv_data *priv;
+
+ priv = platform_get_drvdata(pdev);
+ serial8250_resume_port(priv->line);
+ return 0;
+}
+
+static const struct of_device_id ast_serial_dt_ids[] = {
+ { .compatible = "aspeed,ast-sdma-uart", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver ast25xx_uart_driver = {
+ .probe = ast25xx_uart_probe,
+ .remove = ast25xx_uart_remove,
+ .suspend = ast25xx_uart_suspend,
+ .resume = ast25xx_uart_resume,
+ .driver = {
+ .name = "ast-uart-dma",
+ .of_match_table = of_match_ptr(ast_serial_dt_ids),
+ },
+};
+
+static int __init ast_uart_init(void)
+{
+ int ret;
+
+ if (nr_uarts > UART_DMA_NR)
+ nr_uarts = UART_DMA_NR;
+
+ ret = ast_uart_sdma_probe();
+ if (ret) {
+ pr_debug("ast_uart_sdma_probe Failed ret = %d\n", ret);
+ goto out;
+ }
+ pr_debug("UART driver with DMA%d ports IRQ sharing %sabled\n",
+ nr_uarts, share_irqs ? "en" : "dis");
+
+ spin_lock_init(&ast_uart_irq[0].lock);
+
+ ret = platform_driver_register(&ast25xx_uart_driver);
+ if (ret == 0)
+ goto out;
+
+out:
+ return ret;
+}
+
+static void __exit ast_uart_exit(void)
+{
+
+ platform_driver_unregister(&ast25xx_uart_driver);
+
+}
+module_init(ast_uart_init);
+module_exit(ast_uart_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AST DMA serial driver");
+MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
--
2.17.1
^ permalink raw reply related
* [patch 0/5] *** DMA based UART driver for AST2500 ***
From: sudheer.v @ 2019-06-21 11:17 UTC (permalink / raw)
To: linux-aspeed
From: sudheer veliseti <sudheer.open@gmail.com>
Hi,
AST2500 has dedicated Uart DMA controller which has 12 sets of
Tx and RX channels connected to UART controller directly.
Since the DMA controller have dedicated buffers and registers,
there would be little benifit in adding DMA framework overhead.
So the software for DMA controller is included within the UART driver itself.
Thanks and Regards
Sudheer.V
sudheer veliseti (5):
AST2500 DMA UART driver
build configuration for AST2500 DMA UART driver
DT nodes for AST2500 DMA UART driver
defconfig and MAINTAINERS updated for AST2500 DMA UART driver
Documentation: DT bindings AST2500 DMA UART driver
.../bindings/serial/ast2500-dma-uart.txt | 40 +
MAINTAINERS | 13 +
arch/arm/boot/dts/aspeed-ast2500-evb.dts | 21 +
arch/arm/boot/dts/aspeed-g5.dtsi | 71 +-
arch/arm/configs/aspeed_g5_defconfig | 1 +
.../tty/serial/8250/8250_ast2500_uart_dma.c | 1879 +++++++++++++++++
drivers/tty/serial/8250/Kconfig | 35 +-
drivers/tty/serial/8250/Makefile | 1 +
8 files changed, 2056 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/serial/ast2500-dma-uart.txt
create mode 100644 drivers/tty/serial/8250/8250_ast2500_uart_dma.c
--
2.17.1
^ permalink raw reply
* [PATCH] soc: aspeed: lpc-ctrl: Fix probe error handling
From: Andrew Jeffery @ 2019-06-21 1:56 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20190620091738.14683-1-joel@jms.id.au>
On Thu, 20 Jun 2019, at 18:47, Joel Stanley wrote:
> gcc warns that a mising "flash" phandle node leads to undefined
> behavior later:
>
> drivers/soc/aspeed/aspeed-lpc-ctrl.c: In function
> 'aspeed_lpc_ctrl_probe':
> drivers/soc/aspeed/aspeed-lpc-ctrl.c:201:18: error: '*((void
> *)&resm+8)' may be used uninitialized in this function
> [-Werror=maybe-uninitialized]
>
> Only set the flash base and size if we find a phandle in the device
> tree.
Ugh, yeah. Not sure how I missed that. Thanks for fixing it.
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
>
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/soc/aspeed/aspeed-lpc-ctrl.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> index aca13779764a..eee26c2d8b52 100644
> --- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> +++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> @@ -223,10 +223,11 @@ static int aspeed_lpc_ctrl_probe(struct
> platform_device *pdev)
> dev_err(dev, "Couldn't address to resource for flash\n");
> return rc;
> }
> +
> + lpc_ctrl->pnor_size = resource_size(&resm);
> + lpc_ctrl->pnor_base = resm.start;
> }
>
> - lpc_ctrl->pnor_size = resource_size(&resm);
> - lpc_ctrl->pnor_base = resm.start;
>
> dev_set_drvdata(&pdev->dev, lpc_ctrl);
>
> --
> 2.20.1
>
>
^ permalink raw reply
* [PATCH] soc: aspeed: lpc-ctrl: Fix probe error handling
From: Joel Stanley @ 2019-06-20 9:17 UTC (permalink / raw)
To: linux-aspeed
gcc warns that a mising "flash" phandle node leads to undefined
behavior later:
drivers/soc/aspeed/aspeed-lpc-ctrl.c: In function 'aspeed_lpc_ctrl_probe':
drivers/soc/aspeed/aspeed-lpc-ctrl.c:201:18: error: '*((void *)&resm+8)' may be used uninitialized in this function [-Werror=maybe-uninitialized]
Only set the flash base and size if we find a phandle in the device
tree.
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
drivers/soc/aspeed/aspeed-lpc-ctrl.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
index aca13779764a..eee26c2d8b52 100644
--- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
+++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
@@ -223,10 +223,11 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev)
dev_err(dev, "Couldn't address to resource for flash\n");
return rc;
}
+
+ lpc_ctrl->pnor_size = resource_size(&resm);
+ lpc_ctrl->pnor_base = resm.start;
}
- lpc_ctrl->pnor_size = resource_size(&resm);
- lpc_ctrl->pnor_base = resm.start;
dev_set_drvdata(&pdev->dev, lpc_ctrl);
--
2.20.1
^ permalink raw reply related
* [PATCH] soc: aspeed: fix probe error handling
From: Joel Stanley @ 2019-06-20 8:29 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20190619125636.1109665-1-arnd@arndb.de>
On Wed, 19 Jun 2019 at 12:56, Arnd Bergmann <arnd@arndb.de> wrote:
>
> gcc warns that a mising "flash" phandle node leads to undefined
> behavior later:
>
> drivers/soc/aspeed/aspeed-lpc-ctrl.c: In function 'aspeed_lpc_ctrl_probe':
> drivers/soc/aspeed/aspeed-lpc-ctrl.c:201:18: error: '*((void *)&resm+8)' may be used uninitialized in this function [-Werror=maybe-uninitialized]
>
> The device cannot work without this node, so just error out here.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Thanks Arnd. This looks like it applies on top of Vijay's recent patch?
The intent of that change was to make the driver usable for systems
that do not want to depend on the flash phandle. I think the fix we
want looks like this:
--- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
+++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
@@ -224,10 +224,11 @@ static int aspeed_lpc_ctrl_probe(struct
platform_device *pdev)
dev_err(dev, "Couldn't address to resource for
flash\n");
return rc;
}
+
+ lpc_ctrl->pnor_size = resource_size(&resm);
+ lpc_ctrl->pnor_base = resm.start;
}
- lpc_ctrl->pnor_size = resource_size(&resm);
- lpc_ctrl->pnor_base = resm.start;
Vijay, do you agree?
Cheers,
Joel
> ---
> drivers/soc/aspeed/aspeed-lpc-ctrl.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> index 239520bb207e..81109d22af6a 100644
> --- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> +++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
> @@ -212,6 +212,7 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev)
> node = of_parse_phandle(dev->of_node, "flash", 0);
> if (!node) {
> dev_dbg(dev, "Didn't find host pnor flash node\n");
> + return -ENXIO;
> } else {
> rc = of_address_to_resource(node, 1, &resm);
> of_node_put(node);
> --
> 2.20.0
>
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Tao Ren @ 2019-06-20 8:13 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <195bb56028d04001bbaf835cc17e032e@TWMBX02.aspeed.com>
On 6/20/19 1:01 AM, Ryan Chen wrote:
> Hello Tao,
> Let me more clear. When you set (3, 15, 14) the device sometimes response nack.
> but when you set (4, 7, 7), the device always ack. Am I right?
> Ryan
Hello Ryan,
It's correct. We have seen the problem on 2 Facebook BMC platforms so far. Given the other ~10 Facebook BMC platforms are still running kernel 4.1 (with (4, 7, 7) settings), I'd assume more platforms will be impacted after upgrading to the latest kernel.
Thank you for spending time on this!
Cheers,
Tao
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Ryan Chen @ 2019-06-20 8:01 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <bdd53adb-6987-1b91-adde-298839b2c066@fb.com>
Hello Tao,
Let me more clear. When you set (3, 15, 14) the device sometimes response nack.
but when you set (4, 7, 7), the device always ack. Am I right?
Ryan
-----Original Message-----
From: Tao Ren [mailto:taoren at fb.com]
Sent: Thursday, June 20, 2019 3:57 PM
To: Ryan Chen <ryan_chen@aspeedtech.com>; Brendan Higgins <brendanhiggins@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>; devicetree <devicetree@vger.kernel.org>; linux-aspeed at lists.ozlabs.org; OpenBMC Maillist <openbmc@lists.ozlabs.org>; Linux Kernel Mailing List <linux-kernel@vger.kernel.org>; Rob Herring <robh+dt@kernel.org>; Linux ARM <linux-arm-kernel@lists.infradead.org>; linux-i2c at vger.kernel.org
Subject: Re: [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
On 6/20/19 12:29 AM, Ryan Chen wrote:
> Hello Tao,
> Our recommend about clk divider setting is follow the datasheet clock setting table for clock divisor.
>
> Ryan
Thanks Ryan for the response. Could you also share some recommendations/hints on how to solve the intermittent i2c transaction failures on Facebook AST2500 BMC platforms?
BTW, the patch is not aimed at modifying the existing formula of calculating clock settings in i2c-aspeed driver: people still get the recommended settings by default. The goal of the patch is to allow people to customize clock settings in case the default/recommended one doesn't work.
Cheers,
Tao
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Tao Ren @ 2019-06-20 7:57 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <c610ecede7494c189a92a9a3f6d0fd16@TWMBX02.aspeed.com>
On 6/20/19 12:29 AM, Ryan Chen wrote:
> Hello Tao,
> Our recommend about clk divider setting is follow the datasheet clock setting table for clock divisor.
>
> Ryan
Thanks Ryan for the response. Could you also share some recommendations/hints on how to solve the intermittent i2c transaction failures on Facebook AST2500 BMC platforms?
BTW, the patch is not aimed at modifying the existing formula of calculating clock settings in i2c-aspeed driver: people still get the recommended settings by default. The goal of the patch is to allow people to customize clock settings in case the default/recommended one doesn't work.
Cheers,
Tao
^ permalink raw reply
* [GIT PULL] ARM: aspeed: dts changes for 5.3
From: Joel Stanley @ 2019-06-20 7:34 UTC (permalink / raw)
To: linux-aspeed
Hello ARM maintainers,
Here's the ASPEED device tree changes for 5.3. Most of the patches
have been baking for a number of weeks, with a few late changes added
in today.
The following changes since commit a188339ca5a396acc588e5851ed7e19f66b0ebd9:
Linux 5.2-rc1 (2019-05-19 15:47:09 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git \
tags/aspeed-5.3-devicetree
for you to fetch changes up to 6084110a0e9c4bff75970f3d68091ceff9e2c2c7:
ARM: dts: aspeed: Enable video engine on romulus and wtherspoon
(2019-06-20 16:37:26 +0930)
----------------------------------------------------------------
ASPEED device tree updates for 5.3
We have various device tree updates from the OpenBMC project to enable
bits and pieces in existing systems, notably updates to Google's Zaius.
There are some AST2500 machines under development:
* Lenovo Hr630
* IBM Swift
* Facebook YAMP
And some AST2400 machines that have been around but out of tree and have
now joined the party:
* YADRO VESNIN
* Microsoft Olympus
----------------------------------------------------------------
Adriana Kobylak (2):
ARM: dts: aspeed: Add Swift BMC machine
ARM: dts: aspeed: swift: Add pca9539 devices
Alexander Filippov (1):
ARM: dts: aspeed: Add YADRO VESNIN BMC
Andrew Peng (1):
ARM: dts: aspeed: Adding Lenovo Hr630 BMC
Benjamin Herrenschmidt (1):
ARM: dts: aspeed: Add Power9 and Power9 CFAM description
Eddie James (1):
ARM: dts: aspeed: Enable video engine on romulus and wtherspoon
Hongwei Zhang (1):
ARM: dts: aspeed: Add Microsoft Olympus BMC
Joel Stanley (1):
ARM: dts: aspeed: Rename flash-controller nodes
John Wang (1):
ARM: dts: aspeed: Add Inspur fp5280g2 BMC machine
Maxim Sloyko (1):
ARM: dts: aspeed: zaius: add Infineon and Intersil regulators
Patrick Venture (2):
ARM: dts: aspeed: Add aspeed-p2a-ctrl node
ARM: dts: aspeed: quanta-q71: Enable p2a node
Robert Lippert (2):
ARM: dts: aspeed: zaius: update 12V brick I2C address
ARM: dts: aspeed: zaius: fixed I2C bus numbers for pcie slots
Tao Ren (2):
ARM: dts: aspeed: cmm: enable ehci host controllers
ARM: dts: aspeed: Add Facebook YAMP BMC
arch/arm/boot/dts/Makefile | 6 +
arch/arm/boot/dts/aspeed-bmc-facebook-cmm.dts | 8 +
arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts | 160 ++++
arch/arm/boot/dts/aspeed-bmc-inspur-fp5280g2.dts | 846 ++++++++++++++++++
arch/arm/boot/dts/aspeed-bmc-lenovo-hr630.dts | 566 ++++++++++++
arch/arm/boot/dts/aspeed-bmc-microsoft-olympus.dts | 207 +++++
arch/arm/boot/dts/aspeed-bmc-opp-lanyang.dts | 2 +
arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 22 +
arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts | 14 +
arch/arm/boot/dts/aspeed-bmc-opp-swift.dts | 966 +++++++++++++++++++++
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 224 +++++
arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts | 14 +
arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts | 123 ++-
arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts | 5 +
arch/arm/boot/dts/aspeed-g4.dtsi | 8 +-
arch/arm/boot/dts/aspeed-g5.dtsi | 11 +-
arch/arm/boot/dts/ibm-power9-dual.dtsi | 248 ++++++
17 files changed, 3417 insertions(+), 13 deletions(-)
create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts
create mode 100644 arch/arm/boot/dts/aspeed-bmc-inspur-fp5280g2.dts
create mode 100644 arch/arm/boot/dts/aspeed-bmc-lenovo-hr630.dts
create mode 100644 arch/arm/boot/dts/aspeed-bmc-microsoft-olympus.dts
create mode 100644 arch/arm/boot/dts/aspeed-bmc-opp-swift.dts
create mode 100644 arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
create mode 100644 arch/arm/boot/dts/ibm-power9-dual.dtsi
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Ryan Chen @ 2019-06-20 7:29 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <18565fcf-3dc1-b671-f826-e4417e4ad284@fb.com>
Hello Tao,
Our recommend about clk divider setting is follow the datasheet clock setting table for clock divisor.
Ryan
-----Original Message-----
From: Linux-aspeed [mailto:linux-aspeed-bounces+ryan_chen=aspeedtech.com at lists.ozlabs.org] On Behalf Of Tao Ren
Sent: Thursday, June 20, 2019 6:33 AM
To: Brendan Higgins <brendanhiggins@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>; devicetree <devicetree@vger.kernel.org>; linux-aspeed at lists.ozlabs.org; OpenBMC Maillist <openbmc@lists.ozlabs.org>; Linux Kernel Mailing List <linux-kernel@vger.kernel.org>; Rob Herring <robh+dt@kernel.org>; Linux ARM <linux-arm-kernel@lists.infradead.org>; linux-i2c at vger.kernel.org
Subject: Re: [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
On 6/19/19 2:25 PM, Brendan Higgins wrote:
> On Wed, Jun 19, 2019 at 2:00 PM Tao Ren <taoren@fb.com> wrote:
>>
>> Some intermittent I2C transaction failures are observed on Facebook
>> CMM and Minipack (ast2500) BMC platforms, because slave devices (such
>> as CPLD, BIC and etc.) NACK the address byte sometimes. The issue can
>> be resolved by increasing base clock divisor which affects ASPEED I2C
>> Controller's base clock and other AC timing parameters.
>>
>> This patch allows to customize ASPEED I2C Controller's base clock
>> divisor in device tree.
>
> First off, are you sure you actually need this?
>
> You should be able to achieve an effectively equivalent result by just
> lowering the `bus-frequency` property specified in the DT. The
> `bus-frequency` property ultimately determines all the register
> values, and you should be able to set it to whatever you want by
> refering to the Aspeed documentation.
>
> Nevertheless, the code that determines the correct dividers from the
> frequency is based on the tables in the Aspeed documentation. I don't
> think the equation makes sense when the base_clk_divisor is fixed; I
> mean it will probably just set the other divisor to max or min
> depending on the values chosen. I think if someone really wants to
> program this parameter manually, they probably want to set the other
> parameters manually too.
Thank you for the quick response, Brendan.
Aspeed I2C bus frequency is defined by 3 parameters (base_clk_divisor, clk_high_width, clk_low_width), and I choose base_clk_divisor because it controls all the Aspeed I2C timings (such as setup time and hold time). Once base_clk_divisor is decided (either by the current logic in i2c-aspeed driver or manually set in device tree), clk_high_width and clk_low_width will be calculated by i2c-aspeed driver to meet the specified I2C bus speed.
For example, by setting I2C bus frequency to 100KHz on AST2500 platform, (base_clock_divisor, clk_high_width, clk_low_width) is set to (3, 15, 14) by our driver. But some slave devices (on CMM i2c-8 and Minipack i2c-0) NACK byte transactions with the default timing setting: the issue can be resolved by setting base_clk_divisor to 4, and (clk_high_width, clk_low_width) will be set to (7, 7) by our i2c-aspeed driver to achieve similar I2C bus speed.
Not sure if my answer helps to address your concerns, but kindly let me know if you have further questions/suggestions.
Thanks,
Tao
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Tao Ren @ 2019-06-20 2:28 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <4c8b9ca5e84db7db67ad552d8fdbaa17d11b6432.camel@kernel.crashing.org>
On 6/19/19 4:02 PM, Benjamin Herrenschmidt wrote:
> On Wed, 2019-06-19 at 22:32 +0000, Tao Ren wrote:
>> Thank you for the quick response, Brendan.
>>
>> Aspeed I2C bus frequency is defined by 3 parameters
>> (base_clk_divisor, clk_high_width, clk_low_width), and I choose
>> base_clk_divisor because it controls all the Aspeed I2C timings (such
>> as setup time and hold time). Once base_clk_divisor is decided
>> (either by the current logic in i2c-aspeed driver or manually set in
>> device tree), clk_high_width and clk_low_width will be calculated by
>> i2c-aspeed driver to meet the specified I2C bus speed.
>>
>> For example, by setting I2C bus frequency to 100KHz on AST2500
>> platform, (base_clock_divisor, clk_high_width, clk_low_width) is set
>> to (3, 15, 14) by our driver. But some slave devices (on CMM i2c-8
>> and Minipack i2c-0) NACK byte transactions with the default timing
>> setting: the issue can be resolved by setting base_clk_divisor to 4,
>> and (clk_high_width, clk_low_width) will be set to (7, 7) by our i2c-
>> aspeed driver to achieve similar I2C bus speed.
>>
>> Not sure if my answer helps to address your concerns, but kindly let
>> me know if you have further questions/suggestions.
>
> Did you look at the resulting output on a scope ? I'm curious what
> might be wrong....
>
> CCing Ryan from Aspeed, he might have some idea.
>
> Could it be that with some specific dividers you have more jitter ?
> Still, i2c devices tend to be rather robust vs crappy clocks unless you
> are massively out of bounds, which makes me wonder whether something
> else might be wrong in your setup.
>
> Cheers,
> Ben.
I've reached out to hardware team to see if they can provide more inputs (such as protocol decoder output) but so far I don't have such data. I'm suspecting it's caused by I2C timing mainly because:
1) the intermittent i2c transaction failures always happen to slave devices which are furthest away from ASPEED chip.
2) As the i2c-aspeed driver in my kernel 4.1 tree (derived from ASPEED SDK) works properly, and I copied I2CD04 (Clock and AC Timing Control) register value from kernel 4.1 and applied to the latest upstream driver: the transaction failure is fixed :)
Thank you Ben for looking into the issue and involving more experts (Ryan) for discussion. I have been suffering from the problem for several months and I'm looking forward for proper/right solutions.
Cheers,
Tao
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Benjamin Herrenschmidt @ 2019-06-19 23:02 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <18565fcf-3dc1-b671-f826-e4417e4ad284@fb.com>
On Wed, 2019-06-19 at 22:32 +0000, Tao Ren wrote:
> Thank you for the quick response, Brendan.
>
> Aspeed I2C bus frequency is defined by 3 parameters
> (base_clk_divisor, clk_high_width, clk_low_width), and I choose
> base_clk_divisor because it controls all the Aspeed I2C timings (such
> as setup time and hold time). Once base_clk_divisor is decided
> (either by the current logic in i2c-aspeed driver or manually set in
> device tree), clk_high_width and clk_low_width will be calculated by
> i2c-aspeed driver to meet the specified I2C bus speed.
>
> For example, by setting I2C bus frequency to 100KHz on AST2500
> platform, (base_clock_divisor, clk_high_width, clk_low_width) is set
> to (3, 15, 14) by our driver. But some slave devices (on CMM i2c-8
> and Minipack i2c-0) NACK byte transactions with the default timing
> setting: the issue can be resolved by setting base_clk_divisor to 4,
> and (clk_high_width, clk_low_width) will be set to (7, 7) by our i2c-
> aspeed driver to achieve similar I2C bus speed.
>
> Not sure if my answer helps to address your concerns, but kindly let
> me know if you have further questions/suggestions.
Did you look at the resulting output on a scope ? I'm curious what
might be wrong....
CCing Ryan from Aspeed, he might have some idea.
Could it be that with some specific dividers you have more jitter ?
Still, i2c devices tend to be rather robust vs crappy clocks unless you
are massively out of bounds, which makes me wonder whether something
else might be wrong in your setup.
Cheers,
Ben.
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Tao Ren @ 2019-06-19 22:32 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <CAFd5g45TMtXcuqONdkpN_K+c0O+wUw8wkGzcQfV+sO8p5Krc9w@mail.gmail.com>
On 6/19/19 2:25 PM, Brendan Higgins wrote:
> On Wed, Jun 19, 2019 at 2:00 PM Tao Ren <taoren@fb.com> wrote:
>>
>> Some intermittent I2C transaction failures are observed on Facebook CMM and
>> Minipack (ast2500) BMC platforms, because slave devices (such as CPLD, BIC
>> and etc.) NACK the address byte sometimes. The issue can be resolved by
>> increasing base clock divisor which affects ASPEED I2C Controller's base
>> clock and other AC timing parameters.
>>
>> This patch allows to customize ASPEED I2C Controller's base clock divisor
>> in device tree.
>
> First off, are you sure you actually need this?
>
> You should be able to achieve an effectively equivalent result by just
> lowering the `bus-frequency` property specified in the DT. The
> `bus-frequency` property ultimately determines all the register
> values, and you should be able to set it to whatever you want by
> refering to the Aspeed documentation.
>
> Nevertheless, the code that determines the correct dividers from the
> frequency is based on the tables in the Aspeed documentation. I don't
> think the equation makes sense when the base_clk_divisor is fixed; I
> mean it will probably just set the other divisor to max or min
> depending on the values chosen. I think if someone really wants to
> program this parameter manually, they probably want to set the other
> parameters manually too.
Thank you for the quick response, Brendan.
Aspeed I2C bus frequency is defined by 3 parameters (base_clk_divisor, clk_high_width, clk_low_width), and I choose base_clk_divisor because it controls all the Aspeed I2C timings (such as setup time and hold time). Once base_clk_divisor is decided (either by the current logic in i2c-aspeed driver or manually set in device tree), clk_high_width and clk_low_width will be calculated by i2c-aspeed driver to meet the specified I2C bus speed.
For example, by setting I2C bus frequency to 100KHz on AST2500 platform, (base_clock_divisor, clk_high_width, clk_low_width) is set to (3, 15, 14) by our driver. But some slave devices (on CMM i2c-8 and Minipack i2c-0) NACK byte transactions with the default timing setting: the issue can be resolved by setting base_clk_divisor to 4, and (clk_high_width, clk_low_width) will be set to (7, 7) by our i2c-aspeed driver to achieve similar I2C bus speed.
Not sure if my answer helps to address your concerns, but kindly let me know if you have further questions/suggestions.
Thanks,
Tao
^ permalink raw reply
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Brendan Higgins @ 2019-06-19 21:25 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20190619205009.4176588-1-taoren@fb.com>
On Wed, Jun 19, 2019 at 2:00 PM Tao Ren <taoren@fb.com> wrote:
>
> Some intermittent I2C transaction failures are observed on Facebook CMM and
> Minipack (ast2500) BMC platforms, because slave devices (such as CPLD, BIC
> and etc.) NACK the address byte sometimes. The issue can be resolved by
> increasing base clock divisor which affects ASPEED I2C Controller's base
> clock and other AC timing parameters.
>
> This patch allows to customize ASPEED I2C Controller's base clock divisor
> in device tree.
First off, are you sure you actually need this?
You should be able to achieve an effectively equivalent result by just
lowering the `bus-frequency` property specified in the DT. The
`bus-frequency` property ultimately determines all the register
values, and you should be able to set it to whatever you want by
refering to the Aspeed documentation.
Nevertheless, the code that determines the correct dividers from the
frequency is based on the tables in the Aspeed documentation. I don't
think the equation makes sense when the base_clk_divisor is fixed; I
mean it will probably just set the other divisor to max or min
depending on the values chosen. I think if someone really wants to
program this parameter manually, they probably want to set the other
parameters manually too.
[snip]
^ permalink raw reply
* [PATCH 2/2] dt-bindings: i2c: aspeed: add base-clock-divisor property
From: Tao Ren @ 2019-06-19 20:50 UTC (permalink / raw)
To: linux-aspeed
"base-clock-divisor" allows people to customize ASPEED I2C Controller's
Base Clock, which in turn adjusts all other I2C AC timing settings.
Signed-off-by: Tao Ren <taoren@fb.com>
---
Documentation/devicetree/bindings/i2c/i2c-aspeed.txt | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
index 8fbd8633a387..0c08df847c6f 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
@@ -13,9 +13,11 @@ Required Properties:
- interrupts : interrupt number
Optional Properties:
-- bus-frequency : frequency of the bus clock in Hz defaults to 100 kHz when not
- specified
-- multi-master : states that there is another master active on this bus.
+- bus-frequency : frequency of the bus clock in Hz defaults to 100 kHz
+ when not specified
+- multi-master : states that there is another master active on this bus.
+- base-clock-divisor : the divisor defines the frequency of Base Clock which
+ is divided from APB bus clock. Valid values are 0-15.
Example:
--
2.17.1
^ permalink raw reply related
* [PATCH 1/2] i2c: aspeed: allow to customize base clock divisor
From: Tao Ren @ 2019-06-19 20:50 UTC (permalink / raw)
To: linux-aspeed
Some intermittent I2C transaction failures are observed on Facebook CMM and
Minipack (ast2500) BMC platforms, because slave devices (such as CPLD, BIC
and etc.) NACK the address byte sometimes. The issue can be resolved by
increasing base clock divisor which affects ASPEED I2C Controller's base
clock and other AC timing parameters.
This patch allows to customize ASPEED I2C Controller's base clock divisor
in device tree.
Signed-off-by: Tao Ren <taoren@fb.com>
---
drivers/i2c/busses/i2c-aspeed.c | 48 ++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 6c8b38fd6e64..e4b1c4c71b62 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -145,7 +145,8 @@ struct aspeed_i2c_bus {
spinlock_t lock;
struct completion cmd_complete;
u32 (*get_clk_reg_val)(struct device *dev,
- u32 divisor);
+ u32 divisor,
+ u32 base_clk_div);
unsigned long parent_clk_frequency;
u32 bus_frequency;
/* Transaction state. */
@@ -778,9 +779,10 @@ static const struct i2c_algorithm aspeed_i2c_algo = {
static u32 aspeed_i2c_get_clk_reg_val(struct device *dev,
u32 clk_high_low_mask,
- u32 divisor)
+ u32 divisor,
+ u32 base_clk_divisor)
{
- u32 base_clk_divisor, clk_high_low_max, clk_high, clk_low, tmp;
+ u32 clk_high_low_max, clk_high, clk_low, tmp;
/*
* SCL_high and SCL_low represent a value 1 greater than what is stored
@@ -809,10 +811,12 @@ static u32 aspeed_i2c_get_clk_reg_val(struct device *dev,
* ((1 << base_clk_divisor) * (clk_high + 1 + clk_low + 1))
* The documentation recommends clk_high >= clk_high_max / 2 and
* clk_low >= clk_low_max / 2 - 1 when possible; this last constraint
- * gives us the following solution:
+ * gives us the following solution (unless base_clk_divisor is manually
+ * configured in device tree):
*/
- base_clk_divisor = divisor > clk_high_low_max ?
- ilog2((divisor - 1) / clk_high_low_max) + 1 : 0;
+ if (base_clk_divisor > ASPEED_I2CD_TIME_BASE_DIVISOR_MASK)
+ base_clk_divisor = divisor > clk_high_low_max ?
+ ilog2((divisor - 1) / clk_high_low_max) + 1 : 0;
if (base_clk_divisor > ASPEED_I2CD_TIME_BASE_DIVISOR_MASK) {
base_clk_divisor = ASPEED_I2CD_TIME_BASE_DIVISOR_MASK;
@@ -843,35 +847,49 @@ static u32 aspeed_i2c_get_clk_reg_val(struct device *dev,
& ASPEED_I2CD_TIME_BASE_DIVISOR_MASK);
}
-static u32 aspeed_i2c_24xx_get_clk_reg_val(struct device *dev, u32 divisor)
+static u32 aspeed_i2c_24xx_get_clk_reg_val(struct device *dev,
+ u32 divisor,
+ u32 base_clk_divisor)
{
/*
* clk_high and clk_low are each 3 bits wide, so each can hold a max
* value of 8 giving a clk_high_low_max of 16.
*/
- return aspeed_i2c_get_clk_reg_val(dev, GENMASK(2, 0), divisor);
+ return aspeed_i2c_get_clk_reg_val(dev, GENMASK(2, 0), divisor,
+ base_clk_divisor);
}
-static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev, u32 divisor)
+static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev,
+ u32 divisor,
+ u32 base_clk_divisor)
{
/*
* clk_high and clk_low are each 4 bits wide, so each can hold a max
* value of 16 giving a clk_high_low_max of 32.
*/
- return aspeed_i2c_get_clk_reg_val(dev, GENMASK(3, 0), divisor);
+ return aspeed_i2c_get_clk_reg_val(dev, GENMASK(3, 0), divisor,
+ base_clk_divisor);
}
/* precondition: bus.lock has been acquired. */
-static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus)
+static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
+ struct platform_device *pdev)
{
- u32 divisor, clk_reg_val;
+ int ret;
+ u32 divisor, clk_reg_val, base_clk_divisor;
+
+ ret = of_property_read_u32(pdev->dev.of_node, "base-clock-divisor",
+ &base_clk_divisor);
+ if (ret < 0)
+ base_clk_divisor = (u32)-1;
divisor = DIV_ROUND_UP(bus->parent_clk_frequency, bus->bus_frequency);
clk_reg_val = readl(bus->base + ASPEED_I2C_AC_TIMING_REG1);
clk_reg_val &= (ASPEED_I2CD_TIME_TBUF_MASK |
ASPEED_I2CD_TIME_THDSTA_MASK |
ASPEED_I2CD_TIME_TACST_MASK);
- clk_reg_val |= bus->get_clk_reg_val(bus->dev, divisor);
+ clk_reg_val |= bus->get_clk_reg_val(bus->dev, divisor,
+ base_clk_divisor);
writel(clk_reg_val, bus->base + ASPEED_I2C_AC_TIMING_REG1);
writel(ASPEED_NO_TIMEOUT_CTRL, bus->base + ASPEED_I2C_AC_TIMING_REG2);
@@ -888,7 +906,7 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
/* Disable everything. */
writel(0, bus->base + ASPEED_I2C_FUN_CTRL_REG);
- ret = aspeed_i2c_init_clk(bus);
+ ret = aspeed_i2c_init_clk(bus, pdev);
if (ret < 0)
return ret;
@@ -989,7 +1007,7 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
if (!match)
bus->get_clk_reg_val = aspeed_i2c_24xx_get_clk_reg_val;
else
- bus->get_clk_reg_val = (u32 (*)(struct device *, u32))
+ bus->get_clk_reg_val = (u32 (*)(struct device *, u32, u32))
match->data;
/* Initialize the I2C adapter */
--
2.17.1
^ permalink raw reply related
* [PATCH v3] ARM: configs: Remove useless UEVENT_HELPER_PATH
From: Olof Johansson @ 2019-06-19 14:12 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <CAJKOXPd4LVFGgonbsuxii-5Fu5wWhxU9yotLHw+OXsPcxYw_3g@mail.gmail.com>
On Thu, Jun 13, 2019 at 04:53:53PM +0200, Krzysztof Kozlowski wrote:
> On Tue, 4 Jun 2019 at 20:52, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> > Remove the CONFIG_UEVENT_HELPER_PATH because:
> > 1. It is disabled since commit 1be01d4a5714 ("driver: base: Disable
> > CONFIG_UEVENT_HELPER by default") as its dependency (UEVENT_HELPER) was
> > made default to 'n',
> > 2. It is not recommended (help message: "This should not be used today
> > [...] creates a high system load") and was kept only for ancient
> > userland,
> > 3. Certain userland specifically requests it to be disabled (systemd
> > README: "Legacy hotplug slows down the system and confuses udev").
> >
> > Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> > Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> > For vexpress:
> > Acked-by: Sudeep Holla <sudeep.holla@arm.com>
> >
> > ---
> >
> > Changes since v2:
> > 1. Remove unrelated files.
> > 2. Add Geert's ack.
> >
> > Changes sice v3:
> > 1. Change also mini2440_defconfig.
> > 2. Add more acks.
>
> Hi Arnd and Olof,
>
> Do you want to apply it directly or maybe I can send it along with
> other my defconfig pull request?
Oh, just saw v3, since it didn't thread with v2.
Applied already with the equivalent fixups, so we're good.
-Olof
^ permalink raw reply
* [PATCH v2] ARM: configs: Remove useless UEVENT_HELPER_PATH
From: Olof Johansson @ 2019-06-19 14:09 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <1559636093-26005-1-git-send-email-krzk@kernel.org>
On Tue, Jun 04, 2019 at 10:14:53AM +0200, Krzysztof Kozlowski wrote:
> Remove the CONFIG_UEVENT_HELPER_PATH because:
> 1. It is disabled since commit 1be01d4a5714 ("driver: base: Disable
> CONFIG_UEVENT_HELPER by default") as its dependency (UEVENT_HELPER) was
> made default to 'n',
> 2. It is not recommended (help message: "This should not be used today
> [...] creates a high system load") and was kept only for ancient
> userland,
> 3. Certain userland specifically requests it to be disabled (systemd
> README: "Legacy hotplug slows down the system and confuses udev").
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> ---
>
> Changes since v2:
> 1. Remove unrelated files.
> 2. Add Geert's ack.
So your other patch added mini2440 in a follow-up patch, but this one doesn't?!
Applied with that fixup.
-Olof
^ permalink raw reply
* [PATCH] soc: aspeed: fix probe error handling
From: Arnd Bergmann @ 2019-06-19 12:56 UTC (permalink / raw)
To: linux-aspeed
gcc warns that a mising "flash" phandle node leads to undefined
behavior later:
drivers/soc/aspeed/aspeed-lpc-ctrl.c: In function 'aspeed_lpc_ctrl_probe':
drivers/soc/aspeed/aspeed-lpc-ctrl.c:201:18: error: '*((void *)&resm+8)' may be used uninitialized in this function [-Werror=maybe-uninitialized]
The device cannot work without this node, so just error out here.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/soc/aspeed/aspeed-lpc-ctrl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
index 239520bb207e..81109d22af6a 100644
--- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
+++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
@@ -212,6 +212,7 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev)
node = of_parse_phandle(dev->of_node, "flash", 0);
if (!node) {
dev_dbg(dev, "Didn't find host pnor flash node\n");
+ return -ENXIO;
} else {
rc = of_address_to_resource(node, 1, &resm);
of_node_put(node);
--
2.20.0
^ permalink raw reply related
* [PATCH] ARM: dts: aspeed: Add Facebook Minipack BMC
From: Tao Ren @ 2019-06-19 1:03 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <d201fadc-0b8e-48df-8e50-bccd5d5019c7@www.fastmail.com>
On 6/18/19 5:41 PM, Andrew Jeffery wrote:
>
>
> On Tue, 18 Jun 2019, at 13:54, Tao Ren wrote:
>> Add initial version of device tree for Facebook Minipack ast2500 BMC.
>>
>> Signed-off-by: Tao Ren <taoren@fb.com>
>
> Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Thanks a lot for the quick review, Andrew!
Cheers,
Tao
^ permalink raw reply
* [PATCH] ARM: dts: aspeed: Add Facebook Minipack BMC
From: Andrew Jeffery @ 2019-06-19 0:41 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20190618042421.1227372-1-taoren@fb.com>
On Tue, 18 Jun 2019, at 13:54, Tao Ren wrote:
> Add initial version of device tree for Facebook Minipack ast2500 BMC.
>
> Signed-off-by: Tao Ren <taoren@fb.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> .../boot/dts/aspeed-bmc-facebook-minipack.dts | 429 ++++++++++++++++++
> 2 files changed, 430 insertions(+)
> create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 323fb7f13438..4c94e4c8de1e 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1267,6 +1267,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
> aspeed-bmc-arm-centriq2400-rep.dtb \
> aspeed-bmc-arm-stardragon4800-rep2.dtb \
> aspeed-bmc-facebook-cmm.dtb \
> + aspeed-bmc-facebook-minipack.dtb \
> aspeed-bmc-facebook-tiogapass.dtb \
> aspeed-bmc-facebook-yamp.dtb \
> aspeed-bmc-intel-s2600wf.dtb \
> diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
> b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
> new file mode 100644
> index 000000000000..c05478296446
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
> @@ -0,0 +1,429 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// Copyright (c) 2018 Facebook Inc.
> +/dts-v1/;
> +
> +#include "aspeed-g5.dtsi"
> +
> +/ {
> + model = "Facebook Minipack 100 BMC";
> + compatible = "facebook,minipack-bmc", "aspeed,ast2500";
> +
> + aliases {
> + /*
> + * Override the default serial aliases to avoid breaking
> + * the legacy applications.
> + */
> + serial0 = &uart5;
> + serial1 = &uart1;
> + serial2 = &uart2;
> + serial3 = &uart3;
> + serial4 = &uart4;
> +
> + /*
> + * i2c switch 2-0070, pca9548, 8 child channels assigned
> + * with bus number 16-23.
> + */
> + i2c16 = &imux16;
> + i2c17 = &imux17;
> + i2c18 = &imux18;
> + i2c19 = &imux19;
> + i2c20 = &imux20;
> + i2c21 = &imux21;
> + i2c22 = &imux22;
> + i2c23 = &imux23;
> +
> + /*
> + * i2c switch 8-0070, pca9548, 8 child channels assigned
> + * with bus number 24-31.
> + */
> + i2c24 = &imux24;
> + i2c25 = &imux25;
> + i2c26 = &imux26;
> + i2c27 = &imux27;
> + i2c28 = &imux28;
> + i2c29 = &imux29;
> + i2c30 = &imux30;
> + i2c31 = &imux31;
> +
> + /*
> + * i2c switch 9-0070, pca9548, 8 child channels assigned
> + * with bus number 32-39.
> + */
> + i2c32 = &imux32;
> + i2c33 = &imux33;
> + i2c34 = &imux34;
> + i2c35 = &imux35;
> + i2c36 = &imux36;
> + i2c37 = &imux37;
> + i2c38 = &imux38;
> + i2c39 = &imux39;
> +
> + /*
> + * i2c switch 11-0070, pca9548, 8 child channels assigned
> + * with bus number 40-47.
> + */
> + i2c40 = &imux40;
> + i2c41 = &imux41;
> + i2c42 = &imux42;
> + i2c43 = &imux43;
> + i2c44 = &imux44;
> + i2c45 = &imux45;
> + i2c46 = &imux46;
> + i2c47 = &imux47;
> + };
> +
> + chosen {
> + stdout-path = &uart1;
> + bootargs = "debug console=ttyS1,9600n8 root=/dev/ram rw";
> + };
> +
> + memory at 80000000 {
> + reg = <0x80000000 0x20000000>;
> + };
> +};
> +
> +&wdt1 {
> + status = "okay";
> + aspeed,reset-type = "system";
> +};
> +
> +&wdt2 {
> + status = "okay";
> + aspeed,reset-type = "system";
> +};
> +
> +&fmc {
> + status = "okay";
> + flash at 0 {
> + status = "okay";
> + m25p,fast-read;
> + label = "bmc";
> +#include "facebook-bmc-flash-layout.dtsi"
> + };
> +};
> +
> +&uart1 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_txd1_default
> + &pinctrl_rxd1_default
> + &pinctrl_ncts1_default
> + &pinctrl_ndsr1_default
> + &pinctrl_ndtr1_default
> + &pinctrl_nrts1_default>;
> +};
> +
> +&uart2 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_txd2_default
> + &pinctrl_rxd2_default>;
> +};
> +
> +&uart3 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_txd3_default
> + &pinctrl_rxd3_default>;
> +};
> +
> +&uart4 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_txd4_default
> + &pinctrl_rxd4_default>;
> +};
> +
> +&uart5 {
> + status = "okay";
> +};
> +
> +&mac1 {
> + status = "okay";
> + no-hw-checksum;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
> +};
> +
> +&i2c0 {
> + status = "okay";
> + bus-frequency = <400000>;
> + multi-master;
> +};
> +
> +&i2c1 {
> + status = "okay";
> +};
> +
> +&i2c2 {
> + status = "okay";
> +
> + i2c-switch at 70 {
> + compatible = "nxp,pca9548";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x70>;
> +
> + imux16: i2c at 0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + };
> +
> + imux17: i2c at 1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> + };
> +
> + imux18: i2c at 2 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <2>;
> + };
> +
> + imux19: i2c at 3 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <3>;
> + };
> +
> + imux20: i2c at 4 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <4>;
> + };
> +
> + imux21: i2c at 5 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <5>;
> + };
> +
> + imux22: i2c at 6 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <6>;
> + };
> +
> + imux23: i2c at 7 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <7>;
> + };
> + };
> +};
> +
> +&i2c3 {
> + status = "okay";
> +};
> +
> +&i2c4 {
> + status = "okay";
> + multi-master;
> +};
> +
> +&i2c5 {
> + status = "okay";
> +};
> +
> +&i2c6 {
> + status = "okay";
> +};
> +
> +&i2c7 {
> + status = "okay";
> +};
> +
> +&i2c8 {
> + status = "okay";
> +
> + i2c-switch at 70 {
> + compatible = "nxp,pca9548";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x70>;
> +
> + imux24: i2c at 0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + };
> +
> + imux25: i2c at 1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> + };
> +
> + imux26: i2c at 2 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <2>;
> + };
> +
> + imux27: i2c at 3 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <3>;
> + };
> +
> + imux28: i2c at 4 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <4>;
> + };
> +
> + imux29: i2c at 5 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <5>;
> + };
> +
> + imux30: i2c at 6 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <6>;
> + };
> +
> + imux31: i2c at 7 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <7>;
> + };
> + };
> +};
> +
> +&i2c9 {
> + status = "okay";
> +
> + i2c-switch at 70 {
> + compatible = "nxp,pca9548";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x70>;
> +
> + imux32: i2c at 0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + };
> +
> + imux33: i2c at 1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> + };
> +
> + imux34: i2c at 2 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <2>;
> + };
> +
> + imux35: i2c at 3 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <3>;
> + };
> +
> + imux36: i2c at 4 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <4>;
> + };
> +
> + imux37: i2c at 5 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <5>;
> + };
> +
> + imux38: i2c at 6 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <6>;
> + };
> +
> + imux39: i2c at 7 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <7>;
> + };
> + };
> +};
> +
> +&i2c10 {
> + status = "okay";
> +};
> +
> +&i2c11 {
> + status = "okay";
> +
> + i2c-switch at 70 {
> + compatible = "nxp,pca9548";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x70>;
> +
> + imux40: i2c at 0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + };
> +
> + imux41: i2c at 1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> + };
> +
> + imux42: i2c at 2 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <2>;
> + };
> +
> + imux43: i2c at 3 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <3>;
> + };
> +
> + imux44: i2c at 4 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <4>;
> + };
> +
> + imux45: i2c at 5 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <5>;
> + };
> +
> + imux46: i2c at 6 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <6>;
> + };
> +
> + imux47: i2c at 7 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <7>;
> + };
> + };
> +};
> +
> +&i2c12 {
> + status = "okay";
> +};
> +
> +&i2c13 {
> + status = "okay";
> +};
> +
> +&vhub {
> + status = "okay";
> +};
> --
> 2.17.1
>
>
^ permalink raw reply
* [PATCH] ARM: dts: aspeed: Add Facebook Minipack BMC
From: Tao Ren @ 2019-06-18 4:24 UTC (permalink / raw)
To: linux-aspeed
Add initial version of device tree for Facebook Minipack ast2500 BMC.
Signed-off-by: Tao Ren <taoren@fb.com>
---
arch/arm/boot/dts/Makefile | 1 +
.../boot/dts/aspeed-bmc-facebook-minipack.dts | 429 ++++++++++++++++++
2 files changed, 430 insertions(+)
create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 323fb7f13438..4c94e4c8de1e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1267,6 +1267,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-arm-centriq2400-rep.dtb \
aspeed-bmc-arm-stardragon4800-rep2.dtb \
aspeed-bmc-facebook-cmm.dtb \
+ aspeed-bmc-facebook-minipack.dtb \
aspeed-bmc-facebook-tiogapass.dtb \
aspeed-bmc-facebook-yamp.dtb \
aspeed-bmc-intel-s2600wf.dtb \
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
new file mode 100644
index 000000000000..c05478296446
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+
+/ {
+ model = "Facebook Minipack 100 BMC";
+ compatible = "facebook,minipack-bmc", "aspeed,ast2500";
+
+ aliases {
+ /*
+ * Override the default serial aliases to avoid breaking
+ * the legacy applications.
+ */
+ serial0 = &uart5;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+
+ /*
+ * i2c switch 2-0070, pca9548, 8 child channels assigned
+ * with bus number 16-23.
+ */
+ i2c16 = &imux16;
+ i2c17 = &imux17;
+ i2c18 = &imux18;
+ i2c19 = &imux19;
+ i2c20 = &imux20;
+ i2c21 = &imux21;
+ i2c22 = &imux22;
+ i2c23 = &imux23;
+
+ /*
+ * i2c switch 8-0070, pca9548, 8 child channels assigned
+ * with bus number 24-31.
+ */
+ i2c24 = &imux24;
+ i2c25 = &imux25;
+ i2c26 = &imux26;
+ i2c27 = &imux27;
+ i2c28 = &imux28;
+ i2c29 = &imux29;
+ i2c30 = &imux30;
+ i2c31 = &imux31;
+
+ /*
+ * i2c switch 9-0070, pca9548, 8 child channels assigned
+ * with bus number 32-39.
+ */
+ i2c32 = &imux32;
+ i2c33 = &imux33;
+ i2c34 = &imux34;
+ i2c35 = &imux35;
+ i2c36 = &imux36;
+ i2c37 = &imux37;
+ i2c38 = &imux38;
+ i2c39 = &imux39;
+
+ /*
+ * i2c switch 11-0070, pca9548, 8 child channels assigned
+ * with bus number 40-47.
+ */
+ i2c40 = &imux40;
+ i2c41 = &imux41;
+ i2c42 = &imux42;
+ i2c43 = &imux43;
+ i2c44 = &imux44;
+ i2c45 = &imux45;
+ i2c46 = &imux46;
+ i2c47 = &imux47;
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ bootargs = "debug console=ttyS1,9600n8 root=/dev/ram rw";
+ };
+
+ memory at 80000000 {
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&wdt1 {
+ status = "okay";
+ aspeed,reset-type = "system";
+};
+
+&wdt2 {
+ status = "okay";
+ aspeed,reset-type = "system";
+};
+
+&fmc {
+ status = "okay";
+ flash at 0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+#include "facebook-bmc-flash-layout.dtsi"
+ };
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_txd1_default
+ &pinctrl_rxd1_default
+ &pinctrl_ncts1_default
+ &pinctrl_ndsr1_default
+ &pinctrl_ndtr1_default
+ &pinctrl_nrts1_default>;
+};
+
+&uart2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_txd2_default
+ &pinctrl_rxd2_default>;
+};
+
+&uart3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_txd3_default
+ &pinctrl_rxd3_default>;
+};
+
+&uart4 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_txd4_default
+ &pinctrl_rxd4_default>;
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&mac1 {
+ status = "okay";
+ no-hw-checksum;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&i2c0 {
+ status = "okay";
+ bus-frequency = <400000>;
+ multi-master;
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+
+ i2c-switch at 70 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ imux16: i2c at 0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ imux17: i2c at 1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ imux18: i2c at 2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ imux19: i2c at 3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ imux20: i2c at 4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ imux21: i2c at 5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ imux22: i2c at 6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ imux23: i2c at 7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+ multi-master;
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2c8 {
+ status = "okay";
+
+ i2c-switch at 70 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ imux24: i2c at 0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ imux25: i2c at 1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ imux26: i2c at 2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ imux27: i2c at 3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ imux28: i2c at 4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ imux29: i2c at 5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ imux30: i2c at 6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ imux31: i2c at 7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c9 {
+ status = "okay";
+
+ i2c-switch at 70 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ imux32: i2c at 0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ imux33: i2c at 1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ imux34: i2c at 2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ imux35: i2c at 3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ imux36: i2c at 4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ imux37: i2c at 5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ imux38: i2c at 6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ imux39: i2c at 7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c10 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+
+ i2c-switch at 70 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ imux40: i2c at 0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ imux41: i2c at 1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ imux42: i2c at 2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ imux43: i2c at 3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+
+ imux44: i2c at 4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ imux45: i2c at 5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ imux46: i2c at 6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ imux47: i2c at 7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&i2c12 {
+ status = "okay";
+};
+
+&i2c13 {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+};
--
2.17.1
^ permalink raw reply related
* [PATCH 06/59] drm/prime: Actually remove DRIVER_PRIME everywhere
From: Emil Velikov @ 2019-06-17 17:56 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20190614203615.12639-7-daniel.vetter@ffwll.ch>
On 2019/06/14, Daniel Vetter wrote:
> Split out to make the functional changes stick out more.
>
Since this patch flew-by, as standalone one (intentionally or not) I'd
add, anything vaguely like:
"Core users of DRIVER_PRIME were removed from core with prior patches."
HTH
Emil
^ permalink raw reply
* [PATCH] drm/prime: Actually remove DRIVER_PRIME everywhere
From: Daniel Vetter @ 2019-06-17 15:39 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20190614203615.12639-7-daniel.vetter@ffwll.ch>
Split out to make the functional changes stick out more.
v2: amdgpu gained DRIVER_SYNCOBJ_TIMELINE.
v3: amdgpu lost DRIVER_SYNCOBJ_TIMELINE.
v4: Don't add a space in i915_drv.c (Sam)
Cc: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: amd-gfx at lists.freedesktop.org
Cc: etnaviv at lists.freedesktop.org
Cc: freedreno at lists.freedesktop.org
Cc: intel-gfx at lists.freedesktop.org
Cc: lima at lists.freedesktop.org
Cc: linux-amlogic at lists.infradead.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-arm-msm at vger.kernel.org
Cc: linux-aspeed at lists.ozlabs.org
Cc: linux-renesas-soc at vger.kernel.org
Cc: linux-rockchip at lists.infradead.org
Cc: linux-samsung-soc at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
Cc: linux-tegra at vger.kernel.org
Cc: nouveau at lists.freedesktop.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: spice-devel at lists.freedesktop.org
Cc: virtualization at lists.linux-foundation.org
Cc: VMware Graphics <linux-graphics-maintainer@vmware.com>
Cc: xen-devel at lists.xenproject.org
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
drivers/gpu/drm/arc/arcpgu_drv.c | 3 +--
drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 +-
drivers/gpu/drm/arm/hdlcd_drv.c | 4 +---
drivers/gpu/drm/arm/malidp_drv.c | 3 +--
drivers/gpu/drm/armada/armada_drv.c | 3 +--
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 3 +--
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 4 +---
drivers/gpu/drm/bochs/bochs_drv.c | 3 +--
drivers/gpu/drm/cirrus/cirrus.c | 2 +-
drivers/gpu/drm/etnaviv/etnaviv_drv.c | 4 +---
drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 +-
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 3 +--
drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 3 +--
drivers/gpu/drm/i915/i915_drv.c | 2 +-
drivers/gpu/drm/imx/imx-drm-core.c | 3 +--
drivers/gpu/drm/lima/lima_drv.c | 2 +-
drivers/gpu/drm/mcde/mcde_drv.c | 2 +-
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 3 +--
drivers/gpu/drm/meson/meson_drv.c | 4 +---
drivers/gpu/drm/msm/msm_drv.c | 1 -
drivers/gpu/drm/mxsfb/mxsfb_drv.c | 3 +--
drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +-
drivers/gpu/drm/omapdrm/omap_drv.c | 2 +-
drivers/gpu/drm/panfrost/panfrost_drv.c | 3 +--
drivers/gpu/drm/pl111/pl111_drv.c | 2 +-
drivers/gpu/drm/qxl/qxl_drv.c | 3 +--
drivers/gpu/drm/radeon/radeon_drv.c | 2 +-
drivers/gpu/drm/rcar-du/rcar_du_drv.c | 3 +--
drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 3 +--
drivers/gpu/drm/shmobile/shmob_drm_drv.c | 3 +--
drivers/gpu/drm/sti/sti_drv.c | 3 +--
drivers/gpu/drm/stm/drv.c | 3 +--
drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +-
drivers/gpu/drm/tegra/drm.c | 2 +-
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +--
drivers/gpu/drm/tinydrm/hx8357d.c | 2 +-
drivers/gpu/drm/tinydrm/ili9225.c | 3 +--
drivers/gpu/drm/tinydrm/ili9341.c | 2 +-
drivers/gpu/drm/tinydrm/mi0283qt.c | 3 +--
drivers/gpu/drm/tinydrm/repaper.c | 3 +--
drivers/gpu/drm/tinydrm/st7586.c | 3 +--
drivers/gpu/drm/tinydrm/st7735r.c | 3 +--
drivers/gpu/drm/tve200/tve200_drv.c | 3 +--
drivers/gpu/drm/udl/udl_drv.c | 2 +-
drivers/gpu/drm/v3d/v3d_drv.c | 1 -
drivers/gpu/drm/vboxvideo/vbox_drv.c | 2 +-
drivers/gpu/drm/vc4/vc4_drv.c | 1 -
drivers/gpu/drm/vgem/vgem_drv.c | 3 +--
drivers/gpu/drm/virtio/virtgpu_drv.c | 2 +-
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +-
drivers/gpu/drm/xen/xen_drm_front.c | 3 +--
drivers/gpu/drm/zte/zx_drm_drv.c | 3 +--
include/drm/drm_drv.h | 6 ------
54 files changed, 50 insertions(+), 94 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 0a577a389024..8e1b269351e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1309,7 +1309,7 @@ static struct drm_driver kms_driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_ATOMIC |
DRIVER_GEM |
- DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ,
+ DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ,
.load = amdgpu_driver_load_kms,
.open = amdgpu_driver_open_kms,
.postclose = amdgpu_driver_postclose_kms,
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index af60c6d7a5f4..74240cc1c300 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -135,8 +135,7 @@ static int arcpgu_debugfs_init(struct drm_minor *minor)
#endif
static struct drm_driver arcpgu_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.name = "arcpgu",
.desc = "ARC PGU Controller",
.date = "20160219",
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 86f6542afb40..0c6396dc323f 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -56,7 +56,7 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
static struct drm_driver komeda_kms_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
- DRIVER_PRIME | DRIVER_HAVE_IRQ,
+ DRIVER_HAVE_IRQ,
.lastclose = drm_fb_helper_lastclose,
.irq_handler = komeda_kms_irq_handler,
.gem_free_object_unlocked = drm_gem_cma_free_object,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 8fc0b884c428..b126555895d8 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -229,9 +229,7 @@ static int hdlcd_debugfs_init(struct drm_minor *minor)
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver hdlcd_driver = {
- .driver_features = DRIVER_GEM |
- DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = hdlcd_irq,
.irq_preinstall = hdlcd_irq_preinstall,
.irq_postinstall = hdlcd_irq_postinstall,
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index af1992f06a1d..5dccc7130739 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -568,8 +568,7 @@ static int malidp_debugfs_init(struct drm_minor *minor)
#endif //CONFIG_DEBUG_FS
static struct drm_driver malidp_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
- DRIVER_PRIME,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = malidp_dumb_create,
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index e660c5ca52ae..78c8ad73ae1e 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -43,8 +43,7 @@ static struct drm_driver armada_drm_driver = {
.name = "armada-drm",
.desc = "Armada SoC DRM",
.date = "20120730",
- .driver_features = DRIVER_GEM | DRIVER_MODESET |
- DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.ioctls = armada_ioctls,
.fops = &armada_drm_fops,
};
diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index eeb22eccd1fc..ada2f6aca906 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -194,8 +194,7 @@ static void aspeed_gfx_unload(struct drm_device *drm)
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver aspeed_gfx_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET |
- DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.gem_create_object = drm_cma_gem_create_object_default_funcs,
.dumb_create = drm_gem_cma_dumb_create,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index fb2e7646daeb..274fdf18cde8 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -834,9 +834,7 @@ static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver atmel_hlcdc_dc_driver = {
- .driver_features = DRIVER_GEM |
- DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = atmel_hlcdc_dc_irq_handler,
.irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
.irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 8f3a5bda9d03..78ad6c98861d 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -65,8 +65,7 @@ static const struct file_operations bochs_fops = {
};
static struct drm_driver bochs_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
- DRIVER_PRIME,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &bochs_fops,
.name = "bochs-drm",
.desc = "bochs dispi vga interface (qemu stdvga)",
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
index be4ea370ba31..36a69aec8a4b 100644
--- a/drivers/gpu/drm/cirrus/cirrus.c
+++ b/drivers/gpu/drm/cirrus/cirrus.c
@@ -513,7 +513,7 @@ static void cirrus_mode_config_init(struct cirrus_device *cirrus)
DEFINE_DRM_GEM_SHMEM_FOPS(cirrus_fops);
static struct drm_driver cirrus_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC | DRIVER_PRIME,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 7eb7cf9c3fa8..db3b00031fcf 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -462,9 +462,7 @@ static const struct file_operations fops = {
};
static struct drm_driver etnaviv_drm_driver = {
- .driver_features = DRIVER_GEM |
- DRIVER_PRIME |
- DRIVER_RENDER,
+ .driver_features = DRIVER_GEM | DRIVER_RENDER,
.open = etnaviv_open,
.postclose = etnaviv_postclose,
.gem_free_object_unlocked = etnaviv_gem_free_object,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index ba8932af9b43..e43640fc42d3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -114,7 +114,7 @@ static const struct file_operations exynos_drm_driver_fops = {
};
static struct drm_driver exynos_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
+ .driver_features = DRIVER_MODESET | DRIVER_GEM
| DRIVER_ATOMIC | DRIVER_RENDER,
.open = exynos_drm_open,
.lastclose = drm_fb_helper_lastclose,
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index e81daaaa5965..d18ff729d7f6 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -133,8 +133,7 @@ static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops);
static struct drm_driver fsl_dcu_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET
- | DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.load = fsl_dcu_load,
.unload = fsl_dcu_unload,
.irq_handler = fsl_dcu_drm_irq,
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index 7cb7c042b93f..73f2b53f32cc 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -117,8 +117,7 @@ static int kirin_gem_cma_dumb_create(struct drm_file *file,
}
static struct drm_driver kirin_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &kirin_drm_fops,
.gem_free_object_unlocked = drm_gem_cma_free_object,
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 535b9be4fc58..446cad529a24 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -3194,7 +3194,7 @@ static struct drm_driver driver = {
* deal with them for Intel hardware.
*/
.driver_features =
- DRIVER_GEM | DRIVER_PRIME |
+ DRIVER_GEM |
DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ,
.release = i915_driver_release,
.open = i915_driver_open,
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 3e8bece620df..384db6d86da0 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -147,8 +147,7 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
};
static struct drm_driver imx_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index b29c26cd13b2..beb10bc1a7f3 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -252,7 +252,7 @@ static const struct file_operations lima_drm_driver_fops = {
};
static struct drm_driver lima_drm_driver = {
- .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME | DRIVER_SYNCOBJ,
+ .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
.open = lima_drm_driver_open,
.postclose = lima_drm_driver_postclose,
.ioctls = lima_drm_driver_ioctls,
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index baf63fb6850a..f731d689d52f 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -237,7 +237,7 @@ DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
static struct drm_driver mcde_drm_driver = {
.driver_features =
- DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
+ DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.release = mcde_release,
.lastclose = drm_fb_helper_lastclose,
.ioctls = NULL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 95fdbd0fbcac..1f8b8943b0c6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -321,8 +321,7 @@ static const struct file_operations mtk_drm_fops = {
};
static struct drm_driver mtk_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.gem_free_object_unlocked = mtk_drm_gem_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 2310c96fff46..140363f93575 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -93,9 +93,7 @@ static int meson_dumb_create(struct drm_file *file, struct drm_device *dev,
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver meson_driver = {
- .driver_features = DRIVER_GEM |
- DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
/* IRQ */
.irq_handler = meson_irq,
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 31deb87abfc6..87f92d3906ab 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1016,7 +1016,6 @@ static const struct file_operations fops = {
static struct drm_driver msm_driver = {
.driver_features = DRIVER_GEM |
- DRIVER_PRIME |
DRIVER_RENDER |
DRIVER_ATOMIC |
DRIVER_MODESET,
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 6fafc90da4ec..b5bcaf4036bd 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -313,8 +313,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver mxsfb_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET |
- DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = mxsfb_irq_handler,
.irq_preinstall = mxsfb_irq_preinstall,
.irq_uninstall = mxsfb_irq_preinstall,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 7c2fcaba42d6..8cb174f95448 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1105,7 +1105,7 @@ nouveau_driver_fops = {
static struct drm_driver
driver_stub = {
.driver_features =
- DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER
+ DRIVER_GEM | DRIVER_MODESET | DRIVER_RENDER
#if defined(CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT)
| DRIVER_KMS_LEGACY_CONTEXT
#endif
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 672e0f8ad11c..5929f8688e5a 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -524,7 +524,7 @@ static const struct file_operations omapdriver_fops = {
};
static struct drm_driver omap_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
+ .driver_features = DRIVER_MODESET | DRIVER_GEM |
DRIVER_ATOMIC | DRIVER_RENDER,
.open = dev_open,
.lastclose = drm_fb_helper_lastclose,
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index d11e2281dde6..ed2e29826f62 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -342,8 +342,7 @@ static const struct drm_ioctl_desc panfrost_drm_driver_ioctls[] = {
DEFINE_DRM_GEM_SHMEM_FOPS(panfrost_drm_driver_fops);
static struct drm_driver panfrost_drm_driver = {
- .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_SYNCOBJ,
+ .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
.open = panfrost_open,
.postclose = panfrost_postclose,
.ioctls = panfrost_drm_driver_ioctls,
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index 01f8462aa2db..dd4aaa380250 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -224,7 +224,7 @@ DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
static struct drm_driver pl111_drm_driver = {
.driver_features =
- DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
+ DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.ioctls = NULL,
.fops = &drm_fops,
.name = "pl111",
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index f33e349c4ec5..61e1ce16fc25 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -247,8 +247,7 @@ static struct pci_driver qxl_pci_driver = {
};
static struct drm_driver qxl_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.dumb_create = qxl_mode_dumb_create,
.dumb_map_offset = qxl_mode_dumb_mmap,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index a6cbe11f79c6..3b07aa6e551d 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -539,7 +539,7 @@ radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe,
static struct drm_driver kms_driver = {
.driver_features =
- DRIVER_USE_AGP | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER,
+ DRIVER_USE_AGP | DRIVER_GEM | DRIVER_RENDER,
.load = radeon_driver_load_kms,
.open = radeon_driver_open_kms,
.postclose = radeon_driver_postclose_kms,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 6df37c2a9678..83685250319d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -441,8 +441,7 @@ MODULE_DEVICE_TABLE(of, rcar_du_of_table);
DEFINE_DRM_GEM_CMA_FOPS(rcar_du_fops);
static struct drm_driver rcar_du_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME
- | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 53d2c5bd61dc..59091b6241ec 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -212,8 +212,7 @@ static const struct file_operations rockchip_drm_driver_fops = {
};
static struct drm_driver rockchip_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM |
- DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.lastclose = drm_fb_helper_lastclose,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.gem_free_object_unlocked = rockchip_gem_free_object,
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index cb821adfc321..9047a49ff35e 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -127,8 +127,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
DEFINE_DRM_GEM_CMA_FOPS(shmob_drm_fops);
static struct drm_driver shmob_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET
- | DRIVER_PRIME,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET,
.irq_handler = shmob_drm_irq,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index bb6ae6dd66c9..d9f63c9f287b 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -141,8 +141,7 @@ static void sti_mode_config_init(struct drm_device *dev)
DEFINE_DRM_GEM_CMA_FOPS(sti_driver_fops);
static struct drm_driver sti_driver = {
- .driver_features = DRIVER_MODESET |
- DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 5659572151a8..4026c33ccc39 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -54,8 +54,7 @@ static int stm_gem_cma_dumb_create(struct drm_file *file,
DEFINE_DRM_GEM_CMA_FOPS(drv_driver_fops);
static struct drm_driver drv_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.name = "stm",
.desc = "STMicroelectronics SoC DRM",
.date = "20170330",
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 1a1b52e6f73e..d0fda2bf8224 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -38,7 +38,7 @@ static int drm_sun4i_gem_dumb_create(struct drm_file *file_priv,
DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops);
static struct drm_driver sun4i_drv_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
/* Generic Operations */
.fops = &sun4i_drv_fops,
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 0c5f1e6a0446..87a1443406ab 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1007,7 +1007,7 @@ static int tegra_debugfs_init(struct drm_minor *minor)
#endif
static struct drm_driver tegra_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
+ .driver_features = DRIVER_MODESET | DRIVER_GEM |
DRIVER_ATOMIC | DRIVER_RENDER,
.load = tegra_drm_load,
.unload = tegra_drm_unload,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 3030af9e7b35..92307959435a 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -512,8 +512,7 @@ static int tilcdc_debugfs_init(struct drm_minor *minor)
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver tilcdc_driver = {
- .driver_features = (DRIVER_GEM | DRIVER_MODESET |
- DRIVER_PRIME | DRIVER_ATOMIC),
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = tilcdc_irq,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_print_info = drm_gem_cma_print_info,
diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c
index 5773d0fb6ca1..be197c5c3211 100644
--- a/drivers/gpu/drm/tinydrm/hx8357d.c
+++ b/drivers/gpu/drm/tinydrm/hx8357d.c
@@ -193,7 +193,7 @@ static const struct drm_display_mode yx350hv15_mode = {
DEFINE_DRM_GEM_CMA_FOPS(hx8357d_fops);
static struct drm_driver hx8357d_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &hx8357d_fops,
.release = mipi_dbi_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tinydrm/ili9225.c b/drivers/gpu/drm/tinydrm/ili9225.c
index ea69019f2f33..7a8e1b4a37ee 100644
--- a/drivers/gpu/drm/tinydrm/ili9225.c
+++ b/drivers/gpu/drm/tinydrm/ili9225.c
@@ -350,8 +350,7 @@ static const struct drm_display_mode ili9225_mode = {
DEFINE_DRM_GEM_CMA_FOPS(ili9225_fops);
static struct drm_driver ili9225_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &ili9225_fops,
.release = mipi_dbi_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tinydrm/ili9341.c b/drivers/gpu/drm/tinydrm/ili9341.c
index 4ade9e4b924f..00f28b8e4345 100644
--- a/drivers/gpu/drm/tinydrm/ili9341.c
+++ b/drivers/gpu/drm/tinydrm/ili9341.c
@@ -149,7 +149,7 @@ static const struct drm_display_mode yx240qv29_mode = {
DEFINE_DRM_GEM_CMA_FOPS(ili9341_fops);
static struct drm_driver ili9341_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &ili9341_fops,
.release = mipi_dbi_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index fdefa53455d4..7a14d6b355f2 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -153,8 +153,7 @@ static const struct drm_display_mode mi0283qt_mode = {
DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
static struct drm_driver mi0283qt_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &mi0283qt_fops,
.release = mipi_dbi_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
index 97a874b40394..85acfccefcdb 100644
--- a/drivers/gpu/drm/tinydrm/repaper.c
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -925,8 +925,7 @@ static const u8 repaper_e2271cs021_cs[] = { 0x00, 0x00, 0x00, 0x7f,
DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
static struct drm_driver repaper_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &repaper_fops,
.release = repaper_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
index 9ac626265152..204face7b311 100644
--- a/drivers/gpu/drm/tinydrm/st7586.c
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -296,8 +296,7 @@ static const struct drm_display_mode st7586_mode = {
DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
static struct drm_driver st7586_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &st7586_fops,
.release = mipi_dbi_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tinydrm/st7735r.c b/drivers/gpu/drm/tinydrm/st7735r.c
index ce9109e613e0..b23899788f5b 100644
--- a/drivers/gpu/drm/tinydrm/st7735r.c
+++ b/drivers/gpu/drm/tinydrm/st7735r.c
@@ -123,8 +123,7 @@ static const struct drm_display_mode jd_t18003_t01_mode = {
DEFINE_DRM_GEM_CMA_FOPS(st7735r_fops);
static struct drm_driver st7735r_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &st7735r_fops,
.release = mipi_dbi_release,
DRM_GEM_CMA_VMAP_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
index 6e695fbeb6bc..a1f614e21fcc 100644
--- a/drivers/gpu/drm/tve200/tve200_drv.c
+++ b/drivers/gpu/drm/tve200/tve200_drv.c
@@ -137,8 +137,7 @@ static int tve200_modeset_init(struct drm_device *dev)
DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
static struct drm_driver tve200_drm_driver = {
- .driver_features =
- DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.ioctls = NULL,
.fops = &drm_fops,
.name = "tve200",
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 4a49facb608d..ae53bf75c1d6 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -54,7 +54,7 @@ static void udl_driver_release(struct drm_device *dev)
}
static struct drm_driver driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM,
.release = udl_driver_release,
/* gem hooks */
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index fea597f4db8a..a1604705faee 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -188,7 +188,6 @@ static const struct drm_ioctl_desc v3d_drm_ioctls[] = {
static struct drm_driver v3d_drm_driver = {
.driver_features = (DRIVER_GEM |
DRIVER_RENDER |
- DRIVER_PRIME |
DRIVER_SYNCOBJ),
.open = v3d_open,
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
index 02537ab9cc08..a7fd194c81a9 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
@@ -196,7 +196,7 @@ static const struct file_operations vbox_fops = {
static struct drm_driver driver = {
.driver_features =
- DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
+ DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.lastclose = drm_fb_helper_lastclose,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 0f99ad03614e..ed4fe7ed9e64 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -180,7 +180,6 @@ static struct drm_driver vc4_drm_driver = {
DRIVER_ATOMIC |
DRIVER_GEM |
DRIVER_RENDER |
- DRIVER_PRIME |
DRIVER_SYNCOBJ),
.open = vc4_open,
.postclose = vc4_close,
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 11a8f99ba18c..68c340cfde51 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -427,8 +427,7 @@ static void vgem_release(struct drm_device *dev)
}
static struct drm_driver vgem_driver = {
- .driver_features = DRIVER_GEM | DRIVER_PRIME |
- DRIVER_RENDER,
+ .driver_features = DRIVER_GEM | DRIVER_RENDER,
.release = vgem_release,
.open = vgem_open,
.postclose = vgem_postclose,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index c50868753132..0afdf51fdcfd 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -195,7 +195,7 @@ static const struct file_operations virtio_gpu_driver_fops = {
};
static struct drm_driver driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
.open = virtio_gpu_driver_open,
.postclose = virtio_gpu_driver_postclose,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 4ff11a0077e1..89b8eb047583 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1548,7 +1548,7 @@ static const struct file_operations vmwgfx_driver_fops = {
static struct drm_driver driver = {
.driver_features =
- DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC,
+ DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC,
.load = vmw_driver_load,
.unload = vmw_driver_unload,
.lastclose = vmw_lastclose,
diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index 84aa4d61dc42..aeffec82a5ce 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -485,8 +485,7 @@ static const struct vm_operations_struct xen_drm_drv_vm_ops = {
};
static struct drm_driver xen_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET |
- DRIVER_PRIME | DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.release = xen_drm_drv_release,
.gem_vm_ops = &xen_drm_drv_vm_ops,
.gem_free_object_unlocked = xen_drm_drv_free_object_unlocked,
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index 28e8d6072910..060ad5266bc7 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -38,8 +38,7 @@ static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = {
DEFINE_DRM_GEM_CMA_FOPS(zx_drm_fops);
static struct drm_driver zx_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 5e1ba16d19c6..7bc4795319c4 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -61,12 +61,6 @@ enum drm_driver_feature {
* Driver supports mode setting interfaces (KMS).
*/
DRIVER_MODESET = BIT(1),
- /**
- * @DRIVER_PRIME:
- *
- * Driver implements DRM PRIME buffer sharing.
- */
- DRIVER_PRIME = BIT(2),
/**
* @DRIVER_RENDER:
*
--
2.20.1
^ permalink raw reply related
* [PATCH v2] soc: aspeed: lpc-ctrl: make parameter optional
From: Andrew Jeffery @ 2019-06-17 3:08 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <C4D5C095-A715-4D39-9DEB-1B7734760666@fb.com>
On Sat, 15 Jun 2019, at 07:11, Vijay Khemka wrote:
> Hi Andrew,
> Any update on this patch or do I need any more rework.
No, no more reworks. I've pinged Joel, he'll pick it up.
Andrew
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox