* [PATCH v4 0/3] serial: fsl_lpuart: add DMA support
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
Changed in v4:
- Move dma properties from dtsi to dts.
- Cancle the macro(SERIAL_FSL_LPUART_DMA) .
- Separate the document for clocks which undocumented before into a single patch.
- Change some explanations in document(clocks, clock-names, dmas, dma-names).
- Change "lpuart-tx" and "lpuart-rx" to "tx" and "rx".
Changed in v3:
- Use the streaming DMA API for receive.
- Add the macro(SERIAL_FSL_LPUART_DMA) and dts node propertie for whether using the dma.
- Adjust some coding style.
Changed in v2:
- Add eDMA support for lpuart receive.
- Use dma_mapping_error test dma_map_single.
- Change some names of variable.
- Fix some bugs.
Added in v1:
- Add device tree bindings for lupart eDMA support.
- Add eDMA support for lpuart send.
^ permalink raw reply
* [PATCH v4 1/3] ARM: dts: vf610: lpuart: Add eDMA support
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390363773-24108-1-git-send-email-yao.yuan@freescale.com>
Add lpuart dts node properties for eDMA support, them depend on the eDMA driver.
Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
arch/arm/boot/dts/vf610-twr.dts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 80db14e..4149ed6 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -101,5 +101,8 @@
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
+ dmas = <&edma0 0 4>,
+ <&edma0 0 5>;
+ dma-names = "rx","tx";
status = "okay";
};
--
1.8.4
^ permalink raw reply related
* [PATCH v4 2/3] serial: fsl_lpuart: add DMA support
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390363773-24108-1-git-send-email-yao.yuan@freescale.com>
Add dma support for lpuart. This function depend on DMA driver.
You can turn on it by write both the dmas and dma-name properties in dts node.
Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
.../devicetree/bindings/serial/fsl-lpuart.txt | 19 +-
drivers/tty/serial/fsl_lpuart.c | 430 ++++++++++++++++++++-
2 files changed, 433 insertions(+), 16 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index 6fd1dd1..6e1cbbf 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -5,10 +5,21 @@ Required properties:
- reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt
+Optional properties:
+- dmas: Generic dma devicetree binding as described
+ in Documentation/devicetree/bindings/dma/dma.txt.
+- dma-names: Two dmas have to be defined, "rx" and "tx".
+ An ordered list of channel names affiliated to the above.
+
+Note: Optional properties for DMA support. Write them both or both not.
+
Example:
uart0: serial at 40027000 {
- compatible = "fsl,vf610-lpuart";
- reg = <0x40027000 0x1000>;
- interrupts = <0 61 0x00>;
- };
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x40027000 0x1000>;
+ interrupts = <0 61 0x00>;
+ dmas = <&edma0 0 2>,
+ <&edma0 0 3>;
+ dma-names = "rx","tx";
+ };
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 8978dc9..c5eb897 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -13,14 +13,19 @@
#define SUPPORT_SYSRQ
#endif
-#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
#include <linux/io.h>
#include <linux/irq.h>
-#include <linux/clk.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/console.h>
+#include <linux/of_dma.h>
#include <linux/serial_core.h>
+#include <linux/slab.h>
#include <linux/tty_flip.h>
/* All registers are 8-bit width */
@@ -112,6 +117,10 @@
#define UARTSFIFO_TXOF 0x02
#define UARTSFIFO_RXUF 0x01
+#define DMA_MAXBURST 16
+#define DMA_MAXBURST_MASK (DMA_MAXBURST - 1)
+#define FSL_UART_RX_DMA_BUFFER_SIZE 64
+
#define DRIVER_NAME "fsl-lpuart"
#define DEV_NAME "ttyLP"
#define UART_NR 6
@@ -121,6 +130,24 @@ struct lpuart_port {
struct clk *clk;
unsigned int txfifo_size;
unsigned int rxfifo_size;
+
+ bool lpuart_dma_use;
+ struct dma_chan *dma_tx_chan;
+ struct dma_chan *dma_rx_chan;
+ struct dma_async_tx_descriptor *dma_tx_desc;
+ struct dma_async_tx_descriptor *dma_rx_desc;
+ dma_addr_t dma_tx_buf_bus;
+ dma_addr_t dma_rx_buf_bus;
+ dma_cookie_t dma_tx_cookie;
+ dma_cookie_t dma_rx_cookie;
+ unsigned char *dma_tx_buf_virt;
+ unsigned char *dma_rx_buf_virt;
+ unsigned int dma_tx_bytes;
+ unsigned int dma_rx_bytes;
+ int dma_tx_in_progress;
+ int dma_rx_in_progress;
+ unsigned int dma_rx_timeout;
+ struct timer_list lpuart_timer;
};
static struct of_device_id lpuart_dt_ids[] = {
@@ -131,6 +158,10 @@ static struct of_device_id lpuart_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
+/* Forward declare this for the dma callbacks*/
+static void lpuart_dma_tx_complete(void *arg);
+static void lpuart_dma_rx_complete(void *arg);
+
static void lpuart_stop_tx(struct uart_port *port)
{
unsigned char temp;
@@ -152,6 +183,210 @@ static void lpuart_enable_ms(struct uart_port *port)
{
}
+static void lpuart_copy_rx_to_tty(struct lpuart_port *sport,
+ struct tty_port *tty, int count)
+{
+ int copied;
+
+ sport->port.icount.rx += count;
+
+ if (!tty) {
+ dev_err(sport->port.dev, "No tty port\n");
+ return;
+ }
+
+ dma_sync_single_for_cpu(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+ copied = tty_insert_flip_string(tty,
+ ((unsigned char *)(sport->dma_rx_buf_virt)), count);
+
+ if (copied != count) {
+ WARN_ON(1);
+ dev_err(sport->port.dev, "RxData copy to tty layer failed\n");
+ }
+
+ dma_sync_single_for_device(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE);
+}
+
+static void lpuart_pio_tx(struct lpuart_port *sport)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ while (!uart_circ_empty(xmit) &&
+ readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size) {
+ writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ sport->port.icount.tx++;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&sport->port);
+
+ if (uart_circ_empty(xmit))
+ writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_TDMAS,
+ sport->port.membase + UARTCR5);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static int lpuart_dma_tx(struct lpuart_port *sport, unsigned long count)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ dma_addr_t tx_bus_addr;
+
+ dma_sync_single_for_device(sport->port.dev, sport->dma_tx_buf_bus,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ sport->dma_tx_bytes = count & ~(DMA_MAXBURST_MASK);
+ tx_bus_addr = sport->dma_tx_buf_bus + xmit->tail;
+ sport->dma_tx_desc = dmaengine_prep_slave_single(sport->dma_tx_chan,
+ tx_bus_addr, sport->dma_tx_bytes,
+ DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
+
+ if (!sport->dma_tx_desc) {
+ dev_err(sport->port.dev, "Not able to get desc for tx\n");
+ return -EIO;
+ }
+
+ sport->dma_tx_desc->callback = lpuart_dma_tx_complete;
+ sport->dma_tx_desc->callback_param = sport;
+ sport->dma_tx_in_progress = 1;
+ sport->dma_tx_cookie = dmaengine_submit(sport->dma_tx_desc);
+ dma_async_issue_pending(sport->dma_tx_chan);
+
+ return 0;
+}
+
+static void lpuart_prepare_tx(struct lpuart_port *sport)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ unsigned long count = CIRC_CNT_TO_END(xmit->head,
+ xmit->tail, UART_XMIT_SIZE);
+
+ if (!count)
+ return;
+
+ if (count < DMA_MAXBURST)
+ writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_TDMAS,
+ sport->port.membase + UARTCR5);
+ else {
+ writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_TDMAS,
+ sport->port.membase + UARTCR5);
+ lpuart_dma_tx(sport, count);
+ }
+}
+
+static void lpuart_dma_tx_complete(void *arg)
+{
+ struct lpuart_port *sport = arg;
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ unsigned long flags;
+
+ async_tx_ack(sport->dma_tx_desc);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ xmit->tail = (xmit->tail + sport->dma_tx_bytes) & (UART_XMIT_SIZE - 1);
+ sport->dma_tx_in_progress = 0;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&sport->port);
+
+ lpuart_prepare_tx(sport);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static int lpuart_dma_rx(struct lpuart_port *sport)
+{
+ dma_sync_single_for_device(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE);
+ sport->dma_rx_desc = dmaengine_prep_slave_single(sport->dma_rx_chan,
+ sport->dma_rx_buf_bus, FSL_UART_RX_DMA_BUFFER_SIZE,
+ DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+
+ if (!sport->dma_rx_desc) {
+ dev_err(sport->port.dev, "Not able to get desc for rx\n");
+ return -EIO;
+ }
+
+ sport->dma_rx_desc->callback = lpuart_dma_rx_complete;
+ sport->dma_rx_desc->callback_param = sport;
+ sport->dma_rx_in_progress = 1;
+ sport->dma_rx_cookie = dmaengine_submit(sport->dma_rx_desc);
+ dma_async_issue_pending(sport->dma_rx_chan);
+
+ return 0;
+}
+
+static void lpuart_dma_rx_complete(void *arg)
+{
+ struct lpuart_port *sport = arg;
+ struct tty_port *port = &sport->port.state->port;
+ unsigned long flags;
+
+ async_tx_ack(sport->dma_rx_desc);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ sport->dma_rx_in_progress = 0;
+ lpuart_copy_rx_to_tty(sport, port, FSL_UART_RX_DMA_BUFFER_SIZE);
+ tty_flip_buffer_push(port);
+ lpuart_dma_rx(sport);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static void lpuart_timer_func(unsigned long data)
+{
+ struct lpuart_port *sport = (struct lpuart_port *)data;
+ struct tty_port *port = &sport->port.state->port;
+ struct dma_tx_state state;
+ unsigned long flags;
+ unsigned char temp;
+ int count;
+
+ del_timer(&sport->lpuart_timer);
+ dmaengine_pause(sport->dma_rx_chan);
+ dmaengine_tx_status(sport->dma_rx_chan, sport->dma_rx_cookie, &state);
+ dmaengine_terminate_all(sport->dma_rx_chan);
+ count = FSL_UART_RX_DMA_BUFFER_SIZE - state.residue;
+ async_tx_ack(sport->dma_rx_desc);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ sport->dma_rx_in_progress = 0;
+ lpuart_copy_rx_to_tty(sport, port, count);
+ tty_flip_buffer_push(port);
+ temp = readb(sport->port.membase + UARTCR5);
+ writeb(temp & ~UARTCR5_RDMAS, sport->port.membase + UARTCR5);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static inline void lpuart_prepare_rx(struct lpuart_port *sport)
+{
+ unsigned long flags;
+ unsigned char temp;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ init_timer(&sport->lpuart_timer);
+ sport->lpuart_timer.function = lpuart_timer_func;
+ sport->lpuart_timer.data = (unsigned long)sport;
+ sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout;
+ add_timer(&sport->lpuart_timer);
+
+ lpuart_dma_rx(sport);
+ temp = readb(sport->port.membase + UARTCR5);
+ writeb(temp | UARTCR5_RDMAS, sport->port.membase + UARTCR5);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
{
struct circ_buf *xmit = &sport->port.state->xmit;
@@ -172,14 +407,21 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
static void lpuart_start_tx(struct uart_port *port)
{
- struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct circ_buf *xmit = &sport->port.state->xmit;
unsigned char temp;
temp = readb(port->membase + UARTCR2);
writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
- if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
- lpuart_transmit_buffer(sport);
+ if (sport->lpuart_dma_use) {
+ if (!uart_circ_empty(xmit) && !sport->dma_tx_in_progress)
+ lpuart_prepare_tx(sport);
+ } else {
+ if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
+ lpuart_transmit_buffer(sport);
+ }
}
static irqreturn_t lpuart_txint(int irq, void *dev_id)
@@ -279,12 +521,19 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
sts = readb(sport->port.membase + UARTSR1);
- if (sts & UARTSR1_RDRF)
- lpuart_rxint(irq, dev_id);
-
+ if (sts & UARTSR1_RDRF) {
+ if (sport->lpuart_dma_use)
+ lpuart_prepare_rx(sport);
+ else
+ lpuart_rxint(irq, dev_id);
+ }
if (sts & UARTSR1_TDRE &&
- !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS))
- lpuart_txint(irq, dev_id);
+ !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS)) {
+ if (sport->lpuart_dma_use)
+ lpuart_pio_tx(sport);
+ else
+ lpuart_txint(irq, dev_id);
+ }
return IRQ_HANDLED;
}
@@ -366,13 +615,156 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
sport->port.membase + UARTCFIFO);
- writeb(2, sport->port.membase + UARTTWFIFO);
+ writeb(0, sport->port.membase + UARTTWFIFO);
writeb(1, sport->port.membase + UARTRWFIFO);
/* Restore cr2 */
writeb(cr2_saved, sport->port.membase + UARTCR2);
}
+static int lpuart_dma_tx_request(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *tx_chan;
+ struct dma_slave_config dma_tx_sconfig;
+ dma_addr_t dma_bus;
+ unsigned char *dma_buf;
+ int ret;
+
+ tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
+
+ if (!tx_chan) {
+ dev_err(sport->port.dev, "Dma tx channel request failed!\n");
+ return -ENODEV;
+ }
+
+ dma_bus = dma_map_single(tx_chan->device->dev,
+ sport->port.state->xmit.buf,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+
+ if (dma_mapping_error(tx_chan->device->dev, dma_bus)) {
+ dev_err(sport->port.dev, "dma_map_single tx failed\n");
+ dma_release_channel(tx_chan);
+ return -ENOMEM;
+ }
+
+ dma_buf = sport->port.state->xmit.buf;
+ dma_tx_sconfig.dst_addr = sport->port.mapbase + UARTDR;
+ dma_tx_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_tx_sconfig.dst_maxburst = DMA_MAXBURST;
+ dma_tx_sconfig.direction = DMA_MEM_TO_DEV;
+ ret = dmaengine_slave_config(tx_chan, &dma_tx_sconfig);
+
+ if (ret < 0) {
+ dev_err(sport->port.dev,
+ "Dma slave config failed, err = %d\n", ret);
+ dma_release_channel(tx_chan);
+ return ret;
+ }
+
+ sport->dma_tx_chan = tx_chan;
+ sport->dma_tx_buf_virt = dma_buf;
+ sport->dma_tx_buf_bus = dma_bus;
+ sport->dma_tx_in_progress = 0;
+
+ return 0;
+}
+
+static int lpuart_dma_rx_request(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *rx_chan;
+ struct dma_slave_config dma_rx_sconfig;
+ dma_addr_t dma_bus;
+ unsigned char *dma_buf;
+ int ret;
+
+ rx_chan = dma_request_slave_channel(sport->port.dev, "rx");
+
+ if (!rx_chan) {
+ dev_err(sport->port.dev, "Dma rx channel request failed!\n");
+ return -ENODEV;
+ }
+
+ dma_buf = devm_kzalloc(sport->port.dev,
+ FSL_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL);
+
+ if (!dma_buf) {
+ dev_err(sport->port.dev, "Dma rx alloc failed\n");
+ dma_release_channel(rx_chan);
+ return -ENOMEM;
+ }
+
+ dma_bus = dma_map_single(rx_chan->device->dev, dma_buf,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(rx_chan->device->dev, dma_bus)) {
+ dev_err(sport->port.dev, "dma_map_single rx failed\n");
+ dma_release_channel(rx_chan);
+ return -ENOMEM;
+ }
+
+ dma_rx_sconfig.src_addr = sport->port.mapbase + UARTDR;
+ dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_rx_sconfig.src_maxburst = 1;
+ dma_rx_sconfig.direction = DMA_DEV_TO_MEM;
+ ret = dmaengine_slave_config(rx_chan, &dma_rx_sconfig);
+
+ if (ret < 0) {
+ dev_err(sport->port.dev,
+ "Dma slave config failed, err = %d\n", ret);
+ dma_release_channel(rx_chan);
+ return ret;
+ }
+
+ sport->dma_rx_chan = rx_chan;
+ sport->dma_rx_buf_virt = dma_buf;
+ sport->dma_rx_buf_bus = dma_bus;
+ sport->dma_rx_in_progress = 0;
+
+ sport->dma_rx_timeout = (sport->port.timeout - HZ / 50) *
+ FSL_UART_RX_DMA_BUFFER_SIZE * 3 /
+ sport->rxfifo_size / 2;
+
+ if (sport->dma_rx_timeout < msecs_to_jiffies(20))
+ sport->dma_rx_timeout = msecs_to_jiffies(20);
+
+ return 0;
+}
+
+static void lpuart_dma_tx_free(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *dma_chan;
+
+ dma_unmap_single(sport->port.dev, sport->dma_tx_buf_bus,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ dma_chan = sport->dma_tx_chan;
+ sport->dma_tx_chan = NULL;
+ sport->dma_tx_buf_bus = 0;
+ sport->dma_tx_buf_virt = NULL;
+ dma_release_channel(dma_chan);
+}
+
+static void lpuart_dma_rx_free(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *dma_chan;
+
+ dma_unmap_single(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+ dma_chan = sport->dma_rx_chan;
+ sport->dma_rx_chan = NULL;
+ sport->dma_rx_buf_bus = 0;
+ sport->dma_rx_buf_virt = NULL;
+ dma_release_channel(dma_chan);
+}
+
static int lpuart_startup(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
@@ -380,6 +772,15 @@ static int lpuart_startup(struct uart_port *port)
unsigned long flags;
unsigned char temp;
+ /*whether use dma support by dma request results*/
+ if (lpuart_dma_tx_request(port) || lpuart_dma_rx_request(port)) {
+ sport->lpuart_dma_use = false;
+ } else {
+ sport->lpuart_dma_use = true;
+ temp = readb(port->membase + UARTCR5);
+ writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
+ }
+
ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0,
DRIVER_NAME, sport);
if (ret)
@@ -414,6 +815,11 @@ static void lpuart_shutdown(struct uart_port *port)
spin_unlock_irqrestore(&port->lock, flags);
devm_free_irq(port->dev, port->irq, sport);
+
+ if (sport->lpuart_dma_use) {
+ lpuart_dma_tx_free(port);
+ lpuart_dma_rx_free(port);
+ }
}
static void
--
1.8.4
^ permalink raw reply related
* [PATCH v4 3/3] serial: fsl_lpuart: documented the clock requirement.
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390363773-24108-1-git-send-email-yao.yuan@freescale.com>
It was previously required but not documented.
Add the text to the binding along with the new "dmas" addition.
Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
Documentation/devicetree/bindings/serial/fsl-lpuart.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index 6e1cbbf..9666f97 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -4,6 +4,8 @@ Required properties:
- compatible : Should be "fsl,<soc>-lpuart"
- reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt
+- clocks : phandle + clock specifier pairs, one for each entry in clock-names
+- clock-names : should contain: "ipg" - the uart clock
Optional properties:
- dmas: Generic dma devicetree binding as described
@@ -19,6 +21,8 @@ uart0: serial at 40027000 {
compatible = "fsl,vf610-lpuart";
reg = <0x40027000 0x1000>;
interrupts = <0 61 0x00>;
+ clocks = <&clks VF610_CLK_UART0>;
+ clock-names = "ipg";
dmas = <&edma0 0 2>,
<&edma0 0 3>;
dma-names = "rx","tx";
--
1.8.4
^ permalink raw reply related
* [PATCH v6 0/3] AArch64: KGDB support
From: Vijay Kilari @ 2014-01-22 4:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140121183604.GQ30706@mudshark.cambridge.arm.com>
On Wed, Jan 22, 2014 at 12:06 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jan 21, 2014 at 02:10:14PM +0000, Vijay Kilari wrote:
>> Hi Will,
>
> Hello Vijay,
>
>> On Mon, Jan 20, 2014 at 3:53 PM, Will Deacon <will.deacon@arm.com> wrote:
>> > Well, the warnings are one thing but the 100 miles of backtrace output that
>> > appear on every boot (and I think end in an oops) are probably more
>> > important to fix. Please enable CONFIG_KGDB_TESTS and
>> > CONFIG_KGDB_TESTS_ON_BOOT and take a look.
>> >
>>
>> I could manage to run KGDB boot tests if I run from sysfs after complete boot
>>
>> echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
>>
>> Here the value of PSTATE is 80000145, which means PSTATE.D is unmasked
>> hence it works fine.
>>
>> If I run during boot by enabling CONFIG_KGDB_TESTS_ON_BOOT,
>> the step debug test fail because value of PSTATE is 80000345.
>> If I force PSTATE.D to 0, it works fine
>>
>> In debug_monitors.c file, only PSTATE.SS & MDSCR.KDE/MDE is managed
>> but not PSTATE.D
>>
>> Can you please let me know if where PSTATE.D is managed in arm64?
>
> That's a good point: I think we wait until our first exception before they
> are unmasked. Perhaps we should:
>
> (1) Move local_dbg_{save,restore} from debug-monitors.h into irqflags.h
> (2) Add local_dbg_enable/local_dbg_disable macros
> (3) Add a call to local_dbg_enable in the clear_os_lock function after the
> isb().
>
> Does that work for you?
Yes, only after first exception occurs the PSTATE.D is unmasked.
I have patched (temp) as below and now KGDB boot tests pass
diff --git a/arch/arm64/include/asm/debug-monitors.h
b/arch/arm64/include/asm/debug-monitors.h
index aff3a76..ea2bc46 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -64,6 +111,24 @@ struct task_struct;
#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
+#define local_dbg_enable()
\
+ do {
\
+ asm volatile(
\
+ "msr daifclr, #9 //
arch_local_irq_disable" \
+ :
\
+ :
\
+ : "memory");
\
+ } while (0)
+
+#define local_dbg_disable()
\
+ do {
\
+ asm volatile(
\
+ "msr daifset, #9 //
arch_local_irq_disable" \
+ :
\
+ :
\
+ : "memory");
\
+ } while (0)
+
struct step_hook {
struct list_head node;
int (*fn)(struct pt_regs *regs, unsigned int insn, unsigned long addr);
diff --git a/arch/arm64/kernel/debug-monitors.c
b/arch/arm64/kernel/debug-monitors.c
index f8b90c0..d0e55f7 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -139,6 +142,7 @@ static void clear_os_lock(void *unused)
{
asm volatile("msr oslar_el1, %0" : : "r" (0));
isb();
+ local_dbg_enable();
}
boot test:
[32927.161317] msgmni has been set to 1870
[32927.212747] alg: No test for stdrng (krng)
[32927.213953] Key type asymmetric registered
[32927.214899] Asymmetric key parser 'x509' registered
[32927.220029] Block layer SCSI generic (bsg) driver version 0.4
loaded (major 253)
[32927.225824] io scheduler noop registered
[32927.226764] io scheduler deadline registered
[32927.230714] io scheduler cfq registered (default)
[32927.237895] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[32927.266066] kgdb: Registered I/O driver kgdbts.
[32927.266419] kgdb: Waiting for connection from remote gdb...
[32927.268598] kgdbts:RUN plant and detach test
[32927.270683] kgdbts:RUN sw breakpoint test
[32927.287659] kgdbts:RUN bad memory access test
[32927.290322] kgdbts:RUN singlestep test 1000 iterations
[32927.330342] kgdbts:RUN singlestep [0/1000]
[32931.286356] kgdbts:RUN singlestep [100/1000]
[32935.242536] kgdbts:RUN singlestep [200/1000]
[32939.205392] kgdbts:RUN singlestep [300/1000]
[32943.169522] kgdbts:RUN singlestep [400/1000]
[32947.231868] kgdbts:RUN singlestep [500/1000]
[32951.188008] kgdbts:RUN singlestep [600/1000]
[32955.332243] kgdbts:RUN singlestep [700/1000]
[32959.467109] kgdbts:RUN singlestep [800/1000]
[32963.430888] kgdbts:RUN singlestep [900/1000]
[32967.346992] kgdbts:RUN do_fork for 100 breakpoints
kgdb test using sysfs:
~ # echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
[33231.554237] kgdb: Registered I/O driver kgdbts.
[33231.554677] kgdbts:RUN plant and detach test
[33231.557072] kgdbts:RUN sw breakpoint test
[33231.576980] kgdbts:RUN bad memory access test
[33231.580022] kgdbts:RUN singlestep test 1000 iterations
[33231.627056] kgdbts:RUN singlestep [0/1000]
[33235.954027] kgdbts:RUN singlestep [100/1000]
[33240.429086] kgdbts:RUN singlestep [200/1000]
[33244.687118] kgdbts:RUN singlestep [300/1000]
[33248.945191] kgdbts:RUN singlestep [400/1000]
[33253.203751] kgdbts:RUN singlestep [500/1000]
[33257.462019] kgdbts:RUN singlestep [600/1000]
[33261.817809] kgdbts:RUN singlestep [700/1000]
[33266.081268] kgdbts:RUN singlestep [800/1000]
[33270.339813] kgdbts:RUN singlestep [900/1000]
[33274.712404] kgdbts:RUN do_fork for 1000 breakpoints
~ #
This works for me. Should I patch it or will you send a patch for this?
PS: cc to mailing list missed
>
> Will
^ permalink raw reply related
* [PATCH] pinctrl: Rename Broadcom Capri pinctrl driver
From: Olof Johansson @ 2014-01-22 4:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140122013512.GT31176@beef>
On Tue, Jan 21, 2014 at 5:35 PM, Matt Porter <mporter@linaro.org> wrote:
> On Tue, Jan 21, 2014 at 04:59:35PM -0800, Olof Johansson wrote:
>> Hi,
>>
>>
>> On Tue, Jan 21, 2014 at 2:38 PM, Sherman Yin <syin@broadcom.com> wrote:
>> > To be consistent with other Broadcom drivers, the Broadcom Capri pinctrl
>> > driver and its related CONFIG option are renamed to bcm281xx.
>> >
>> > Devicetree compatible string and binding documentation use
>> > "brcm,bcm11351-pinctrl" to match the machine binding here:
>> > Documentation/devicetree/bindings/arm/bcm/bcm11351.txt
>> >
>> > This driver supports pinctrl on BCM11130, BCM11140, BCM11351, BCM28145
>> > and BCM28155 SoCs.
>> >
>> > Signed-off-by: Sherman Yin <syin@broadcom.com>
>> > Reviewed-by: Matt Porter <mporter@linaro.org>
>> > ---
>> > ...capri-pinctrl.txt => brcm,bcm11351-pinctrl.txt} | 8 +-
>> > arch/arm/boot/dts/bcm11351.dtsi | 2 +-
>> > arch/arm/configs/bcm_defconfig | 2 +-
>> > drivers/pinctrl/Kconfig | 8 +-
>> > drivers/pinctrl/Makefile | 2 +-
>> > .../{pinctrl-capri.c => pinctrl-bcm281xx.c} | 1521 ++++++++++----------
>> > 6 files changed, 775 insertions(+), 768 deletions(-)
>> > rename Documentation/devicetree/bindings/pinctrl/{brcm,capri-pinctrl.txt => brcm,bcm11351-pinctrl.txt} (98%)
>> > rename drivers/pinctrl/{pinctrl-capri.c => pinctrl-bcm281xx.c} (25%)
>> >
>> > diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
>> > similarity index 98%
>> > rename from Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt
>> > rename to Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
>> > index 9e9e9ef..c119deb 100644
>> > --- a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt
>> > +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
>> > @@ -1,4 +1,4 @@
>> > -Broadcom Capri Pin Controller
>> > +Broadcom BCM281xx Pin Controller
>> >
>> > This is a pin controller for the Broadcom BCM281xx SoC family, which includes
>> > BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs.
>> > @@ -7,14 +7,14 @@ BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs.
>> >
>> > Required Properties:
>> >
>> > -- compatible: Must be "brcm,capri-pinctrl".
>> > +- compatible: Must be "brcm,bcm11351-pinctrl"
>>
>> Since the original binding is queued for 3.14 (I believe?), if this
>> rename isn't merged for 3.14 then you will still need to accept the
>> old compatible string (binding). You can document it as deprecated,
>> but the driver needs to still probe with it.
>
> Linus had mentioned that he could take a rename in 3.14-rc for this
> driver which is really what we had in mind here. Since the binding
> doesn't become stable until 3.14 is actually released I was under the
> impression that this is ok without keeping a deprecated compatible
> string. I notice that Tomasz had comments about this type of situation
> in http://www.spinics.net/lists/devicetree/msg18010.html
Yes, if the rename goes in before the binding has been in one stable
release then we can make noncompatible changes. Which is why I said if
this isn't merged for 3.14, etc.
-Olof
^ permalink raw reply
* [PATCH] clk: export __clk_get_hw for re-use in others
From: Greg KH @ 2014-01-22 4:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAEjAshozB4S0ZGqEn41ROfZwGTV+_GZRRTZ8cssi0VdH8Uhr_w@mail.gmail.com>
On Wed, Jan 22, 2014 at 12:05:57PM +0900, SeongJae Park wrote:
> Dear Greg, Mike,
>
> May I ask your answer or other opinion, please?
It's the middle of the merge window, it's not time for new development,
or much time for free-time for me, sorry. Feel free to fix it the best
way you know how.
greg k-h
^ permalink raw reply
* [PATCH] clk: export __clk_get_hw for re-use in others
From: SeongJae Park @ 2014-01-22 5:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140122045937.GB23869@kroah.com>
On Wed, Jan 22, 2014 at 1:59 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Wed, Jan 22, 2014 at 12:05:57PM +0900, SeongJae Park wrote:
>> Dear Greg, Mike,
>>
>> May I ask your answer or other opinion, please?
>
> It's the middle of the merge window, it's not time for new development,
> or much time for free-time for me, sorry. Feel free to fix it the best
> way you know how.
Oops, I've forgot about the merge window. Thank you very much for your
kind answer.
Sorry if I bothered you while you're in busy time.
Because the build problem is not a big deal because it exists only in
-next tree,
I will wait until merge window be closed and then fix it again if it
still exist.
SeongJae Park.
>
> greg k-h
^ permalink raw reply
* mutual exculsion between clk_prepare_enable /clk_disable_unprepare and clk_set_parent
From: Xiaoguang Chen @ 2014-01-22 6:02 UTC (permalink / raw)
To: linux-arm-kernel
Hi, Mike
We met a issue between clk_prepare_enable /clk_disable_unprepare and
clk_set_parent.
As we know, clk preprare/unprare will grab preprare lock, and clk
enable/disable will grab enable lock. clk_set_parent will grab prepare
lock
but there is no lock protection in clk_prepare_enable /clk_disable_unprepare,
for example, in clk_disable_unprepare, it is expended as clk_disable +
clk_unprepare,
and if below condition occurs, there will be problem
thread1 thread 2
call clk_disable_unprepare
1) clk_disable
get enable lock
...............
release enable lock
call clk_set_parent
get prepare lock
set clock's
parent to another parent
release prepare lock
2) clk_unprepare
get prepare lock
unprepare parent clock <<--------------
release prepare lock
In above sequence, After thread 1 call clock disable, thread 2 change
clk's parent to another clock, then in thread1 step2, it will
unprepare clk's new parent, but not old parent, this will cause old
parent is not unprepared, but new parent is unprepared even when it is
not prepared yet.
So How can we use this API: clk_prepare_enable and clk_disable_unprepare ?
Should we add lock to protect this API, if we get a prepare lock
inside this API, like
clk_disable_unprepare ()
{
get_prepare_lock();
clk_disable();
clk_unprepare();
clk_prepare_unlock();
}
is above sequence ok? if so, I can provide a patch for this.
Thanks
Xiaoguang
^ permalink raw reply
* [PATCH v4 2/2] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
From: Vivek Gautam @ 2014-01-22 6:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52DE7D75.4040302@ti.com>
Hi,
On Tue, Jan 21, 2014 at 7:30 PM, Roger Quadros <rogerq@ti.com> wrote:
> Hi Kishon,
>
> On 01/21/2014 12:11 PM, Kishon Vijay Abraham I wrote:
>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>> phy_power_on() and phy_power_off().
>>
>> However using the old USB phy library wont be removed till the PHYs of all
>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v3:
>> * avoided using quirks
>>
>> Documentation/devicetree/bindings/usb/dwc3.txt | 6 ++-
>> drivers/usb/dwc3/core.c | 60 ++++++++++++++++++++++++
>> drivers/usb/dwc3/core.h | 7 +++
>> 3 files changed, 71 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>> index e807635..471366d 100644
>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>> @@ -6,11 +6,13 @@ Required properties:
>> - compatible: must be "snps,dwc3"
>> - reg : Address and length of the register set for the device
>> - interrupts: Interrupts used by the dwc3 controller.
>> +
>> +Optional properties:
>> - usb-phy : array of phandle for the PHY device. The first element
>> in the array is expected to be a handle to the USB2/HS PHY and
>> the second element is expected to be a handle to the USB3/SS PHY
>> -
>> -Optional properties:
>> + - phys: from the *Generic PHY* bindings
>> + - phy-names: from the *Generic PHY* bindings
>> - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>
>> This is usually a subnode to DWC3 glue to which it is connected.
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index e009d4e..036d589 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -82,6 +82,11 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>
>> usb_phy_init(dwc->usb2_phy);
>> usb_phy_init(dwc->usb3_phy);
>> + if (dwc->usb2_generic_phy)
>> + phy_init(dwc->usb2_generic_phy);
>
> What if phy_init() fails? You need to report and fail. Same applies for all PHY apis in this patch.
>
>> + if (dwc->usb3_generic_phy)
>> + phy_init(dwc->usb3_generic_phy);
>> +
>> mdelay(100);
>>
>> /* Clear USB3 PHY reset */
>> @@ -343,6 +348,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>> {
>> usb_phy_shutdown(dwc->usb2_phy);
>> usb_phy_shutdown(dwc->usb3_phy);
>> + if (dwc->usb2_generic_phy)
>> + phy_exit(dwc->usb2_generic_phy);
>> + if (dwc->usb3_generic_phy)
>> + phy_exit(dwc->usb3_generic_phy);
>> +
>> }
>>
>> #define DWC3_ALIGN_MASK (16 - 1)
>> @@ -433,6 +443,32 @@ static int dwc3_probe(struct platform_device *pdev)
>> }
>> }
>>
>> + dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>> + if (IS_ERR(dwc->usb2_generic_phy)) {
>> + ret = PTR_ERR(dwc->usb2_generic_phy);
>> + if (ret == -ENOSYS || ret == -ENODEV) {
>> + dwc->usb2_generic_phy = NULL;
>> + } else if (ret == -EPROBE_DEFER) {
>> + return ret;
>> + } else {
>> + dev_err(dev, "no usb2 phy configured\n");
>> + return ret;
>> + }
>> + }
>> +
>> + dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>> + if (IS_ERR(dwc->usb3_generic_phy)) {
>> + ret = PTR_ERR(dwc->usb3_generic_phy);
>> + if (ret == -ENOSYS || ret == -ENODEV) {
>> + dwc->usb3_generic_phy = NULL;
>> + } else if (ret == -EPROBE_DEFER) {
>> + return ret;
>> + } else {
>> + dev_err(dev, "no usb3 phy configured\n");
>> + return ret;
>> + }
>> + }
>> +
>> dwc->xhci_resources[0].start = res->start;
>> dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
>> DWC3_XHCI_REGS_END;
>> @@ -482,6 +518,11 @@ static int dwc3_probe(struct platform_device *pdev)
>> usb_phy_set_suspend(dwc->usb2_phy, 0);
>> usb_phy_set_suspend(dwc->usb3_phy, 0);
>>
>> + if (dwc->usb2_generic_phy)
>> + phy_power_on(dwc->usb2_generic_phy);
>> + if (dwc->usb3_generic_phy)
>> + phy_power_on(dwc->usb3_generic_phy);
>> +
>
> Is it OK to power on the phy before phy_init()?
Isn't phy_init() being done before phy_power_on() in the
core_soft_reset() in this patch ?
Isn't that what you want here ?
>
> I suggest to move phy_init() from core_soft_reset() to here, just before phy_power_on().
core_soft_reset() is called before phy_power_on() itself from
dwc3_core_init(), right ?
will moving the phy_inti() here make nay difference ?
>
>> ret = dwc3_event_buffers_setup(dwc);
>> if (ret) {
>> dev_err(dwc->dev, "failed to setup event buffers\n");
[...]
snip
--
Best Regards
Vivek Gautam
Samsung R&D Institute, Bangalore
India
^ permalink raw reply
* [PATCH REPOST 1/5] ARM: kvm: replace push and pop with stdmb and ldmia instrs to enable assembler.h inclusion
From: Victor Kamensky @ 2014-01-22 6:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52DE44C4.20503@arm.com>
Russell, Dave, Will, could you please check below
inline, looking for your opinion.
Marc, response is inline.
On 21 January 2014 01:58, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On 21/01/14 01:18, Christoffer Dall wrote:
>> On Fri, Dec 20, 2013 at 08:48:41AM -0800, Victor Kamensky wrote:
>>> Before fix kvm interrupt.S and interrupt_head.S used push and pop assembler
>>> instruction. It causes problem if <asm/assembler.h> file should be include. In
>>> assembler.h "push" is defined as macro so it causes compilation errors like
>>> this:
>>
>> "Before fix kvm..." doesn't read very pleasently, consider using
>> something like "Prior to this commit...."
>>
>> "causes a problem" or "causes problems"
>>
>> change "if <asm/assembler.h> file should be include..." to "if
>> <asm/assembler.h> is included, because assember.h defines 'push' as a
>> macro..."
>>
>>
>>
>>>
>>> arch/arm/kvm/interrupts.S: Assembler messages:
>>> arch/arm/kvm/interrupts.S:51: Error: ARM register expected -- `lsr {r2,r3}'
>>>
>>> Solution implemented by this patch replaces all 'push {...}' with
>>> 'stdmb sp!, {...}' instruction; and all 'pop {...}' with 'ldmia sp!, {...}'.
>>>
>>> Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
>>> ---
>>> arch/arm/kvm/interrupts.S | 38 +++++++++++++++++++-------------------
>>> arch/arm/kvm/interrupts_head.S | 34 +++++++++++++++++-----------------
>>> 2 files changed, 36 insertions(+), 36 deletions(-)
>>>
>>> diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
>>> index ddc1553..df19133 100644
>>> --- a/arch/arm/kvm/interrupts.S
>>> +++ b/arch/arm/kvm/interrupts.S
>>> @@ -47,7 +47,7 @@ __kvm_hyp_code_start:
>>> * instead, ignoring the ipa value.
>>> */
>>> ENTRY(__kvm_tlb_flush_vmid_ipa)
>>> - push {r2, r3}
>>> + stmdb sp!, {r2, r3}
>>>
>>> dsb ishst
>>> add r0, r0, #KVM_VTTBR
>>> @@ -62,7 +62,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa)
>>> mcrr p15, 6, r2, r3, c2 @ Back to VMID #0
>>> isb @ Not necessary if followed by eret
>>>
>>> - pop {r2, r3}
>>> + ldmia sp!, {r2, r3}
>>> bx lr
>>> ENDPROC(__kvm_tlb_flush_vmid_ipa)
>>>
>>> @@ -110,7 +110,7 @@ ENTRY(__kvm_vcpu_run)
>>> #ifdef CONFIG_VFPv3
>>> @ Set FPEXC_EN so the guest doesn't trap floating point instructions
>>> VFPFMRX r2, FPEXC @ VMRS
>>> - push {r2}
>>> + stmdb sp!, {r2}
>>> orr r2, r2, #FPEXC_EN
>>> VFPFMXR FPEXC, r2 @ VMSR
>>> #endif
>>> @@ -175,7 +175,7 @@ __kvm_vcpu_return:
>>>
>>> after_vfp_restore:
>>> @ Restore FPEXC_EN which we clobbered on entry
>>> - pop {r2}
>>> + ldmia sp!, {r2}
>>> VFPFMXR FPEXC, r2
>>> #endif
>>>
>>> @@ -260,7 +260,7 @@ ENTRY(kvm_call_hyp)
>>>
>>> /* Handle undef, svc, pabt, or dabt by crashing with a user notice */
>>> .macro bad_exception exception_code, panic_str
>>> - push {r0-r2}
>>> + stmdb sp!, {r0-r2}
>>> mrrc p15, 6, r0, r1, c2 @ Read VTTBR
>>> lsr r1, r1, #16
>>> ands r1, r1, #0xff
>>> @@ -338,7 +338,7 @@ hyp_hvc:
>>> * Getting here is either becuase of a trap from a guest or from calling
>>> * HVC from the host kernel, which means "switch to Hyp mode".
>>> */
>>> - push {r0, r1, r2}
>>> + stmdb sp!, {r0, r1, r2}
>>>
>>> @ Check syndrome register
>>> mrc p15, 4, r1, c5, c2, 0 @ HSR
>>> @@ -361,11 +361,11 @@ hyp_hvc:
>>> bne guest_trap @ Guest called HVC
>>>
>>> host_switch_to_hyp:
>>> - pop {r0, r1, r2}
>>> + ldmia sp!, {r0, r1, r2}
>>>
>>> - push {lr}
>>> + stmdb sp!, {lr}
>>> mrs lr, SPSR
>>> - push {lr}
>>> + stmdb sp!, {lr}
>>>
>>> mov lr, r0
>>> mov r0, r1
>>> @@ -375,9 +375,9 @@ host_switch_to_hyp:
>>> THUMB( orr lr, #1)
>>> blx lr @ Call the HYP function
>>>
>>> - pop {lr}
>>> + ldmia sp!, {lr}
>>> msr SPSR_csxf, lr
>>> - pop {lr}
>>> + ldmia sp!, {lr}
>>> eret
>>>
>>> guest_trap:
>>> @@ -418,7 +418,7 @@ guest_trap:
>>>
>>> /* Preserve PAR */
>>> mrrc p15, 0, r0, r1, c7 @ PAR
>>> - push {r0, r1}
>>> + stmdb sp!, {r0, r1}
>>>
>>> /* Resolve IPA using the xFAR */
>>> mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR
>>> @@ -431,7 +431,7 @@ guest_trap:
>>> orr r2, r2, r1, lsl #24
>>>
>>> /* Restore PAR */
>>> - pop {r0, r1}
>>> + ldmia sp!, {r0, r1}
>>> mcrr p15, 0, r0, r1, c7 @ PAR
>>>
>>> 3: load_vcpu @ Load VCPU pointer to r0
>>> @@ -440,10 +440,10 @@ guest_trap:
>>> 1: mov r1, #ARM_EXCEPTION_HVC
>>> b __kvm_vcpu_return
>>>
>>> -4: pop {r0, r1} @ Failed translation, return to guest
>>> +4: ldmia sp!, {r0, r1} @ Failed translation, return to guest
>>> mcrr p15, 0, r0, r1, c7 @ PAR
>>> clrex
>>> - pop {r0, r1, r2}
>>> + ldmia sp!, {r0, r1, r2}
>>> eret
>>>
>>> /*
>>> @@ -455,7 +455,7 @@ guest_trap:
>>> #ifdef CONFIG_VFPv3
>>> switch_to_guest_vfp:
>>> load_vcpu @ Load VCPU pointer to r0
>>> - push {r3-r7}
>>> + stmdb sp!, {r3-r7}
>>>
>>> @ NEON/VFP used. Turn on VFP access.
>>> set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11))
>>> @@ -467,15 +467,15 @@ switch_to_guest_vfp:
>>> add r7, r0, #VCPU_VFP_GUEST
>>> restore_vfp_state r7
>>>
>>> - pop {r3-r7}
>>> - pop {r0-r2}
>>> + ldmia sp!, {r3-r7}
>>> + ldmia sp!, {r0-r2}
>>> clrex
>>> eret
>>> #endif
>>>
>>> .align
>>> hyp_irq:
>>> - push {r0, r1, r2}
>>> + stmdb sp!, {r0, r1, r2}
>>> mov r1, #ARM_EXCEPTION_IRQ
>>> load_vcpu @ Load VCPU pointer to r0
>>> b __kvm_vcpu_return
>>> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
>>> index 6f18695..c371db7 100644
>>> --- a/arch/arm/kvm/interrupts_head.S
>>> +++ b/arch/arm/kvm/interrupts_head.S
>>> @@ -63,7 +63,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrs r2, SP_\mode
>>> mrs r3, LR_\mode
>>> mrs r4, SPSR_\mode
>>> - push {r2, r3, r4}
>>> + stmdb sp!, {r2, r3, r4}
>>> .endm
>>>
>>> /*
>>> @@ -73,13 +73,13 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> .macro save_host_regs
>>> /* Hyp regs. Only ELR_hyp (SPSR_hyp already saved) */
>>> mrs r2, ELR_hyp
>>> - push {r2}
>>> + stmdb sp!, {r2}
>>>
>>> /* usr regs */
>>> - push {r4-r12} @ r0-r3 are always clobbered
>>> + stmdb sp!, {r4-r12} @ r0-r3 are always clobbered
>>> mrs r2, SP_usr
>>> mov r3, lr
>>> - push {r2, r3}
>>> + stmdb sp!, {r2, r3}
>>>
>>> push_host_regs_mode svc
>>> push_host_regs_mode abt
>>> @@ -95,11 +95,11 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrs r7, SP_fiq
>>> mrs r8, LR_fiq
>>> mrs r9, SPSR_fiq
>>> - push {r2-r9}
>>> + stmdb sp!, {r2-r9}
>>> .endm
>>>
>>> .macro pop_host_regs_mode mode
>>> - pop {r2, r3, r4}
>>> + ldmia sp!, {r2, r3, r4}
>>> msr SP_\mode, r2
>>> msr LR_\mode, r3
>>> msr SPSR_\mode, r4
>>> @@ -110,7 +110,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> * Clobbers all registers, in all modes, except r0 and r1.
>>> */
>>> .macro restore_host_regs
>>> - pop {r2-r9}
>>> + ldmia sp!, {r2-r9}
>>> msr r8_fiq, r2
>>> msr r9_fiq, r3
>>> msr r10_fiq, r4
>>> @@ -125,12 +125,12 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> pop_host_regs_mode abt
>>> pop_host_regs_mode svc
>>>
>>> - pop {r2, r3}
>>> + ldmia sp!, {r2, r3}
>>> msr SP_usr, r2
>>> mov lr, r3
>>> - pop {r4-r12}
>>> + ldmia sp!, {r4-r12}
>>>
>>> - pop {r2}
>>> + ldmia sp!, {r2}
>>> msr ELR_hyp, r2
>>> .endm
>>>
>>> @@ -218,7 +218,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> add r2, vcpu, #VCPU_USR_REG(3)
>>> stm r2, {r3-r12}
>>> add r2, vcpu, #VCPU_USR_REG(0)
>>> - pop {r3, r4, r5} @ r0, r1, r2
>>> + ldmia sp!, {r3, r4, r5} @ r0, r1, r2
>>> stm r2, {r3, r4, r5}
>>> mrs r2, SP_usr
>>> mov r3, lr
>>> @@ -258,7 +258,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrc p15, 2, r12, c0, c0, 0 @ CSSELR
>>>
>>> .if \store_to_vcpu == 0
>>> - push {r2-r12} @ Push CP15 registers
>>> + stmdb sp!, {r2-r12} @ Push CP15 registers
>>> .else
>>> str r2, [vcpu, #CP15_OFFSET(c1_SCTLR)]
>>> str r3, [vcpu, #CP15_OFFSET(c1_CPACR)]
>>> @@ -286,7 +286,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrc p15, 0, r12, c12, c0, 0 @ VBAR
>>>
>>> .if \store_to_vcpu == 0
>>> - push {r2-r12} @ Push CP15 registers
>>> + stmdb sp!, {r2-r12} @ Push CP15 registers
>>> .else
>>> str r2, [vcpu, #CP15_OFFSET(c13_CID)]
>>> str r3, [vcpu, #CP15_OFFSET(c13_TID_URW)]
>>> @@ -305,7 +305,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrrc p15, 0, r4, r5, c7 @ PAR
>>>
>>> .if \store_to_vcpu == 0
>>> - push {r2,r4-r5}
>>> + stmdb sp!, {r2,r4-r5}
>>> .else
>>> str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
>>> add r12, vcpu, #CP15_OFFSET(c7_PAR)
>>> @@ -322,7 +322,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> */
>>> .macro write_cp15_state read_from_vcpu
>>> .if \read_from_vcpu == 0
>>> - pop {r2,r4-r5}
>>> + ldmia sp!, {r2,r4-r5}
>>> .else
>>> ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
>>> add r12, vcpu, #CP15_OFFSET(c7_PAR)
>>> @@ -333,7 +333,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mcrr p15, 0, r4, r5, c7 @ PAR
>>>
>>> .if \read_from_vcpu == 0
>>> - pop {r2-r12}
>>> + ldmia sp!, {r2-r12}
>>> .else
>>> ldr r2, [vcpu, #CP15_OFFSET(c13_CID)]
>>> ldr r3, [vcpu, #CP15_OFFSET(c13_TID_URW)]
>>> @@ -361,7 +361,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mcr p15, 0, r12, c12, c0, 0 @ VBAR
>>>
>>> .if \read_from_vcpu == 0
>>> - pop {r2-r12}
>>> + ldmia sp!, {r2-r12}
>>> .else
>>> ldr r2, [vcpu, #CP15_OFFSET(c1_SCTLR)]
>>> ldr r3, [vcpu, #CP15_OFFSET(c1_CPACR)]
>>> --
>>> 1.8.1.4
>>>
>>
>> If you fix to address Dave's comments, then the code change otherwise
>> looks good.
>
> How about trying this alternative approach:
>
> It looks like all the users of the push/pop macros are located in
> arch/arm/lib (mostly checksumming code). Can't we move these macros to a
> separate include file and leave the code that uses push/pop (as defined
> by the assembler) alone?
Marc, personally I am OK with such proposal. I was considering something
along these lines as one of the options. It works for me both ways. If
others agree I am happy to recode it as your suggested. I choose
proposed above patch because kvm arm code came after push and pop
defines were introduced in asm/assembler.h and used in other places.
I am OK either way. I agree that use of push and pop as define names
seems a bit unfortunate, but I don't have any historic visibility here
Russell, Dave, Will, do you have any opinion on Marc's proposal to
fix this issue?
Thanks,
Victor
> Thanks,
>
> M.
> --
> Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH V2] ARM: imx: correct usecount of IPG, ARM and MMDC clk on i.mx6sl
From: Sascha Hauer @ 2014-01-22 6:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390301452-10143-1-git-send-email-b20788@freescale.com>
On Tue, Jan 21, 2014 at 06:50:52PM +0800, Anson Huang wrote:
> IPG, ARM and MMDC's clock should be enabled during kernel boot up,
> so we need to maintain their use count, otherwise, they may be
> disabled unexpectedly if their children's clock are turned off,
> which is not allowed.
>
> Signed-off-by: Anson Huang <b20788@freescale.com>
> ---
> arch/arm/mach-imx/clk-imx6sl.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
> index 78f3bd6..047f4ff 100644
> --- a/arch/arm/mach-imx/clk-imx6sl.c
> +++ b/arch/arm/mach-imx/clk-imx6sl.c
> @@ -291,6 +291,22 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> pr_warn("%s: failed to set AHB clock rate %d!\n",
> __func__, ret);
>
> + /*
> + * Make sure those always on clocks are enabled to maintain the correct
> + * usecount and enabling/disabling of parent PLLs.
> + */
> + ret = clk_prepare_enable(clks[IMX6SL_CLK_IPG]);
> + if (ret)
> + pr_warn("%s: failed to enable IPG clock %d\n", __func__, ret);
> +
> + ret = clk_prepare_enable(clks[IMX6SL_CLK_ARM]);
> + if (ret)
> + pr_warn("%s: failed to enable ARM clock %d\n", __func__, ret);
> +
> + ret = clk_prepare_enable(clks[IMX6SL_CLK_MMDC_ROOT]);
> + if (ret)
> + pr_warn("%s: failed to enable MMDC clock %d\n", __func__, ret);
> +
Consider using a clk_init_on array like we have in clk-imx6q.c
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform
From: Sascha Hauer @ 2014-01-22 6:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390236303-22538-11-git-send-email-hdegoede@redhat.com>
Hi Hans,
On Mon, Jan 20, 2014 at 05:45:03PM +0100, Hans de Goede wrote:
> This avoids the ugliness of creating a nested platform device from probe.
>
> Note untested, I've ordered a wandboard to be able to test these changes.
Looks much better now, thanks. I could test this patch aswell, no need
to buy new hardware for this.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH RFC 00/73] tree-wide: clean up some no longer required #include <linux/init.h>
From: Stephen Rothwell @ 2014-01-22 7:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390339396-3479-1-git-send-email-paul.gortmaker@windriver.com>
Hi Paul,
On Tue, 21 Jan 2014 16:22:03 -0500 Paul Gortmaker <paul.gortmaker@windriver.com> wrote:
>
> Where: This work exists as a queue of patches that I apply to
> linux-next; since the changes are fixing some things that currently
> can only be found there. The patch series can be found at:
>
> http://git.kernel.org/cgit/linux/kernel/git/paulg/init.git
> git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git
>
> I've avoided annoying Stephen with another queue of patches for
> linux-next while the development content was in flux, but now that
> the merge window has opened, and new additions are fewer, perhaps he
> wouldn't mind tacking it on the end... Stephen?
OK, I have added this to the end of linux-next today - we will see how we
go. It is called "init".
Thanks for adding your subsystem tree as a participant of linux-next. As
you may know, this is not a judgment of your code. The purpose of
linux-next is for integration testing and to lower the impact of
conflicts between subsystems in the next merge window.
You will need to ensure that the patches/commits in your tree/series have
been:
* submitted under GPL v2 (or later) and include the Contributor's
Signed-off-by,
* posted to the relevant mailing list,
* reviewed by you (or another maintainer of your subsystem tree),
* successfully unit tested, and
* destined for the current or next Linux merge window.
Basically, this should be just what you would send to Linus (or ask him
to fetch). It is allowed to be rebased if you deem it necessary.
--
Cheers,
Stephen Rothwell
sfr at canb.auug.org.au
Legal Stuff:
By participating in linux-next, your subsystem tree contributions are
public and will be included in the linux-next trees. You may be sent
e-mail messages indicating errors or other issues when the
patches/commits from your subsystem tree are merged and tested in
linux-next. These messages may also be cross-posted to the linux-next
mailing list, the linux-kernel mailing list, etc. The linux-next tree
project and IBM (my employer) make no warranties regarding the linux-next
project, the testing procedures, the results, the e-mails, etc. If you
don't agree to these ground rules, let me know and I'll remove your tree
from participation in linux-next.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140122/4f1e8752/attachment.sig>
^ permalink raw reply
* [PATCH V3] ARM: imx: add always-on clock array for i.mx6sl to maintain correct usecount
From: Anson Huang @ 2014-01-22 7:14 UTC (permalink / raw)
To: linux-arm-kernel
IPG, ARM and MMDC's clock should be enabled during kernel boot up,
so we need to maintain their usecount, otherwise, they may be
disabled unexpectedly if their children's clock are turned off, and
caused their parent PLLs also get disabled, which is incorrect.
Signed-off-by: Anson Huang <b20788@freescale.com>
---
arch/arm/mach-imx/clk-imx6sl.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
index 78f3bd6..04e9f1c 100644
--- a/arch/arm/mach-imx/clk-imx6sl.c
+++ b/arch/arm/mach-imx/clk-imx6sl.c
@@ -66,6 +66,10 @@ static struct clk_div_table video_div_table[] = {
static struct clk *clks[IMX6SL_CLK_END];
static struct clk_onecell_data clk_data;
+static const u32 clks_init_on[] __initconst = {
+ IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT,
+};
+
/*
* ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken
* during WAIT mode entry process could cause cache memory
@@ -291,6 +295,13 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
pr_warn("%s: failed to set AHB clock rate %d!\n",
__func__, ret);
+ /*
+ * Make sure those always on clocks are enabled to maintain the correct
+ * usecount and enabling/disabling of parent PLLs.
+ */
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+
if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
--
1.7.9.5
^ permalink raw reply related
* [PATCH V2] ARM: imx: correct usecount of IPG, ARM and MMDC clk on i.mx6sl
From: Anson Huang @ 2014-01-22 7:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140122064740.GB16215@pengutronix.de>
On Wed, Jan 22, 2014 at 07:47:40AM +0100, Sascha Hauer wrote:
> On Tue, Jan 21, 2014 at 06:50:52PM +0800, Anson Huang wrote:
> > IPG, ARM and MMDC's clock should be enabled during kernel boot up,
> > so we need to maintain their use count, otherwise, they may be
> > disabled unexpectedly if their children's clock are turned off,
> > which is not allowed.
> >
> > Signed-off-by: Anson Huang <b20788@freescale.com>
> > ---
> > arch/arm/mach-imx/clk-imx6sl.c | 16 ++++++++++++++++
> > 1 file changed, 16 insertions(+)
> >
> > diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
> > index 78f3bd6..047f4ff 100644
> > --- a/arch/arm/mach-imx/clk-imx6sl.c
> > +++ b/arch/arm/mach-imx/clk-imx6sl.c
> > @@ -291,6 +291,22 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> > pr_warn("%s: failed to set AHB clock rate %d!\n",
> > __func__, ret);
> >
> > + /*
> > + * Make sure those always on clocks are enabled to maintain the correct
> > + * usecount and enabling/disabling of parent PLLs.
> > + */
> > + ret = clk_prepare_enable(clks[IMX6SL_CLK_IPG]);
> > + if (ret)
> > + pr_warn("%s: failed to enable IPG clock %d\n", __func__, ret);
> > +
> > + ret = clk_prepare_enable(clks[IMX6SL_CLK_ARM]);
> > + if (ret)
> > + pr_warn("%s: failed to enable ARM clock %d\n", __func__, ret);
> > +
> > + ret = clk_prepare_enable(clks[IMX6SL_CLK_MMDC_ROOT]);
> > + if (ret)
> > + pr_warn("%s: failed to enable MMDC clock %d\n", __func__, ret);
> > +
>
> Consider using a clk_init_on array like we have in clk-imx6q.c
>
> Sascha
>
Right, that can make code more clean, thanks for the comment, please help review V3 patch.
Anson.
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
>
^ permalink raw reply
* [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform
From: Hans de Goede @ 2014-01-22 7:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140122065151.GC16215@pengutronix.de>
Hi,
On 01/22/2014 07:51 AM, Sascha Hauer wrote:
> Hi Hans,
>
> On Mon, Jan 20, 2014 at 05:45:03PM +0100, Hans de Goede wrote:
>> This avoids the ugliness of creating a nested platform device from probe.
>>
>> Note untested, I've ordered a wandboard to be able to test these changes.
>
> Looks much better now, thanks. I could test this patch aswell, no need
> to buy new hardware for this.
Thanks for the offer, but the wandboard arrived yesterday. Having a bit more
variety in the arm hardware I've to test with is good to have anyways.
Regards,
Hans
^ permalink raw reply
* [PATCH v6 0/3] AArch64: KGDB support
From: Vijay Kilari @ 2014-01-22 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALicx6tx9aLmXpai5SFzZeR6cfu7NKF7WipZWY1nrKGBcA-oGA@mail.gmail.com>
On Wed, Jan 22, 2014 at 10:01 AM, Vijay Kilari <vijay.kilari@gmail.com> wrote:
> On Wed, Jan 22, 2014 at 12:06 AM, Will Deacon <will.deacon@arm.com> wrote:
>> On Tue, Jan 21, 2014 at 02:10:14PM +0000, Vijay Kilari wrote:
>>> Hi Will,
>>
>> Hello Vijay,
>>
>>> On Mon, Jan 20, 2014 at 3:53 PM, Will Deacon <will.deacon@arm.com> wrote:
>>> > Well, the warnings are one thing but the 100 miles of backtrace output that
>>> > appear on every boot (and I think end in an oops) are probably more
>>> > important to fix. Please enable CONFIG_KGDB_TESTS and
>>> > CONFIG_KGDB_TESTS_ON_BOOT and take a look.
>>> >
>>>
>>> I could manage to run KGDB boot tests if I run from sysfs after complete boot
>>>
>>> echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
>>>
>>> Here the value of PSTATE is 80000145, which means PSTATE.D is unmasked
>>> hence it works fine.
>>>
>>> If I run during boot by enabling CONFIG_KGDB_TESTS_ON_BOOT,
>>> the step debug test fail because value of PSTATE is 80000345.
>>> If I force PSTATE.D to 0, it works fine
>>>
>>> In debug_monitors.c file, only PSTATE.SS & MDSCR.KDE/MDE is managed
>>> but not PSTATE.D
>>>
>>> Can you please let me know if where PSTATE.D is managed in arm64?
>>
>> That's a good point: I think we wait until our first exception before they
>> are unmasked. Perhaps we should:
>>
>> (1) Move local_dbg_{save,restore} from debug-monitors.h into irqflags.h
local_dbg_save is setting bit #8 it should be bit #9?
#define local_dbg_save(flags)
\
do {
\
typecheck(unsigned long, flags);
\
asm volatile(
\
"mrs %0, daif //
local_dbg_save\n" \
"msr daifset, #8"
\
: "=r" (flags) : : "memory");
\
} while (0)
>> (2) Add local_dbg_enable/local_dbg_disable macros
>> (3) Add a call to local_dbg_enable in the clear_os_lock function after the
>> isb().
>>
>> Does that work for you?
>
> Yes, only after first exception occurs the PSTATE.D is unmasked.
>
> I have patched (temp) as below and now KGDB boot tests pass
>
> diff --git a/arch/arm64/include/asm/debug-monitors.h
> b/arch/arm64/include/asm/debug-monitors.h
> index aff3a76..ea2bc46 100644
> --- a/arch/arm64/include/asm/debug-monitors.h
> +++ b/arch/arm64/include/asm/debug-monitors.h
> @@ -64,6 +111,24 @@ struct task_struct;
>
> #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
>
> +#define local_dbg_enable()
> \
> + do {
> \
> + asm volatile(
> \
> + "msr daifclr, #9 //
> arch_local_irq_disable" \
> + :
> \
> + :
> \
> + : "memory");
> \
> + } while (0)
> +
> +#define local_dbg_disable()
> \
> + do {
> \
> + asm volatile(
> \
> + "msr daifset, #9 //
> arch_local_irq_disable" \
> + :
> \
> + :
> \
> + : "memory");
> \
> + } while (0)
> +
> struct step_hook {
> struct list_head node;
> int (*fn)(struct pt_regs *regs, unsigned int insn, unsigned long addr);
>
> diff --git a/arch/arm64/kernel/debug-monitors.c
> b/arch/arm64/kernel/debug-monitors.c
> index f8b90c0..d0e55f7 100644
> --- a/arch/arm64/kernel/debug-monitors.c
> +++ b/arch/arm64/kernel/debug-monitors.c
> @@ -139,6 +142,7 @@ static void clear_os_lock(void *unused)
> {
> asm volatile("msr oslar_el1, %0" : : "r" (0));
> isb();
> + local_dbg_enable();
> }
>
>
> boot test:
>
> [32927.161317] msgmni has been set to 1870
> [32927.212747] alg: No test for stdrng (krng)
> [32927.213953] Key type asymmetric registered
> [32927.214899] Asymmetric key parser 'x509' registered
> [32927.220029] Block layer SCSI generic (bsg) driver version 0.4
> loaded (major 253)
> [32927.225824] io scheduler noop registered
> [32927.226764] io scheduler deadline registered
> [32927.230714] io scheduler cfq registered (default)
> [32927.237895] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
> [32927.266066] kgdb: Registered I/O driver kgdbts.
> [32927.266419] kgdb: Waiting for connection from remote gdb...
> [32927.268598] kgdbts:RUN plant and detach test
> [32927.270683] kgdbts:RUN sw breakpoint test
> [32927.287659] kgdbts:RUN bad memory access test
> [32927.290322] kgdbts:RUN singlestep test 1000 iterations
> [32927.330342] kgdbts:RUN singlestep [0/1000]
> [32931.286356] kgdbts:RUN singlestep [100/1000]
> [32935.242536] kgdbts:RUN singlestep [200/1000]
> [32939.205392] kgdbts:RUN singlestep [300/1000]
> [32943.169522] kgdbts:RUN singlestep [400/1000]
> [32947.231868] kgdbts:RUN singlestep [500/1000]
> [32951.188008] kgdbts:RUN singlestep [600/1000]
> [32955.332243] kgdbts:RUN singlestep [700/1000]
> [32959.467109] kgdbts:RUN singlestep [800/1000]
> [32963.430888] kgdbts:RUN singlestep [900/1000]
> [32967.346992] kgdbts:RUN do_fork for 100 breakpoints
>
> kgdb test using sysfs:
>
> ~ # echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
> [33231.554237] kgdb: Registered I/O driver kgdbts.
> [33231.554677] kgdbts:RUN plant and detach test
> [33231.557072] kgdbts:RUN sw breakpoint test
> [33231.576980] kgdbts:RUN bad memory access test
> [33231.580022] kgdbts:RUN singlestep test 1000 iterations
> [33231.627056] kgdbts:RUN singlestep [0/1000]
> [33235.954027] kgdbts:RUN singlestep [100/1000]
> [33240.429086] kgdbts:RUN singlestep [200/1000]
> [33244.687118] kgdbts:RUN singlestep [300/1000]
> [33248.945191] kgdbts:RUN singlestep [400/1000]
> [33253.203751] kgdbts:RUN singlestep [500/1000]
> [33257.462019] kgdbts:RUN singlestep [600/1000]
> [33261.817809] kgdbts:RUN singlestep [700/1000]
> [33266.081268] kgdbts:RUN singlestep [800/1000]
> [33270.339813] kgdbts:RUN singlestep [900/1000]
> [33274.712404] kgdbts:RUN do_fork for 1000 breakpoints
> ~ #
>
> This works for me. Should I patch it or will you send a patch for this?
>
> PS: cc to mailing list missed
>>
>> Will
^ permalink raw reply
* [PATCH v4 2/2] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
From: Roger Quadros @ 2014-01-22 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFp+6iFkgD8x4DozhQdRSx=KLWGwR5pOsCxrVgWbcnCMTFT-sg@mail.gmail.com>
On 01/22/2014 08:04 AM, Vivek Gautam wrote:
> Hi,
>
>
> On Tue, Jan 21, 2014 at 7:30 PM, Roger Quadros <rogerq@ti.com> wrote:
>> Hi Kishon,
>>
>> On 01/21/2014 12:11 PM, Kishon Vijay Abraham I wrote:
>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>> phy_power_on() and phy_power_off().
>>>
>>> However using the old USB phy library wont be removed till the PHYs of all
>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>> Changes from v3:
>>> * avoided using quirks
>>>
>>> Documentation/devicetree/bindings/usb/dwc3.txt | 6 ++-
>>> drivers/usb/dwc3/core.c | 60 ++++++++++++++++++++++++
>>> drivers/usb/dwc3/core.h | 7 +++
>>> 3 files changed, 71 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> index e807635..471366d 100644
>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> @@ -6,11 +6,13 @@ Required properties:
>>> - compatible: must be "snps,dwc3"
>>> - reg : Address and length of the register set for the device
>>> - interrupts: Interrupts used by the dwc3 controller.
>>> +
>>> +Optional properties:
>>> - usb-phy : array of phandle for the PHY device. The first element
>>> in the array is expected to be a handle to the USB2/HS PHY and
>>> the second element is expected to be a handle to the USB3/SS PHY
>>> -
>>> -Optional properties:
>>> + - phys: from the *Generic PHY* bindings
>>> + - phy-names: from the *Generic PHY* bindings
>>> - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>
>>> This is usually a subnode to DWC3 glue to which it is connected.
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index e009d4e..036d589 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -82,6 +82,11 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>
>>> usb_phy_init(dwc->usb2_phy);
>>> usb_phy_init(dwc->usb3_phy);
>>> + if (dwc->usb2_generic_phy)
>>> + phy_init(dwc->usb2_generic_phy);
>>
>> What if phy_init() fails? You need to report and fail. Same applies for all PHY apis in this patch.
>>
>>> + if (dwc->usb3_generic_phy)
>>> + phy_init(dwc->usb3_generic_phy);
>>> +
>>> mdelay(100);
>>>
>>> /* Clear USB3 PHY reset */
>>> @@ -343,6 +348,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>> {
>>> usb_phy_shutdown(dwc->usb2_phy);
>>> usb_phy_shutdown(dwc->usb3_phy);
>>> + if (dwc->usb2_generic_phy)
>>> + phy_exit(dwc->usb2_generic_phy);
>>> + if (dwc->usb3_generic_phy)
>>> + phy_exit(dwc->usb3_generic_phy);
>>> +
>>> }
>>>
>>> #define DWC3_ALIGN_MASK (16 - 1)
>>> @@ -433,6 +443,32 @@ static int dwc3_probe(struct platform_device *pdev)
>>> }
>>> }
>>>
>>> + dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>> + if (IS_ERR(dwc->usb2_generic_phy)) {
>>> + ret = PTR_ERR(dwc->usb2_generic_phy);
>>> + if (ret == -ENOSYS || ret == -ENODEV) {
>>> + dwc->usb2_generic_phy = NULL;
>>> + } else if (ret == -EPROBE_DEFER) {
>>> + return ret;
>>> + } else {
>>> + dev_err(dev, "no usb2 phy configured\n");
>>> + return ret;
>>> + }
>>> + }
>>> +
>>> + dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>>> + if (IS_ERR(dwc->usb3_generic_phy)) {
>>> + ret = PTR_ERR(dwc->usb3_generic_phy);
>>> + if (ret == -ENOSYS || ret == -ENODEV) {
>>> + dwc->usb3_generic_phy = NULL;
>>> + } else if (ret == -EPROBE_DEFER) {
>>> + return ret;
>>> + } else {
>>> + dev_err(dev, "no usb3 phy configured\n");
>>> + return ret;
>>> + }
>>> + }
>>> +
>>> dwc->xhci_resources[0].start = res->start;
>>> dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
>>> DWC3_XHCI_REGS_END;
>>> @@ -482,6 +518,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>> usb_phy_set_suspend(dwc->usb2_phy, 0);
>>> usb_phy_set_suspend(dwc->usb3_phy, 0);
>>>
>>> + if (dwc->usb2_generic_phy)
>>> + phy_power_on(dwc->usb2_generic_phy);
>>> + if (dwc->usb3_generic_phy)
>>> + phy_power_on(dwc->usb3_generic_phy);
>>> +
>>
>> Is it OK to power on the phy before phy_init()?
>
> Isn't phy_init() being done before phy_power_on() in the
> core_soft_reset() in this patch ?
> Isn't that what you want here ?
>
>>
>> I suggest to move phy_init() from core_soft_reset() to here, just before phy_power_on().
>
> core_soft_reset() is called before phy_power_on() itself from
> dwc3_core_init(), right ?
> will moving the phy_inti() here make nay difference ?
You are right. This part is fine then.
cheers,
-roger
^ permalink raw reply
* [PATCH 18/20] clocksource / acpi: Add macro CLOCKSOURCE_ACPI_DECLARE
From: Linus Walleij @ 2014-01-22 8:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389961514-13562-19-git-send-email-hanjun.guo@linaro.org>
On Fri, Jan 17, 2014 at 1:25 PM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
> From: Amit Daniel Kachhap <amit.daniel@samsung.com>
>
> This macro does the same job as CLOCKSOURCE_OF_DECLARE. The device
> name from the ACPI timer table is matched with all the registered
> timer controllers and matching initialisation routine is invoked.
>
> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Actually I have a fat patch renaming CLOCKSOURCE_OF_DECLARE()
to TIMER_OF_DECLARE() and I think this macro, if needed, should
be named TIMER_ACPI_DECLARE().
The reason is that "clocksource" is a Linux-internal name and this
macro pertains to the hardware name in respective system
description type.
> +#ifdef CONFIG_ACPI
> +#define CLOCKSOURCE_ACPI_DECLARE(name, compat, fn) \
> + static const struct acpi_device_id __clksrc_acpi_table_##name \
> + __used __section(__clksrc_acpi_table) \
> + = { .id = compat, \
> + .driver_data = (kernel_ulong_t)fn }
> +#else
> +#define CLOCKSOURCE_ACPI_DECLARE(name, compat, fn)
> +#endif
This hammers down the world to compile one binary for ACPI
and one binary for device tree. Maybe that's fine, I don't know.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCHv3 00/41] OMAPDSS: DT support v3
From: Tomi Valkeinen @ 2014-01-22 8:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52DEE6B0.20106@ti.com>
On 2014-01-21 23:29, Nishanth Menon wrote:
> Tomi,
>
> On 01/21/2014 04:56 AM, Tomi Valkeinen wrote:
>> Hi,
>>
>> Here's version 3 of the DSS DT series.
>>
>> The previous version can be found from:
>>
>> v1: http://permalink.gmane.org/gmane.linux.ports.arm.omap/108249
>> v2: http://permalink.gmane.org/gmane.linux.ports.arm.omap/108866
>>
>> The main changes to v2 are:
>>
>> - DT Binding documentation
>> - OMAP2 DSS support
>> - Split DSI register space
>> - DSS nodes disabled by default
>> - Hack to have generic DT bindings but OMAP specific drivers (for now)
>>
>> This series can also be found from:
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git work/dss-dt-review-3
>>
> http://slexy.org/view/s20JhteOFR is my quick build test report -> few
> checkpatch and build bisect issues would probably need fixing.
Thanks. Shouldn't make trivial changes, and then not run a full
commit-by-commit compile test...
I fixed the issues and pushed the branch again to work/dss-dt-review-3.
The fixes are minor, so the already posted series can be reviewed.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140122/257a5b6c/attachment.sig>
^ permalink raw reply
* [alsa-devel] [PATCH RFC v2 REPOST 3/8] ASoC: davinci-evm: HDMI audio support for TDA998x trough McASP I2S bus
From: Jyri Sarha @ 2014-01-22 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140115165100.3bfab96f@armhf>
On 01/15/2014 05:51 PM, Jean-Francois Moine wrote:
> On Wed, 15 Jan 2014 13:27:21 +0200
> Jyri Sarha <jsarha@ti.com> wrote:
>
>> From driver/gpu/drm/i2c/tda998x_drv.c. The driver configures CTS_N
>> register statically to a value that works only with 4 byte samples.
>> According to my tests it is possible to support 3 and 2 byte samples too
>> by changing the CTS_N register value, but I am not sure if the
>> configuration can be changed on the fly. My data sheet of the nxp chip
>> is very vague about the register definitions, but I suppose the register
>> configures some clock divider on the chip. HDMI supports only upto 24bit
>> audio and the data sheet states that any extraneous least significant
>> bits are ignored.
>
> In the tda998x driver, the CTS_N is automatic (AIP_CNTRL_0_ACR_MAN is
> not set).
>
> Then, in my Cubox (Marvell A510 + tda19988), the 16, 24 and 32 bits
> formats are working well with I2S input at any rate.
>
Could you refer the kernel version (main line?) and the involved ASoC
drivers so could take I a look if there is something I could do differently?
Best regards,
Jyri
^ permalink raw reply
* [PATCH] tty/serial: atmel_serial: remove dev_dbg in atmel_set_termios
From: Nicolas Ferre @ 2014-01-22 9:38 UTC (permalink / raw)
To: linux-arm-kernel
This fixes a driver bug which stopped the whole system (in case
of serial console).
This log message is not useful anyway as this information is
printed elsewhere.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
drivers/tty/serial/atmel_serial.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index a49f10d269b2..3d7206fc532f 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1853,13 +1853,10 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
mode &= ~ATMEL_US_USMODE;
if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
- dev_dbg(port->dev, "Setting UART to RS485\n");
if ((atmel_port->rs485.delay_rts_after_send) > 0)
UART_PUT_TTGR(port,
atmel_port->rs485.delay_rts_after_send);
mode |= ATMEL_US_USMODE_RS485;
- } else {
- dev_dbg(port->dev, "Setting UART to RS232\n");
}
/* set the parity, stop bits and data size */
--
1.8.2.2
^ permalink raw reply related
* [Xen-devel] [PATCH v4] arm: remove !CPU_V6 and !GENERIC_ATOMIC64 build dependencies for XEN
From: Ian Campbell @ 2014-01-22 9:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390311864-19119-1-git-send-email-stefano.stabellini@eu.citrix.com>
On Tue, 2014-01-21 at 13:44 +0000, Stefano Stabellini wrote:
> Remove !GENERIC_ATOMIC64 build dependency:
> - introduce xen_atomic64_xchg
> - use it to implement xchg_xen_ulong
>
> Remove !CPU_V6 build dependency:
> - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
> CONFIG_CPU_V6
> - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply
* [PATCH v2 05/15] watchdog: orion: Make RSTOUT register a separate resource
From: Arnd Bergmann @ 2014-01-22 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140121233321.GR18269@obsidianresearch.com>
On Tuesday 21 January 2014 16:33:21 Jason Gunthorpe wrote:
> On Tue, Jan 21, 2014 at 06:12:31AM -0300, Ezequiel Garcia wrote:
> > In order to support other SoC, it's required to distinguish
> > the 'control' timer register, from the 'rstout' register
> > that enables system reset on watchdog expiration.
>
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > + if (!res)
> > + return -ENODEV;
> ^^^^^^^^^^^^^^^^^^^^^^
>
> This change seems to break compatibility with existing DT files that
> have only a single entry in reg?
>
> Can the value be defaulted some how if missing?
I think this is a direct consequence of the attempt to remove the
header file dependency, since the RSTOUTn_MASK macro is defined
in mach/bridge-regs.h.
I don't see a good way out that would preserve backwards compatibility,
other than hardcoding the physical address in the driver, which seems
just as bad as breaking compatibility. That said, it is always the
same constant (0xf1000000 + 0x20000 + 0x0108) on Dove, Kirkwood and
Orion5x (not on mv78xx0, but that doesn't use the wdt), so hardcoding
a fallback would technically work, but we should print a fat warning at
boot time if we actually fall back to that.
Arnd
^ 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