Linux Serial subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH 4/7] tty: serial: lantiq: Always use readl()/writel()
From: Wu, Songjun @ 2018-06-14  7:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: hua.ma, yixin.zhu, chuanhua.lei, Linux MIPS Mailing List,
	qi-ming.wu, linux-clk, open list:SERIAL DRIVERS, devicetree,
	James Hogan, Jiri Slaby, Linux Kernel Mailing List,
	Greg Kroah-Hartman, Ralf Baechle
In-Reply-To: <CAHp75Vc_EVgfj1MpuA_hKHgy6SiQdU7JQDdtVHfOT1sZ_K-nRQ@mail.gmail.com>



On 6/12/2018 4:13 PM, Andy Shevchenko wrote:
> On Tue, Jun 12, 2018 at 8:40 AM, Songjun Wu <songjun.wu@linux.intel.com> wrote:
>> Previous implementation uses platform-dependent functions
>> ltq_w32()/ltq_r32() to access registers. Those functions are not
>> available for other SoC which uses the same IP.
>> Change to OS provided readl()/writel() and readb()/writeb(), so
>> that different SoCs can use the same driver.
> This patch consists 2 or even 3 ones:
> - whitespace shuffling (indentation fixes, blank lines), I dunno if
> it's needed at all
> - some new registers / bits
> - actual switch to readl() / writel()
>
> Please, split.
It will be split to four patches, coding style, new registers, 
readl()/writel() and asc_update_bits.
>> +#define asc_w32_mask(clear, set, reg)  \
>> +       ({ typeof(reg) reg_ = (reg);    \
>> +       writel((readl(reg_) & ~(clear)) | (set), reg_); })
> This would be better as a static inline helper, and name is completely
> misleading, it doesn't mask the register bits, it _updates_ them.
It will be changed to asc_update_bits.

^ permalink raw reply

* Re: [PATCH 7/7] tty: serial: lantiq: Add CCF support
From: Wu, Songjun @ 2018-06-14  6:38 UTC (permalink / raw)
  To: Rob Herring
  Cc: hua.ma, yixin.zhu, chuanhua.lei, linux-mips, qi-ming.wu,
	linux-clk, linux-serial, devicetree, Jiri Slaby, linux-kernel,
	Greg Kroah-Hartman, Mark Rutland
In-Reply-To: <20180612223953.GA21621@rob-hp-laptop>



On 6/13/2018 6:39 AM, Rob Herring wrote:
> On Tue, Jun 12, 2018 at 01:40:34PM +0800, Songjun Wu wrote:
>> Previous implementation uses platform-dependent API to get the clock.
>> Those functions are not available for other SoC which uses the same IP.
>> The CCF (Common Clock Framework) have an abstraction based APIs
>> for clock.
>> Change to use CCF APIs to get clock and rate.
>> So that different SoCs can use the same driver.
>> Clocks and clock-names are updated in device tree binding.
>>
>> Signed-off-by: Songjun Wu <songjun.wu@linux.intel.com>
>>
>> ---
>>
>>   .../devicetree/bindings/serial/lantiq_asc.txt      |  15 +++
> Please split bindings to separate patch.
Thanks.
It will be split to two separate patches, one for bindings, the other 
for code.
>>   drivers/tty/serial/Kconfig                         |   2 +-
>>   drivers/tty/serial/lantiq.c                        | 101 +++++++++++++++++----
>>   3 files changed, 98 insertions(+), 20 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/serial/lantiq_asc.txt b/Documentation/devicetree/bindings/serial/lantiq_asc.txt
>> index 3acbd309ab9d..608f0c87a4af 100644
>> --- a/Documentation/devicetree/bindings/serial/lantiq_asc.txt
>> +++ b/Documentation/devicetree/bindings/serial/lantiq_asc.txt
>> @@ -6,6 +6,10 @@ Required properties:
>>   - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier
>>     depends on the interrupt-parent interrupt controller.
>>   
>> +Optional properties:
>> +- clocks: Should contain frequency clock and gate clock
>> +- clock-names: Should be "freq" and "asc"
>> +
>>   Example:
>>   
>>   asc1: serial@e100c00 {
>> @@ -14,3 +18,14 @@ asc1: serial@e100c00 {
>>   	interrupt-parent = <&icu0>;
>>   	interrupts = <112 113 114>;
>>   };
>> +
>> +asc0: serial@600000 {
>> +	compatible = "lantiq,asc";
>> +	reg = <0x600000 0x100000>;
> 1MB of address space? That wastes a lot of virtual space on 32-bit
> systems. Just make the size the actual used range.
The size of address space will be updated to the actual used range.
>> +	interrupt-parent = <&gic>;
>> +	interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>,
>> +	<GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>,
>> +	<GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>;
>> +	clocks = <&pll0aclk SSX4_CLK>, <&clkgate1 GATE_URT_CLK>;
>> +	clock-names = "freq", "asc";
>> +};

^ permalink raw reply

* Re: [PATCH 3/4] serial: 8250: Handle case port doesn't have TEMT interrupt using em485.
From: Alan Cox @ 2018-06-13 16:59 UTC (permalink / raw)
  To: Giulio Benetti
  Cc: matwey.kornilov, Greg Kroah-Hartman, Jiri Slaby, Andy Shevchenko,
	Stefan Potyra, Philipp Zabel, Ed Blake, Joshua Scott, Vignesh R,
	Rolf Evers-Fischer, Aaron Sierra, Phil Elwell, Rafael Gago,
	Joel Stanley, Sean Wang, open list:SERIAL DRIVERS, open list
In-Reply-To: <20180606095156.72628-2-giulio.benetti@micronovasrl.com>

> +		} else {
> +			while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) {
> +				lsr = serial_in(p, UART_LSR);
> +				cpu_relax();
> +			}
> +		}

This still needs a timeout in case some kind of hardware flow control line
is asserted and therefore the byte is staying put.

Alan

^ permalink raw reply

* [PATCH v7 6/6] tty/serial: atmel: change the driver to work under at91-usart mfd
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180613163621.23995-1-radu.pirea@microchip.com>

This patch modifies the place where resources and device tree properties
are searched.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
Acked-by: Richard Genoud <richard.genoud@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/tty/serial/Kconfig        |  1 +
 drivers/tty/serial/atmel_serial.c | 42 ++++++++++++++++++++-----------
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 3682fd3e960c..25e55332f8b1 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -119,6 +119,7 @@ config SERIAL_ATMEL
 	depends on ARCH_AT91 || COMPILE_TEST
 	select SERIAL_CORE
 	select SERIAL_MCTRL_GPIO if GPIOLIB
+	select MFD_AT91_USART
 	help
 	  This enables the driver for the on-chip UARTs of the Atmel
 	  AT91 processors.
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index df46a9e88c34..107114d73c5d 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -193,8 +193,7 @@ static struct console atmel_console;
 
 #if defined(CONFIG_OF)
 static const struct of_device_id atmel_serial_dt_ids[] = {
-	{ .compatible = "atmel,at91rm9200-usart" },
-	{ .compatible = "atmel,at91sam9260-usart" },
+	{ .compatible = "atmel,at91rm9200-usart-serial" },
 	{ /* sentinel */ }
 };
 #endif
@@ -915,6 +914,7 @@ static void atmel_tx_dma(struct uart_port *port)
 static int atmel_prepare_tx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	struct device *mfd_dev = port->dev->parent;
 	dma_cap_mask_t		mask;
 	struct dma_slave_config config;
 	int ret, nent;
@@ -922,7 +922,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	atmel_port->chan_tx = dma_request_slave_channel(port->dev, "tx");
+	atmel_port->chan_tx = dma_request_slave_channel(mfd_dev, "tx");
 	if (atmel_port->chan_tx == NULL)
 		goto chan_err;
 	dev_info(port->dev, "using %s for tx DMA transfers\n",
@@ -1093,6 +1093,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
 static int atmel_prepare_rx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	struct device *mfd_dev = port->dev->parent;
 	struct dma_async_tx_descriptor *desc;
 	dma_cap_mask_t		mask;
 	struct dma_slave_config config;
@@ -1104,7 +1105,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_CYCLIC, mask);
 
-	atmel_port->chan_rx = dma_request_slave_channel(port->dev, "rx");
+	atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx");
 	if (atmel_port->chan_rx == NULL)
 		goto chan_err;
 	dev_info(port->dev, "using %s for rx DMA transfers\n",
@@ -2222,8 +2223,8 @@ static const char *atmel_type(struct uart_port *port)
  */
 static void atmel_release_port(struct uart_port *port)
 {
-	struct platform_device *pdev = to_platform_device(port->dev);
-	int size = pdev->resource[0].end - pdev->resource[0].start + 1;
+	struct platform_device *mpdev = to_platform_device(port->dev->parent);
+	int size = resource_size(mpdev->resource);
 
 	release_mem_region(port->mapbase, size);
 
@@ -2238,8 +2239,8 @@ static void atmel_release_port(struct uart_port *port)
  */
 static int atmel_request_port(struct uart_port *port)
 {
-	struct platform_device *pdev = to_platform_device(port->dev);
-	int size = pdev->resource[0].end - pdev->resource[0].start + 1;
+	struct platform_device *mpdev = to_platform_device(port->dev->parent);
+	int size = resource_size(mpdev->resource);
 
 	if (!request_mem_region(port->mapbase, size, "atmel_serial"))
 		return -EBUSY;
@@ -2341,27 +2342,28 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
 {
 	int ret;
 	struct uart_port *port = &atmel_port->uart;
+	struct platform_device *mpdev = to_platform_device(pdev->dev.parent);
 
 	atmel_init_property(atmel_port, pdev);
 	atmel_set_ops(port);
 
-	uart_get_rs485_mode(&pdev->dev, &port->rs485);
+	uart_get_rs485_mode(&mpdev->dev, &port->rs485);
 
 	port->iotype		= UPIO_MEM;
 	port->flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP;
 	port->ops		= &atmel_pops;
 	port->fifosize		= 1;
 	port->dev		= &pdev->dev;
-	port->mapbase	= pdev->resource[0].start;
-	port->irq	= pdev->resource[1].start;
+	port->mapbase		= mpdev->resource[0].start;
+	port->irq		= mpdev->resource[1].start;
 	port->rs485_config	= atmel_config_rs485;
-	port->membase	= NULL;
+	port->membase		= NULL;
 
 	memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
 	/* for console, the clock could already be configured */
 	if (!atmel_port->clk) {
-		atmel_port->clk = clk_get(&pdev->dev, "usart");
+		atmel_port->clk = clk_get(&mpdev->dev, "usart");
 		if (IS_ERR(atmel_port->clk)) {
 			ret = PTR_ERR(atmel_port->clk);
 			atmel_port->clk = NULL;
@@ -2694,13 +2696,22 @@ static void atmel_serial_probe_fifos(struct atmel_uart_port *atmel_port,
 static int atmel_serial_probe(struct platform_device *pdev)
 {
 	struct atmel_uart_port *atmel_port;
-	struct device_node *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.parent->of_node;
 	void *data;
 	int ret = -ENODEV;
 	bool rs485_enabled;
 
 	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
+	/*
+	 * In device tree there is no node with "atmel,at91rm9200-usart-serial"
+	 * as compatible string. This driver is probed by at91-usart mfd driver
+	 * which is just a wrapper over the atmel_serial driver and
+	 * spi-at91-usart driver. All attributes needed by this driver are
+	 * found in of_node of parent.
+	 */
+	pdev->dev.of_node = np;
+
 	ret = of_alias_get_id(np, "serial");
 	if (ret < 0)
 		/* port id not found in platform data nor device-tree aliases:
@@ -2835,6 +2846,7 @@ static int atmel_serial_remove(struct platform_device *pdev)
 
 	clk_put(atmel_port->clk);
 	atmel_port->clk = NULL;
+	pdev->dev.of_node = NULL;
 
 	return ret;
 }
@@ -2845,7 +2857,7 @@ static struct platform_driver atmel_serial_driver = {
 	.suspend	= atmel_serial_suspend,
 	.resume		= atmel_serial_resume,
 	.driver		= {
-		.name			= "atmel_usart",
+		.name			= "atmel_usart_serial",
 		.of_match_table		= of_match_ptr(atmel_serial_dt_ids),
 	},
 };
-- 
2.17.1

^ permalink raw reply related

* [PATCH v7 5/6] spi: at91-usart: add driver for at91-usart as spi
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180613163621.23995-1-radu.pirea@microchip.com>

This is the driver for at91-usart in spi mode. The USART IP can be configured
to work in many modes and one of them is SPI.

The driver was tested on sama5d3-xplained and sama5d4-xplained boards with
enc28j60 ethernet controller as slave.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/spi/Kconfig          |   9 +
 drivers/spi/Makefile         |   1 +
 drivers/spi/spi-at91-usart.c | 434 +++++++++++++++++++++++++++++++++++
 3 files changed, 444 insertions(+)
 create mode 100644 drivers/spi/spi-at91-usart.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 6fb0347a24f2..1a002a32d7aa 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -77,6 +77,15 @@ config SPI_ATMEL
 	  This selects a driver for the Atmel SPI Controller, present on
 	  many AT91 (ARM) chips.
 
+config SPI_AT91_USART
+	tristate "Atmel USART Controller SPI driver"
+	depends on HAS_DMA
+	depends on (ARCH_AT91 || COMPILE_TEST)
+	select MFD_AT91_USART
+	help
+	  This selects a driver for the AT91 USART Controller as SPI Master,
+	  present on AT91 and SAMA5 SoC series.
+
 config SPI_AU1550
 	tristate "Au1550/Au1200/Au1300 SPI Controller"
 	depends on MIPS_ALCHEMY
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 34c5f2832ddf..fb6cb42f4eaa 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST)		+= spi-loopback-test.o
 obj-$(CONFIG_SPI_ALTERA)		+= spi-altera.o
 obj-$(CONFIG_SPI_ARMADA_3700)		+= spi-armada-3700.o
 obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o
+obj-$(CONFIG_SPI_AT91_USART)		+= spi-at91-usart.o
 obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
 obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
 obj-$(CONFIG_SPI_AXI_SPI_ENGINE)	+= spi-axi-spi-engine.o
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c
new file mode 100644
index 000000000000..ae889aa6bda3
--- /dev/null
+++ b/drivers/spi/spi-at91-usart.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for AT91 USART Controllers as SPI
+ *
+ * Copyright (C) 2018 Microchip Technology Inc.
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+
+#define US_CR			0x00
+#define US_MR			0x04
+#define US_IER			0x08
+#define US_IDR			0x0C
+#define US_CSR			0x14
+#define US_RHR			0x18
+#define US_THR			0x1C
+#define US_BRGR			0x20
+#define US_VERSION		0xFC
+
+#define US_CR_RSTRX		BIT(2)
+#define US_CR_RSTTX		BIT(3)
+#define US_CR_RXEN		BIT(4)
+#define US_CR_RXDIS		BIT(5)
+#define US_CR_TXEN		BIT(6)
+#define US_CR_TXDIS		BIT(7)
+
+#define US_MR_SPI_MASTER	0x0E
+#define US_MR_CHRL		GENMASK(7, 6)
+#define US_MR_CPHA		BIT(8)
+#define US_MR_CPOL		BIT(16)
+#define US_MR_CLKO		BIT(18)
+#define US_MR_WRDBT		BIT(20)
+#define US_MR_LOOP		BIT(15)
+
+#define US_IR_RXRDY		BIT(0)
+#define US_IR_TXRDY		BIT(1)
+#define US_IR_OVRE		BIT(5)
+
+#define US_BRGR_SIZE		BIT(16)
+
+#define US_MIN_CLK_DIV		0x06
+#define US_MAX_CLK_DIV		BIT(16)
+
+#define US_RESET		(US_CR_RSTRX | US_CR_RSTTX)
+#define US_DISABLE		(US_CR_RXDIS | US_CR_TXDIS)
+#define US_ENABLE		(US_CR_RXEN | US_CR_TXEN)
+#define US_OVRE_RXRDY_IRQS	(US_IR_OVRE | US_IR_RXRDY)
+
+#define US_INIT \
+	(US_MR_SPI_MASTER | US_MR_CHRL | US_MR_CLKO | US_MR_WRDBT)
+
+/* Register access macros */
+#define at91_usart_spi_readl(port, reg) \
+	readl_relaxed((port)->regs + US_##reg)
+#define at91_usart_spi_writel(port, reg, value) \
+	writel_relaxed((value), (port)->regs + US_##reg)
+
+#define at91_usart_spi_readb(port, reg) \
+	readb_relaxed((port)->regs + US_##reg)
+#define at91_usart_spi_writeb(port, reg, value) \
+	writeb_relaxed((value), (port)->regs + US_##reg)
+
+struct at91_usart_spi {
+	struct spi_transfer	*current_transfer;
+	void __iomem		*regs;
+	struct device		*dev;
+	struct clk		*clk;
+
+	/*used in interrupt to protect data reading*/
+	spinlock_t		lock;
+
+	int			irq;
+	unsigned int		current_tx_remaining_bytes;
+	unsigned int		current_rx_remaining_bytes;
+	int			done_status;
+
+	u32			spi_clk;
+	u32			status;
+
+	bool			xfer_failed;
+};
+
+static inline u32 at91_usart_spi_tx_ready(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_TXRDY;
+}
+
+static inline u32 at91_usart_spi_rx_ready(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_RXRDY;
+}
+
+static inline u32 at91_usart_spi_check_overrun(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_OVRE;
+}
+
+static inline u32 at91_usart_spi_read_status(struct at91_usart_spi *aus)
+{
+	aus->status = at91_usart_spi_readl(aus, CSR);
+	return aus->status;
+}
+
+static inline void at91_usart_spi_tx(struct at91_usart_spi *aus)
+{
+	unsigned int len = aus->current_transfer->len;
+	unsigned int remaining = aus->current_tx_remaining_bytes;
+	const u8  *tx_buf = aus->current_transfer->tx_buf;
+
+	if (!remaining)
+		return;
+
+	if (at91_usart_spi_tx_ready(aus)) {
+		at91_usart_spi_writeb(aus, THR, tx_buf[len - remaining]);
+		aus->current_tx_remaining_bytes--;
+	}
+}
+
+static inline void at91_usart_spi_rx(struct at91_usart_spi *aus)
+{
+	int len = aus->current_transfer->len;
+	int remaining = aus->current_rx_remaining_bytes;
+	u8  *rx_buf = aus->current_transfer->rx_buf;
+
+	if (!remaining)
+		return;
+
+	rx_buf[len - remaining] = at91_usart_spi_readb(aus, RHR);
+	aus->current_rx_remaining_bytes--;
+}
+
+static inline void
+at91_usart_spi_set_xfer_speed(struct at91_usart_spi *aus,
+			      struct spi_transfer *xfer)
+{
+	at91_usart_spi_writel(aus, BRGR,
+			      DIV_ROUND_UP(aus->spi_clk, xfer->speed_hz));
+}
+
+static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id)
+{
+	struct spi_controller *controller = dev_id;
+	struct at91_usart_spi *aus = spi_master_get_devdata(controller);
+
+	spin_lock(&aus->lock);
+	at91_usart_spi_read_status(aus);
+
+	if (at91_usart_spi_check_overrun(aus)) {
+		aus->xfer_failed = true;
+		aus->done_status = -EIO;
+		at91_usart_spi_writel(aus, IDR, US_IR_OVRE | US_IR_RXRDY);
+		spin_unlock(&aus->lock);
+		return IRQ_HANDLED;
+	}
+
+	if (at91_usart_spi_rx_ready(aus)) {
+		at91_usart_spi_rx(aus);
+		spin_unlock(&aus->lock);
+		return IRQ_HANDLED;
+	}
+
+	spin_unlock(&aus->lock);
+
+	return IRQ_NONE;
+}
+
+static int at91_usart_spi_setup(struct spi_device *spi)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller);
+	u32 *ausd = spi->controller_state;
+	unsigned int mr = at91_usart_spi_readl(aus, MR);
+	u8 bits = spi->bits_per_word;
+
+	if (bits != 8) {
+		dev_dbg(&spi->dev, "Only 8 bits per word are supported\n");
+		return -EINVAL;
+	}
+
+	if (spi->mode & SPI_CPOL)
+		mr |= US_MR_CPOL;
+	else
+		mr &= ~US_MR_CPOL;
+
+	if (spi->mode & SPI_CPHA)
+		mr |= US_MR_CPHA;
+	else
+		mr &= ~US_MR_CPHA;
+
+	if (spi->mode & SPI_LOOP)
+		mr |= US_MR_LOOP;
+	else
+		mr &= ~US_MR_LOOP;
+
+	if (!ausd) {
+		ausd = kzalloc(sizeof(*ausd), GFP_KERNEL);
+		if (!ausd)
+			return -ENOMEM;
+
+		spi->controller_state = ausd;
+	}
+
+	*ausd = mr;
+
+	dev_dbg(&spi->dev,
+		"setup: bpw %u mode 0x%x -> mr %d %08x\n",
+		bits, spi->mode, spi->chip_select, mr);
+
+	return 0;
+}
+
+int at91_usart_spi_transfer_one(struct spi_controller *ctlr,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+
+	at91_usart_spi_set_xfer_speed(aus, xfer);
+	aus->done_status = 0;
+	aus->xfer_failed = false;
+	aus->current_transfer = xfer;
+	aus->current_tx_remaining_bytes = xfer->len;
+	aus->current_rx_remaining_bytes = xfer->len;
+
+	while ((aus->current_tx_remaining_bytes ||
+		aus->current_rx_remaining_bytes) && !aus->xfer_failed) {
+		at91_usart_spi_read_status(aus);
+		at91_usart_spi_tx(aus);
+		cpu_relax();
+	}
+	if (aus->xfer_failed) {
+		dev_err(aus->dev, "Overrun!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int at91_usart_spi_prepare_message(struct spi_controller *ctlr,
+				   struct spi_message *message)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+	struct spi_device *spi = message->spi;
+	u32 *ausd = spi->controller_state;
+
+	at91_usart_spi_writel(aus, CR, US_ENABLE);
+	at91_usart_spi_writel(aus, IER, US_OVRE_RXRDY_IRQS);
+	at91_usart_spi_writel(aus, MR, *ausd);
+
+	return 0;
+}
+
+int at91_usart_spi_unprepare_message(struct spi_controller *ctlr,
+				     struct spi_message *message)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+
+	at91_usart_spi_writel(aus, CR, US_RESET | US_DISABLE);
+	at91_usart_spi_writel(aus, IDR, US_OVRE_RXRDY_IRQS);
+
+	return 0;
+}
+
+static void at91_usart_spi_cleanup(struct spi_device *spi)
+{
+	struct at91_usart_spi_device *ausd = spi->controller_state;
+
+	spi->controller_state = NULL;
+	kfree(ausd);
+}
+
+static void at91_usart_spi_init(struct at91_usart_spi *aus)
+{
+	at91_usart_spi_writel(aus, MR, US_INIT);
+	at91_usart_spi_writel(aus, CR, US_RESET | US_DISABLE);
+}
+
+static int at91_usart_gpio_setup(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.parent->of_node;
+	int i;
+	int ret;
+	int nb;
+
+	if (!np)
+		return -EINVAL;
+
+	nb = of_gpio_named_count(np, "cs-gpios");
+	for (i = 0; i < nb; i++) {
+		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
+
+		if (cs_gpio < 0)
+			return cs_gpio;
+
+		if (gpio_is_valid(cs_gpio)) {
+			ret = devm_gpio_request_one(&pdev->dev, cs_gpio,
+						    GPIOF_DIR_OUT,
+						    dev_name(&pdev->dev));
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int at91_usart_spi_probe(struct platform_device *pdev)
+{
+	struct resource *regs;
+	struct spi_controller *controller;
+	struct at91_usart_spi *aus;
+	struct clk *clk;
+	int irq;
+	int ret;
+
+	regs = platform_get_resource(to_platform_device(pdev->dev.parent),
+				     IORESOURCE_MEM, 0);
+	if (!regs)
+		return -EINVAL;
+
+	irq = platform_get_irq(to_platform_device(pdev->dev.parent), 0);
+	if (irq < 0)
+		return irq;
+
+	clk = devm_clk_get(pdev->dev.parent, "usart");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = -ENOMEM;
+	controller = spi_alloc_master(&pdev->dev, sizeof(*aus));
+	if (!controller)
+		goto at91_usart_spi_probe_fail;
+
+	ret = at91_usart_gpio_setup(pdev);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH;
+	controller->dev.of_node = pdev->dev.parent->of_node;
+	controller->bits_per_word_mask = SPI_BPW_MASK(8);
+	controller->setup = at91_usart_spi_setup;
+	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+	controller->transfer_one = at91_usart_spi_transfer_one;
+	controller->prepare_message = at91_usart_spi_prepare_message;
+	controller->unprepare_message = at91_usart_spi_unprepare_message;
+	controller->cleanup = at91_usart_spi_cleanup;
+	controller->max_speed_hz = DIV_ROUND_UP(clk_get_rate(clk),
+						US_MIN_CLK_DIV);
+	controller->min_speed_hz = DIV_ROUND_UP(clk_get_rate(clk),
+						US_MAX_CLK_DIV);
+	platform_set_drvdata(pdev, controller);
+
+	aus = spi_master_get_devdata(controller);
+
+	aus->dev = &pdev->dev;
+	aus->regs = devm_ioremap_resource(&pdev->dev, regs);
+	if (IS_ERR(aus->regs)) {
+		ret = PTR_ERR(aus->regs);
+		goto at91_usart_spi_probe_fail;
+	}
+
+	aus->irq = irq;
+	aus->clk = clk;
+
+	ret = devm_request_irq(&pdev->dev, irq, at91_usart_spi_interrupt, 0,
+			       dev_name(&pdev->dev), controller);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	aus->spi_clk = clk_get_rate(clk);
+	at91_usart_spi_init(aus);
+
+	spin_lock_init(&aus->lock);
+	ret = devm_spi_register_master(&pdev->dev, controller);
+	if (ret)
+		goto fail_register_master;
+
+	dev_info(&pdev->dev,
+		 "Atmel USART SPI Controller version 0x%x at 0x%08x (irq %d)\n",
+		 at91_usart_spi_readl(aus, VERSION),
+		 regs->start, irq);
+
+	return 0;
+
+fail_register_master:
+	clk_disable_unprepare(clk);
+at91_usart_spi_probe_fail:
+	spi_master_put(controller);
+	return ret;
+}
+
+static int at91_usart_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct at91_usart_spi *aus = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(aus->clk);
+
+	return 0;
+}
+
+static const struct of_device_id at91_usart_spi_dt_ids[] = {
+	{ .compatible = "microchip,at91sam9g45-usart-spi"},
+	{ /* sentinel */}
+};
+
+MODULE_DEVICE_TABLE(of, at91_usart_spi_dt_ids);
+
+static struct platform_driver at91_usart_spi_driver = {
+	.driver = {
+		.name = "at91_usart_spi",
+	},
+	.probe = at91_usart_spi_probe,
+	.remove = at91_usart_spi_remove,
+};
+
+module_platform_driver(at91_usart_spi_driver);
+
+MODULE_DESCRIPTION("Microchip AT91 USART SPI Controller driver");
+MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:at91_usart_spi");
-- 
2.17.1

^ permalink raw reply related

* [PATCH v7 4/6] MAINTAINERS: add at91 usart spi driver
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180613163621.23995-1-radu.pirea@microchip.com>

Added entry for at91 usart mfd driver.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 12203d07c6af..dae31df711fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9201,6 +9201,13 @@ F:	drivers/mfd/at91-usart.c
 F:	include/dt-bindings/mfd/at91-usart.h
 F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
+MICROCHIP AT91 USART SPI DRIVER
+M:	Radu Pirea <radu.pirea@microchip.com>
+L:	linux-spi@vger.kernel.org
+S:	Supported
+F:	drivers/spi/spi-at91-usart.c
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-- 
2.17.1

^ permalink raw reply related

* [PATCH v7 3/6] mfd: at91-usart: added mfd driver for usart
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180613163621.23995-1-radu.pirea@microchip.com>

This mfd driver is just a wrapper over atmel_serial driver and
spi-at91-usart driver. Selection of one of the drivers is based on a
property from device tree. If the property is not specified, the default
driver is atmel_serial.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/Kconfig      |  9 ++++++
 drivers/mfd/Makefile     |  1 +
 drivers/mfd/at91-usart.c | 69 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)
 create mode 100644 drivers/mfd/at91-usart.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..a886672b960d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -99,6 +99,15 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
+config MFD_AT91_USART
+	tristate "AT91 USART Driver"
+	select MFD_CORE
+	help
+	  Select this to get support for AT91 USART IP. This is a wrapper
+	  over at91-usart-serial driver and usart-spi-driver. Only one function
+	  can be used at a time. The choice is done at boot time by the probe
+	  function of this MFD driver according to a device tree property.
+
 config MFD_ATMEL_FLEXCOM
 	tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d9d2cf0d32ef..db1332aa96db 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -185,6 +185,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_AT91_USART)	+= at91-usart.o
 obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
 obj-$(CONFIG_MFD_ATMEL_HLCDC)	+= atmel-hlcdc.o
 obj-$(CONFIG_MFD_ATMEL_SMC)	+= atmel-smc.o
diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c
new file mode 100644
index 000000000000..3014ce532644
--- /dev/null
+++ b/drivers/mfd/at91-usart.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for AT91 USART
+ *
+ * Copyright (C) 2018 Microchip Technology
+ *
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ *
+ */
+
+#include <dt-bindings/mfd/at91-usart.h>
+
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/property.h>
+
+static struct mfd_cell at91_usart_spi_subdev = {
+		.name = "at91_usart_spi",
+		.of_compatible = "microchip,at91sam9g45-usart-spi",
+	};
+
+static struct mfd_cell at91_usart_serial_subdev = {
+		.name = "atmel_usart_serial",
+		.of_compatible = "atmel,at91rm9200-usart-serial",
+	};
+
+static int at91_usart_mode_probe(struct platform_device *pdev)
+{
+	struct mfd_cell cell;
+	u32 opmode = AT91_USART_MODE_SERIAL;
+
+	device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode);
+
+	switch (opmode) {
+	case AT91_USART_MODE_SPI:
+		cell = at91_usart_spi_subdev;
+		break;
+	case AT91_USART_MODE_SERIAL:
+		cell = at91_usart_serial_subdev;
+		break;
+	default:
+		break;
+	}
+
+	return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1,
+			      NULL, 0, NULL);
+}
+
+static const struct of_device_id at91_usart_mode_of_match[] = {
+	{ .compatible = "atmel,at91rm9200-usart" },
+	{ .compatible = "atmel,at91sam9260-usart" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, at91_flexcom_of_match);
+
+static struct platform_driver at91_usart_mfd = {
+	.probe	= at91_usart_mode_probe,
+	.driver	= {
+		.name		= "at91_usart_mode",
+		.of_match_table	= at91_usart_mode_of_match,
+	},
+};
+
+module_platform_driver(at91_usart_mfd);
+
+MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>");
+MODULE_DESCRIPTION("AT91 USART MFD driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1

^ permalink raw reply related

* [PATCH v7 2/6] dt-bindings: add binding for atmel-usart in SPI mode
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180613163621.23995-1-radu.pirea@microchip.com>

This patch moves the bindings for serial from serial/atmel-usart.txt to
mfd/atmel-usart.txt and adds bindings for USART in SPI mode.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/{serial => mfd}/atmel-usart.txt  | 25 +++++++++++++++++--
 include/dt-bindings/mfd/at91-usart.h          | 17 +++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)
 create mode 100644 include/dt-bindings/mfd/at91-usart.h

diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/mfd/atmel-usart.txt
similarity index 76%
rename from Documentation/devicetree/bindings/serial/atmel-usart.txt
rename to Documentation/devicetree/bindings/mfd/atmel-usart.txt
index 7c0d6b2f53e4..3b9e18642c3b 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/mfd/atmel-usart.txt
@@ -1,6 +1,6 @@
 * Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART)
 
-Required properties:
+Required properties for USART:
 - compatible: Should be "atmel,<chip>-usart" or "atmel,<chip>-dbgu"
   The compatible <chip> indicated will be the first SoC to support an
   additional mode or an USART new feature.
@@ -11,7 +11,13 @@ Required properties:
 	Required elements: "usart"
 - clocks: phandles to input clocks.
 
-Optional properties:
+Required properties for USART in SPI mode:
+- #size-cells      : Must be <0>
+- #address-cells   : Must be <1>
+- cs-gpios: chipselects (internal cs not supported)
+- atmel,usart-mode : Must be <USART_MODE_SPI> (found in dt-bindings/mfd/at91-usart.h)
+
+Optional properties in serial mode:
 - atmel,use-dma-rx: use of PDC or DMA for receiving data
 - atmel,use-dma-tx: use of PDC or DMA for transmitting data
 - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD line respectively.
@@ -62,3 +68,18 @@ Example:
 		dma-names = "tx", "rx";
 		atmel,fifo-size = <32>;
 	};
+
+- SPI mode:
+	#include <dt-bindings/mfd/at91-usart.h>
+
+	spi0: spi@f001c000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "atmel,at91rm9200-usart", "atmel,at91sam9260-usart";
+		atmel,usart-mode = <USART_MODE_SPI>;
+		reg = <0xf001c000 0x100>;
+		interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&usart0_clk>;
+		clock-names = "usart";
+		cs-gpios = <&pioB 3 0>;
+	};
diff --git a/include/dt-bindings/mfd/at91-usart.h b/include/dt-bindings/mfd/at91-usart.h
new file mode 100644
index 000000000000..2de5bc312e1e
--- /dev/null
+++ b/include/dt-bindings/mfd/at91-usart.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides macros for AT91 USART DT bindings.
+ *
+ * Copyright (C) 2018 Microchip Technology
+ *
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_AT91_USART_H__
+#define __DT_BINDINGS_AT91_USART_H__
+
+#define AT91_USART_MODE_SERIAL	0
+#define AT91_USART_MODE_SPI	1
+
+#endif /* __DT_BINDINGS_AT91_USART_H__ */
-- 
2.17.1

^ permalink raw reply related

* [PATCH v7 1/6] MAINTAINERS: add at91 usart mfd driver
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180613163621.23995-1-radu.pirea@microchip.com>

Added entry for at91 usart mfd driver.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8e2a2fddbd19..12203d07c6af 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9160,6 +9160,7 @@ M:	Richard Genoud <richard.genoud@gmail.com>
 S:	Maintained
 F:	drivers/tty/serial/atmel_serial.c
 F:	drivers/tty/serial/atmel_serial.h
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
 MICROCHIP / ATMEL DMA DRIVER
 M:	Ludovic Desroches <ludovic.desroches@microchip.com>
@@ -9192,6 +9193,14 @@ S:	Supported
 F:	drivers/mtd/nand/raw/atmel/*
 F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
 
+MICROCHIP AT91 USART MFD DRIVER
+M:	Radu Pirea <radu.pirea@microchip.com>
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	drivers/mfd/at91-usart.c
+F:	include/dt-bindings/mfd/at91-usart.h
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-- 
2.17.1

^ permalink raw reply related

* [PATCH v7 0/6] Driver for at91 usart in spi mode
From: Radu Pirea @ 2018-06-13 16:36 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea

Hello,

This is the second version of driver. I added a mfd driver which by
default probes atmel_serial driver and if in dt is specified to probe
the spi driver, then the spi-at91-usart driver will be probed. The
compatible for atmel_serial is now the compatible for at91-usart mfd
driver and compatilbe for atmel_serial driver was changed in order to
keep the bindings for serial as they are.

Changes in v7:
- synced up  SPDIX license with module license
- numbering of usart modes starts from 0 insteand of 1

Changes in v6:
- removed unused compatible strings from serial and spi drivers

Changes in v5:
- fixed usage of stdout-path property with atmel_serial driver

Changes in v4:
- modified the spi driver to use cs gpio support form spi subsystem
- fixed dma transfers for serial driver
- squashed binding for spi and serial and moved them to mfd/atmel-usart.txt

Changes in v3:
- fixed spi slaves probing

Changes in v2:
- added at91-usart mfd driver
- modified spi-at91-usart driver to work as mfd driver child
- modified atmel_serial driver to work as mfd driver child

Changes in v1:
- added spi-at91-usart driver

Radu Pirea (6):
  MAINTAINERS: add at91 usart mfd driver
  dt-bindings: add binding for atmel-usart in SPI mode
  mfd: at91-usart: added mfd driver for usart
  MAINTAINERS: add at91 usart spi driver
  spi: at91-usart: add driver for at91-usart as spi
  tty/serial: atmel: change the driver to work under at91-usart mfd

 .../bindings/{serial => mfd}/atmel-usart.txt  |  25 +-
 MAINTAINERS                                   |  16 +
 drivers/mfd/Kconfig                           |   9 +
 drivers/mfd/Makefile                          |   1 +
 drivers/mfd/at91-usart.c                      |  69 +++
 drivers/spi/Kconfig                           |   9 +
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-at91-usart.c                  | 434 ++++++++++++++++++
 drivers/tty/serial/Kconfig                    |   1 +
 drivers/tty/serial/atmel_serial.c             |  42 +-
 include/dt-bindings/mfd/at91-usart.h          |  17 +
 11 files changed, 607 insertions(+), 17 deletions(-)
 rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)
 create mode 100644 drivers/mfd/at91-usart.c
 create mode 100644 drivers/spi/spi-at91-usart.c
 create mode 100644 include/dt-bindings/mfd/at91-usart.h

-- 
2.17.1

^ permalink raw reply

* [PATCH] serdev: fix memleak on module unload
From: Johan Hovold @ 2018-06-13 15:08 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman
  Cc: Jiri Slaby, linux-serial, linux-kernel, Johan Hovold, stable

Make sure to free all resources associated with the ida on module
exit.

Fixes: cd6484e1830b ("serdev: Introduce new bus for serial attached devices")
Cc: stable <stable@vger.kernel.org>	# 4.11
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/tty/serdev/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index df93b727e984..9e59f4788589 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -617,6 +617,7 @@ EXPORT_SYMBOL_GPL(__serdev_device_driver_register);
 static void __exit serdev_exit(void)
 {
 	bus_unregister(&serdev_bus_type);
+	ida_destroy(&ctrl_ida);
 }
 module_exit(serdev_exit);
 
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH v2 18/24] serdev: ttydev: Serdev driver that creates an standard TTY port
From: Ricardo Ribalda Delgado @ 2018-06-13  6:35 UTC (permalink / raw)
  To: Rob Herring
  Cc: LKML, open list:SERIAL DRIVERS, Johan Hovold, Greg Kroah-Hartman,
	Jiri Slaby, Andy Shevchenko
In-Reply-To: <CAL_JsqLhRSbhmpaiqgG_TRRXQEsRKG5UK0HWw0tu9Eymn8cNcA@mail.gmail.com>

Hi Rob,
On Wed, Jun 13, 2018 at 3:20 AM Rob Herring <robh@kernel.org> wrote:
>
> On Mon, Jun 11, 2018 at 5:52 AM, Ricardo Ribalda Delgado
> <ricardo.ribalda@gmail.com> wrote:
> > Standard TTY port that can be loaded/unloaded via serdev sysfs. This
> > serdev driver can only be used by serdev controllers that are compatible
> > with ttyport.
>
> I'm hesitant to expose a tty device on top of serdev to userspace that
> we then have to support forever unless that's the only way tty devices
> (for serial ports) are created.

My concern is that, with the current implementation, serdev does have
a tiny collection of usecases:

-It cannot be used for board bring up
-It cannot be used as a replacement of hciattach and friends

It can only be used on embedded devices or platforms where the
developer has control of the ACPI table.

This hack, allows its use in almost any scenario and I have been
happily using it for two weeks with no issue.
It is also a very simple solution that does not have the issues of
cdev/serdev coexistence that you mention.

I am not very convinced about all the ttydev being serdevs. Adding 1K
lines of code to people that do not plan to use serdev seems like a
high expense. If in the future we can get rid of all the hciattach
programs then we can redesign the port probing.

>
> I did a similar patch which just registered both serdev and a tty
> allowing them to coexist. It suffered from warnings about open counts
> though and felt hacky.
>
> Rob



-- 
Ricardo Ribalda

^ permalink raw reply

* Re: [PATCH v4 2/6] dt-bindings: add binding for atmel-usart in SPI mode
From: Lee Jones @ 2018-06-13  6:11 UTC (permalink / raw)
  To: Radu Pirea
  Cc: broonie, nicolas.ferre, alexandre.belloni, richard.genoud,
	robh+dt, mark.rutland, gregkh, linux-spi, linux-arm-kernel,
	linux-kernel, devicetree, linux-serial
In-Reply-To: <20180525171941.26766-3-radu.pirea@microchip.com>

On Fri, 25 May 2018, Radu Pirea wrote:

> This patch moves the bindings for serial from serial/atmel-usart.txt to
> mfd/atmel-usart.txt and adds bindings for USART in SPI mode.
> 
> Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
> ---
>  .../bindings/{serial => mfd}/atmel-usart.txt  | 25 +++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)
>  rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* Re: [PATCH v2 18/24] serdev: ttydev: Serdev driver that creates an standard TTY port
From: Rob Herring @ 2018-06-13  1:20 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: linux-kernel@vger.kernel.org, open list:SERIAL DRIVERS,
	Johan Hovold, Greg Kroah-Hartman, Jiri Slaby, Andy Shevchenko
In-Reply-To: <20180611115240.32606-19-ricardo.ribalda@gmail.com>

On Mon, Jun 11, 2018 at 5:52 AM, Ricardo Ribalda Delgado
<ricardo.ribalda@gmail.com> wrote:
> Standard TTY port that can be loaded/unloaded via serdev sysfs. This
> serdev driver can only be used by serdev controllers that are compatible
> with ttyport.

I'm hesitant to expose a tty device on top of serdev to userspace that
we then have to support forever unless that's the only way tty devices
(for serial ports) are created.

I did a similar patch which just registered both serdev and a tty
allowing them to coexist. It suffered from warnings about open counts
though and felt hacky.

Rob

^ permalink raw reply

* Re: [PATCH 7/7] tty: serial: lantiq: Add CCF support
From: Rob Herring @ 2018-06-12 22:39 UTC (permalink / raw)
  To: Songjun Wu
  Cc: hua.ma, yixin.zhu, chuanhua.lei, linux-mips, qi-ming.wu,
	linux-clk, linux-serial, devicetree, Jiri Slaby, linux-kernel,
	Greg Kroah-Hartman, Mark Rutland
In-Reply-To: <20180612054034.4969-8-songjun.wu@linux.intel.com>

On Tue, Jun 12, 2018 at 01:40:34PM +0800, Songjun Wu wrote:
> Previous implementation uses platform-dependent API to get the clock.
> Those functions are not available for other SoC which uses the same IP.
> The CCF (Common Clock Framework) have an abstraction based APIs
> for clock.
> Change to use CCF APIs to get clock and rate.
> So that different SoCs can use the same driver.
> Clocks and clock-names are updated in device tree binding.
> 
> Signed-off-by: Songjun Wu <songjun.wu@linux.intel.com>
> 
> ---
> 
>  .../devicetree/bindings/serial/lantiq_asc.txt      |  15 +++

Please split bindings to separate patch.

>  drivers/tty/serial/Kconfig                         |   2 +-
>  drivers/tty/serial/lantiq.c                        | 101 +++++++++++++++++----
>  3 files changed, 98 insertions(+), 20 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/lantiq_asc.txt b/Documentation/devicetree/bindings/serial/lantiq_asc.txt
> index 3acbd309ab9d..608f0c87a4af 100644
> --- a/Documentation/devicetree/bindings/serial/lantiq_asc.txt
> +++ b/Documentation/devicetree/bindings/serial/lantiq_asc.txt
> @@ -6,6 +6,10 @@ Required properties:
>  - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier
>    depends on the interrupt-parent interrupt controller.
>  
> +Optional properties:
> +- clocks: Should contain frequency clock and gate clock
> +- clock-names: Should be "freq" and "asc"
> +
>  Example:
>  
>  asc1: serial@e100c00 {
> @@ -14,3 +18,14 @@ asc1: serial@e100c00 {
>  	interrupt-parent = <&icu0>;
>  	interrupts = <112 113 114>;
>  };
> +
> +asc0: serial@600000 {
> +	compatible = "lantiq,asc";
> +	reg = <0x600000 0x100000>;

1MB of address space? That wastes a lot of virtual space on 32-bit 
systems. Just make the size the actual used range.

> +	interrupt-parent = <&gic>;
> +	interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>,
> +	<GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>,
> +	<GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>;
> +	clocks = <&pll0aclk SSX4_CLK>, <&clkgate1 GATE_URT_CLK>;
> +	clock-names = "freq", "asc";
> +};

^ permalink raw reply

* Re: [PATCH 2/7] clk: intel: Add clock driver for GRX500 SoC
From: Rob Herring @ 2018-06-12 22:37 UTC (permalink / raw)
  To: Songjun Wu
  Cc: hua.ma, yixin.zhu, chuanhua.lei, linux-mips, qi-ming.wu,
	linux-clk, linux-serial, devicetree, Michael Turquette,
	Stephen Boyd, linux-kernel, Mark Rutland
In-Reply-To: <20180612054034.4969-3-songjun.wu@linux.intel.com>

On Tue, Jun 12, 2018 at 01:40:29PM +0800, Songjun Wu wrote:
> From: Yixin Zhu <yixin.zhu@linux.intel.com>
> 
> PLL of GRX500 provide clock to DDR, CPU, and peripherals as show below
> 
>                  +---------+
> 	    |--->| LCPLL3 0|--PCIe clk-->
>    XO       |    +---------+
> +-----------|
>             |    +---------+
>             |    |        3|--PAE clk-->
>             |--->| PLL0B  2|--GSWIP clk-->
>             |    |        1|--DDR clk-->DDR PHY clk-->
>             |    |        0|--CPU1 clk--+   +-----+
>             |    +---------+            |--->0    |
>             |                               | MUX |--CPU clk-->
>             |    +---------+            |--->1    |
>             |    |        0|--CPU0 clk--+   +-----+
>             |--->| PLLOA  1|--SSX4 clk-->
>                  |        2|--NGI clk-->
>                  |        3|--CBM clk-->
>                  +---------+
> 
> VCO of all PLLs of GRX500 is not supposed to be reprogrammed.
> DDR PHY clock is created to show correct clock rate in software
> point of view.
> CPU clock of 1Ghz from PLL0B otherwise from PLL0A.
> Signed-off-by: Yixin Zhu <yixin.zhu@linux.intel.com>
> 
> Signed-off-by: Songjun Wu <songjun.wu@linux.intel.com>

Need a blank line before the SoB's and not one in the middle.

> ---
> 
>  .../devicetree/bindings/clock/intel,grx500-clk.txt |  46 ++

Please split bindings to separate patch.

>  drivers/clk/Kconfig                                |   1 +
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/intel/Kconfig                          |  21 +
>  drivers/clk/intel/Makefile                         |   7 +
>  drivers/clk/intel/clk-cgu-api.c                    | 676 +++++++++++++++++++++
>  drivers/clk/intel/clk-cgu-api.h                    | 120 ++++
>  drivers/clk/intel/clk-grx500.c                     | 236 +++++++
>  include/dt-bindings/clock/intel,grx500-clk.h       |  61 ++
>  9 files changed, 1169 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/intel,grx500-clk.txt
>  create mode 100644 drivers/clk/intel/Kconfig
>  create mode 100644 drivers/clk/intel/Makefile
>  create mode 100644 drivers/clk/intel/clk-cgu-api.c
>  create mode 100644 drivers/clk/intel/clk-cgu-api.h
>  create mode 100644 drivers/clk/intel/clk-grx500.c
>  create mode 100644 include/dt-bindings/clock/intel,grx500-clk.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt b/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt
> new file mode 100644
> index 000000000000..dd761d900dc9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt
> @@ -0,0 +1,46 @@
> +Device Tree Clock bindings for GRX500 PLL controller.
> +
> +This binding uses the common clock binding:
> +	Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +This GRX500 PLL controller provides the 5 main clock domain of the SoC: CPU/DDR, XBAR,
> +Voice, WLAN, PCIe and gate clocks for HW modules.
> +
> +Required properties for osc clock node
> +- compatible: Should be intel,grx500-xxx-clk

These would need to be enumerated with all possible values. However, see 
below.

> +- reg: offset address of the controller memory area.
> +- clocks: phandle of the external reference clock
> +- #clock-cells: can be one or zero.
> +- clock-output-names: Names of the output clocks.
> +
> +Example:
> +	pll0aclk: pll0aclk {
> +		#clock-cells = <1>;
> +		compatible = "intel,grx500-pll0a-clk";
> +		clocks = <&pll0a>;
> +		reg = <0x8>;
> +		clock-output-names = "cbmclk", "ngiclk", "ssx4clk", "cpu0clk";
> +	};
> +
> +	cpuclk: cpuclk {
> +		#clock-cells = <0>;
> +		compatible = "intel,grx500-cpu-clk";
> +		clocks = <&pll0aclk CPU0_CLK>, <&pll0bclk CPU1_CLK>;
> +		reg = <0x8>;
> +		clock-output-names = "cpu";
> +	};
> +
> +Required properties for gate node:
> +- compatible: Should be intel,grx500-gatex-clk
> +- reg: offset address of the controller memory area.
> +- #clock-cells: Should be <1>
> +- clock-output-names: Names of the output clocks.
> +
> +Example:
> +	clkgate0: clkgate0 {
> +		#clock-cells = <1>;
> +		compatible = "intel,grx500-gate0-clk";
> +		reg = <0x114>;
> +		clock-output-names = "gate_xbar0", "gate_xbar1", "gate_xbar2",
> +		"gate_xbar3", "gate_xbar6", "gate_xbar7";
> +	};

We generally don't do a clock node per clock or few clocks but rather 1 
clock node per clock controller block. See any recent clock bindings.

Rob

^ permalink raw reply

* Re: [PATCH 3/7] MIPS: intel: Add initial support for Intel MIPS SoCs
From: Rob Herring @ 2018-06-12 22:31 UTC (permalink / raw)
  To: Songjun Wu
  Cc: hua.ma, yixin.zhu, chuanhua.lei, linux-mips, qi-ming.wu,
	linux-clk, linux-serial, devicetree, James Hogan, linux-kernel,
	Ralf Baechle, Mark Rutland
In-Reply-To: <20180612054034.4969-4-songjun.wu@linux.intel.com>

On Tue, Jun 12, 2018 at 01:40:30PM +0800, Songjun Wu wrote:
> From: Hua Ma <hua.ma@linux.intel.com>
> 
> Add initial support for Intel MIPS interAptiv SoCs made by Intel.
> This series will add support for the GRX500 family.
> 
> The series allows booting a minimal system using a initramfs.
> 
> Signed-off-by: Hua ma <hua.ma@linux.intel.com>
> Signed-off-by: Songjun Wu <songjun.wu@linux.intel.com>
> ---
> 
>  arch/mips/Kbuild.platforms                         |   1 +
>  arch/mips/Kconfig                                  |  36 ++++
>  arch/mips/boot/dts/Makefile                        |   1 +
>  arch/mips/boot/dts/intel-mips/Makefile             |   3 +
>  arch/mips/boot/dts/intel-mips/easy350_anywan.dts   |  20 +++
>  arch/mips/boot/dts/intel-mips/xrx500.dtsi          | 196 +++++++++++++++++++++

Please split dts files to separate patch.


> diff --git a/arch/mips/boot/dts/intel-mips/easy350_anywan.dts b/arch/mips/boot/dts/intel-mips/easy350_anywan.dts
> new file mode 100644
> index 000000000000..40177f6cee1e
> --- /dev/null
> +++ b/arch/mips/boot/dts/intel-mips/easy350_anywan.dts
> @@ -0,0 +1,20 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/dts-v1/;
> +
> +#include <dt-bindings/interrupt-controller/mips-gic.h>
> +#include <dt-bindings/clock/intel,grx500-clk.h>
> +
> +#include "xrx500.dtsi"
> +
> +/ {
> +	model = "EASY350 ANYWAN (GRX350) Main model";

A board should have a board specific compatible, too. 

> +	chosen {
> +		bootargs = "earlycon=lantiq,0x16600000 clk_ignore_unused";
> +		stdout-path = "serial0";
> +	};
> +
> +	memory@0 {

memory@20000000

> +		device_type = "memory";
> +		reg = <0x20000000 0x0e000000>;
> +	};
> +};
> diff --git a/arch/mips/boot/dts/intel-mips/xrx500.dtsi b/arch/mips/boot/dts/intel-mips/xrx500.dtsi
> new file mode 100644
> index 000000000000..04a068d6d96b
> --- /dev/null
> +++ b/arch/mips/boot/dts/intel-mips/xrx500.dtsi
> @@ -0,0 +1,196 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	compatible = "intel,xrx500";

This needs to be documented.

> +
> +	aliases {
> +		serial0 = &asc0;
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			compatible = "mti,interaptiv";
> +			clocks = <&cpuclk>;
> +			reg = <0>;
> +		};
> +
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			compatible = "mti,interaptiv";
> +			reg = <1>;
> +		};
> +	};
> +
> +	cpu_intc: interrupt-controller {
> +		compatible = "mti,cpu-interrupt-controller";
> +
> +		interrupt-controller;
> +		#interrupt-cells = <1>;
> +	};
> +
> +	gic: gic@12320000 {
> +		compatible = "mti,gic";
> +		reg = <0x12320000 0x20000>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <3>;
> +		/*
> +		 * Declare the interrupt-parent even though the mti,gic
> +		 * binding doesn't require it, such that the kernel can
> +		 * figure out that cpu_intc is the root interrupt
> +		 * controller & should be probed first.
> +		 */
> +		interrupt-parent = <&cpu_intc>;
> +		mti,reserved-ipi-vectors = <56 8>;
> +	};
> +
> +	cgu0: cgu@16200000 {
> +		compatible = "syscon";
> +		reg = <0x16200000 0x100000>;
> +
> +		clock {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			osc0: osc0 {
> +				#clock-cells = <0>;
> +				compatible = "fixed-clock";
> +				clock-frequency = <40000000>;
> +				clock-output-names = "osc40M";
> +			};
> +
> +			pll0a: pll0a {
> +				#clock-cells = <0>;
> +				compatible = "fixed-factor-clock";
> +				clock-mult = <0x3C>;
> +				clock-div = <1>;
> +				clocks = <&osc0>;
> +				clock-output-names = "pll0a";
> +			};
> +
> +			pll0b: pll0b {
> +				#clock-cells = <0>;
> +				compatible = "fixed-factor-clock";
> +				clock-mult = <0x32>;
> +				clock-div = <1>;
> +				clocks = <&osc0>;
> +				clock-output-names = "pll0b";
> +			};
> +
> +			pll3: pll3 {
> +				#clock-cells = <0>;
> +				compatible = "fixed-factor-clock";
> +				clock-mult = <0x64>;
> +				clock-div = <1>;
> +				clocks = <&osc0>;
> +				clock-output-names = "lcpll3";
> +			};
> +
> +			pll0aclk: pll0aclk {
> +				#clock-cells = <1>;
> +				compatible = "intel,grx500-pll0a-clk";
> +				clocks = <&pll0a>;
> +				reg = <0x8>;
> +				clock-output-names = "cbm", "ngi",
> +				"ssx4", "cpu0";
> +			};
> +
> +			pll0bclk: pll0bclk {
> +				#clock-cells = <1>;
> +				compatible = "intel,grx500-pll0b-clk";
> +				clocks = <&pll0b>;
> +				reg = <0x38>;
> +				clock-output-names = "pae", "gswip", "ddr",
> +				"cpu1";
> +			};
> +
> +			ddrphyclk: ddrphyclk {
> +				#clock-cells = <0>;
> +				compatible = "fixed-factor-clock";
> +				clock-mult = <2>;
> +				clock-div = <1>;
> +				clocks = <&pll0bclk DDR_CLK>;
> +				clock-output-names = "ddrphy";
> +			};
> +
> +			pcieclk: pcieclk {
> +				#clock-cells = <0>;
> +				compatible = "intel,grx500-pcie-clk";
> +				clocks = <&pll3>;
> +				reg = <0x98>;
> +				clock-output-names = "pcie";
> +			};
> +
> +			cpuclk: cpuclk {
> +				#clock-cells = <0>;
> +				compatible = "intel,grx500-cpu-clk";
> +				clocks = <&pll0aclk CPU0_CLK>,
> +				<&pll0bclk CPU1_CLK>;
> +				reg = <0x8>;
> +				clock-output-names = "cpu";
> +			};
> +
> +			clkgate0: clkgate0 {
> +				#clock-cells = <1>;
> +				compatible = "intel,grx500-gate0-clk";
> +				reg = <0x114>;
> +				clock-output-names = "gate_xbar0", "gate_xbar1",
> +				"gate_xbar2", "gate_xbar3", "gate_xbar6",
> +				"gate_xbar7";
> +			};
> +
> +			clkgate1: clkgate1 {
> +				#clock-cells = <1>;
> +				compatible = "intel,grx500-gate1-clk";
> +				reg = <0x120>;
> +				clock-output-names = "gate_vcodec", "gate_dma0",
> +				"gate_usb0", "gate_spi1", "gate_spi0",
> +				"gate_cbm", "gate_ebu", "gate_sso",
> +				"gate_gptc0", "gate_gptc1", "gate_gptc2",
> +				"gate_urt", "gate_eip97", "gate_eip123",
> +				"gate_toe", "gate_mpe", "gate_tdm", "gate_pae",
> +				"gate_usb1", "gate_gswip";
> +			};
> +
> +			clkgate2: clkgate2 {
> +				#clock-cells = <1>;
> +				compatible = "intel,grx500-gate2-clk";
> +				reg = <0x130>;
> +				clock-output-names = "gate_pcie0", "gate_pcie1",
> +				"gate_pcie2";
> +			};
> +
> +			voiceclk: voiceclk {
> +				#clock-cells = <0>;
> +				compatible = "intel,grx500-voice-clk";
> +				clock-frequency = <8192000>;
> +				reg = <0xc4>;
> +				clock-output-names = "voice";
> +			};
> +
> +			i2cclk: i2cclk {
> +				#clock-cells = <0>;
> +				compatible = "intel,grx500-gate-dummy-clk";
> +				clock-output-names = "gate_i2c";
> +			};
> +		};
> +	};
> +
> +	asc0: serial@16600000 {
> +		compatible = "lantiq,asc";
> +		reg = <0x16600000 0x100000>;
> +
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>,
> +			<GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>,
> +			<GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&pll0aclk SSX4_CLK>, <&clkgate1 GATE_URT_CLK>;
> +		clock-names = "freq", "asc";
> +	};
> +};

^ permalink raw reply

* Re: [PATCH 1/7] MIPS: dts: Add aliases node for lantiq danube serial
From: Rob Herring @ 2018-06-12 22:24 UTC (permalink / raw)
  To: Songjun Wu
  Cc: hua.ma, yixin.zhu, chuanhua.lei, linux-mips, qi-ming.wu,
	linux-clk, linux-serial, devicetree, James Hogan, linux-kernel,
	Thomas Gleixner, Philippe Ombredanne, Kate Stewart,
	Greg Kroah-Hartman, Mark Rutland, Ralf Baechle
In-Reply-To: <20180612054034.4969-2-songjun.wu@linux.intel.com>

On Tue, Jun 12, 2018 at 01:40:28PM +0800, Songjun Wu wrote:
> Previous implementation uses a hard-coded register value to check if
> the current serial entity is the console entity.
> Now the lantiq serial driver uses the aliases for the index of the
> serial port.
> The lantiq danube serial dts are updated with aliases to support this.
> 
> Signed-off-by: Songjun Wu <songjun.wu@linux.intel.com>
> ---
> 
>  arch/mips/boot/dts/lantiq/danube.dtsi | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/mips/boot/dts/lantiq/danube.dtsi b/arch/mips/boot/dts/lantiq/danube.dtsi
> index 2dd950181f8a..7a9e15da6bd0 100644
> --- a/arch/mips/boot/dts/lantiq/danube.dtsi
> +++ b/arch/mips/boot/dts/lantiq/danube.dtsi
> @@ -4,6 +4,10 @@
>  	#size-cells = <1>;
>  	compatible = "lantiq,xway", "lantiq,danube";
>  
> +	aliases {
> +		serial0 = &asc1;
> +	};
> +
>  	cpus {
>  		cpu@0 {
>  			compatible = "mips,mips24Kc";
> @@ -74,7 +78,7 @@
>  			reg = <0xE100A00 0x100>;
>  		};
>  
> -		serial@E100C00 {
> +		asc1: serial@E100C00 {

Fix this to be lower case hex while you are at it.

>  			compatible = "lantiq,asc";
>  			reg = <0xE100C00 0x400>;
>  			interrupt-parent = <&icu0>;
> -- 
> 2.11.0
> 

^ permalink raw reply

* Re: [RFC PATCH 3/6] serial: 8250_omap: Add support for AM654 UART controller
From: Nishanth Menon @ 2018-06-12 22:03 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, devicetree, Sudeep Holla, Vignesh R, Tony Lindgren,
	Catalin Marinas, Santosh Shilimkar, Will Deacon, linux-kernel,
	Sekhar Nori, Russell King, Tero Kristo, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <20180612210640.GA20728@rob-hp-laptop>

On 21:06-20180612, Rob Herring wrote:
> > diff --git a/Documentation/devicetree/bindings/serial/omap_serial.txt b/Documentation/devicetree/bindings/serial/omap_serial.txt
> > index 4b0f05adb228..c35d5ece1156 100644
> > --- a/Documentation/devicetree/bindings/serial/omap_serial.txt
> > +++ b/Documentation/devicetree/bindings/serial/omap_serial.txt
> > @@ -1,6 +1,7 @@
> >  OMAP UART controller
> >  
> >  Required properties:
> > +- compatible : should be "ti,am654-uart" for AM654 controllers
> 
> Not compatible with any existing TI 8250 UARTs?

Base is compatible, however there are differences in DMA operation and
few additional bits. omap4-uart is sufficient for a basic PIO mode of
operation given initialization a bootloader might do for base console.

I will split the bindings off into it's own patch to keep the confusion
to a minimum and allowing serial driver change to go in independently.

-- 
Regards,
Nishanth Menon

^ permalink raw reply

* Re: [RFC PATCH 1/6] Documentation: arm: ti: Add bindings for AM654 SoC
From: Nishanth Menon @ 2018-06-12 22:01 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, devicetree, Sudeep Holla, Vignesh R, Tony Lindgren,
	Catalin Marinas, Santosh Shilimkar, Will Deacon, linux-kernel,
	Russell King, Tero Kristo, linux-serial, Greg Kroah-Hartman,
	linux-arm-kernel
In-Reply-To: <20180612210519.GA17653@rob-hp-laptop>

On 21:05-20180612, Rob Herring wrote:
> On Tue, Jun 05, 2018 at 01:01:20AM -0500, Nishanth Menon wrote:
[...]
> > +Boards based on K3 Multicore SoC architecture shall have the following property:
> > +- compatible: Every hardware block introduced in K3 Multicore SoC
> > +  architecture shall be of the form:
> > +  "ti,XXX-YYY", where:
> > +     'XXX' represents the specific SoC part for which the support is added.
> > +     'YYY' represents the corresponding peripheral in SoC being supported.
> 
> No need to explain standard DT convention here. (But I don't think we 
> have this convention documented anywhere, so patches welcome. :))
> 

Thanks. Will drop off from my series (will skip the generic dts
convention for now ;) ).
-- 
Regards,
Nishanth Menon

^ permalink raw reply

* Re: [RFC PATCH 3/6] serial: 8250_omap: Add support for AM654 UART controller
From: Rob Herring @ 2018-06-12 21:06 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Santosh Shilimkar, Will Deacon, Catalin Marinas,
	Greg Kroah-Hartman, Mark Rutland, linux-serial, linux-kernel,
	devicetree, linux-arm-kernel, Tony Lindgren, Vignesh R,
	Tero Kristo, Russell King, Sudeep Holla, Sekhar Nori
In-Reply-To: <20180605060125.9518-4-nm@ti.com>

On Tue, Jun 05, 2018 at 01:01:22AM -0500, Nishanth Menon wrote:
> AM654 uses a UART controller that is compatible (partially) with
> existing 8250 UART, however, has a few differences with respect to DMA
> support and control paths. Introduce a base definition that allows us
> to build up the differences in follow on patches.
> 
> Cc: Sekhar Nori <nsekhar@ti.com>
> Cc: Vignesh R <vigneshr@ti.com>
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  Documentation/devicetree/bindings/serial/omap_serial.txt | 1 +
>  drivers/tty/serial/8250/8250_omap.c                      | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/serial/omap_serial.txt b/Documentation/devicetree/bindings/serial/omap_serial.txt
> index 4b0f05adb228..c35d5ece1156 100644
> --- a/Documentation/devicetree/bindings/serial/omap_serial.txt
> +++ b/Documentation/devicetree/bindings/serial/omap_serial.txt
> @@ -1,6 +1,7 @@
>  OMAP UART controller
>  
>  Required properties:
> +- compatible : should be "ti,am654-uart" for AM654 controllers

Not compatible with any existing TI 8250 UARTs?

>  - compatible : should be "ti,omap2-uart" for OMAP2 controllers
>  - compatible : should be "ti,omap3-uart" for OMAP3 controllers
>  - compatible : should be "ti,omap4-uart" for OMAP4 controllers
> diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
> index 1b337fee07ed..a019286f8bb6 100644
> --- a/drivers/tty/serial/8250/8250_omap.c
> +++ b/drivers/tty/serial/8250/8250_omap.c
> @@ -1115,6 +1115,7 @@ static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;
>  static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;
>  
>  static const struct of_device_id omap8250_dt_ids[] = {
> +	{ .compatible = "ti,am654-uart" },
>  	{ .compatible = "ti,omap2-uart" },
>  	{ .compatible = "ti,omap3-uart" },
>  	{ .compatible = "ti,omap4-uart", .data = &omap4_habit, },
> -- 
> 2.15.1
> 

^ permalink raw reply

* Re: [RFC PATCH 1/6] Documentation: arm: ti: Add bindings for AM654 SoC
From: Rob Herring @ 2018-06-12 21:05 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Santosh Shilimkar, Will Deacon, Catalin Marinas,
	Greg Kroah-Hartman, Mark Rutland, linux-serial, linux-kernel,
	devicetree, linux-arm-kernel, Tony Lindgren, Vignesh R,
	Tero Kristo, Russell King, Sudeep Holla
In-Reply-To: <20180605060125.9518-2-nm@ti.com>

On Tue, Jun 05, 2018 at 01:01:20AM -0500, Nishanth Menon wrote:
> The AM654 SoC is a lead device of the K3 Multicore SoC architecture
> platform, targeted for broad market and industrial control with aim to
> meet the complex processing needs of modern embedded products.
> 
> Some highlights of this SoC are:
> * Quad ARMv8 A53 cores split over two clusters
> * GICv3 compliant GIC500
> * Configurable L3 Cache and IO-coherent architecture
> * Dual lock-step capable R5F uC for safety-critical applications
> * High data throughput capable distributed DMA architecture under NAVSS
> * Three Gigabit Industrial Communication Subsystems (ICSSG), each with dual
>   PRUs and dual RTUs
> * Hardware accelerator block containing AES/DES/SHA/MD5 called SA2UL
> * Centralized System Controller for Security, Power, and Resource
>   management.
> * Dual ADCSS, eQEP/eCAP, eHRPWM, dual CAN-FD
> * Flash subystem with OSPI and Hyperbus interfaces
> * Multimedia capability with CAL, DSS7-UL, SGX544, McASP
> * Peripheral connectivity including USB3, PCIE, MMC/SD, GPMC, I2C, SPI,
>   GPIO
> 
> See AM65x Technical Reference Manual (SPRUID7, April 2018)
> for further details: http://www.ti.com/lit/pdf/spruid7
> 
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  Documentation/devicetree/bindings/arm/ti/k3.txt | 33 +++++++++++++++++++++++++
>  MAINTAINERS                                     |  7 ++++++
>  2 files changed, 40 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/ti/k3.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/ti/k3.txt b/Documentation/devicetree/bindings/arm/ti/k3.txt
> new file mode 100644
> index 000000000000..cbabb1b89f6f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/ti/k3.txt
> @@ -0,0 +1,33 @@
> +Texas Instruments K3 Multicore SoC architecture device tree bindings
> +--------------------------------------------------------------------
> +
> +Boards based on K3 Multicore SoC architecture shall have the following property:
> +- compatible: Every hardware block introduced in K3 Multicore SoC
> +  architecture shall be of the form:
> +  "ti,XXX-YYY", where:
> +     'XXX' represents the specific SoC part for which the support is added.
> +     'YYY' represents the corresponding peripheral in SoC being supported.

No need to explain standard DT convention here. (But I don't think we 
have this convention documented anywhere, so patches welcome. :))

> +
> +  NOTE: Generic devices such as GIC or legacy devices shall use the specified
> +  compatible for those devices.
> +
> +  Example:
> +    compatible = "ti,am654-i2c";
> +
> +SoCs
> +-------------------------------------------
> +
> +Each device tree root node must specify which exact SoC in K3 Multicore SoC
> +architecture it uses, using one of the following compatible values:
> +
> +- AM654
> +  compatible = "ti,am654";
> +
> +Boards
> +-------------------------------------------
> +
> +In addition, each device tree root node must specify which one or more
> +of the following board-specific compatible values:
> +
> +- AM654 EVM
> +  compatible = "ti,am654-evm", "ti,am654";
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f39a8de1bbd7..cfb35b252ac7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2086,6 +2086,13 @@ L:	linux-kernel@vger.kernel.org
>  S:	Maintained
>  F:	drivers/memory/*emif*
>  
> +ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE
> +M:	Tero Kristo <t-kristo@ti.com>
> +M:	Nishanth Menon <nm@ti.com>
> +L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> +S:	Supported
> +F:	Documentation/devicetree/bindings/arm/ti/k3.txt
> +
>  ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
>  M:	Santosh Shilimkar <ssantosh@kernel.org>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> -- 
> 2.15.1
> 

^ permalink raw reply

* Re: [PATCH v2] serial: imx: fix cached UCR2 read on software reset
From: Uwe Kleine-König @ 2018-06-12 12:28 UTC (permalink / raw)
  To: Stefan Agner; +Cc: gregkh, festevam, jslaby, linux-serial, linux-kernel
In-Reply-To: <afda793c86ba7394233e17813589b44c@agner.ch>

On Tue, Jun 12, 2018 at 02:11:44PM +0200, Stefan Agner wrote:
> On 07.06.2018 09:56, Uwe Kleine-König wrote:
> > On Fri, Apr 20, 2018 at 02:44:07PM +0200, Stefan Agner wrote:
> >> To reset the UART the SRST needs be cleared (low active). According
> >> to the documentation the bit will remain active for 4 module clocks
> >> until it is cleared (set to 1).
> >>
> >> Hence the real register need to be read in case the cached register
> >> indicates that the SRST bit is zero.
> >>
> >> This bug lead to wrong baudrate because the baud rate register got
> >> restored before reset completed in imx_flush_buffer.
> >>
> >> Fixes: 3a0ab62f43de ("serial: imx: implement shadow registers for UCRx and UFCR")
> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> >> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> >> Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > 
> > For the record, there is a customer of mine who reports that this commit
> > breaks rs485 communication on i.MX25 because RTS stops to toggle as
> > intended.
> > 
> > (Some details: uart3, fsl,uart-has-rtscts, fsl,dte-mode,
> > linux,rs485-enabled-at-boot-time, native RTS.)
> > 
> > I didn't debug this yet.
> 
> I have seen your patch today "serial: imx: fix comment about UCR2_SRST
> and its handling for shadowing" so I assume you looked into this issue?
> 
> Was it related to that change?

I started looking into this issue, but didn't find the culprit yet.

My work in progress patch looks as follows:

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 758a67f3c8b3..5270173721c6 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1357,6 +1357,12 @@ static int imx_uart_startup(struct uart_port *port)
 	while (!(imx_uart_readl(sport, UCR2) & UCR2_SRST) && (--i > 0))
 		udelay(1);
 
+	if (imx_uart_readl(sport, UCR2) & UCR2_SRST) {
+		spin_unlock_irqrestore(&sport->port.lock, flags);
+		dev_warn(port->dev, "SRST didn't go away\n");
+		return -EIO;
+	}
+
 	/*
 	 * Finally, clear and enable interrupts
 	 */

which seems to trigger on both i.MX25 and i.MX6 at least occasionally.

Maybe 100 us is too short?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply related

* Re: [PATCH v2] serial: imx: fix cached UCR2 read on software reset
From: Stefan Agner @ 2018-06-12 12:11 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: gregkh, festevam, jslaby, linux-serial, linux-kernel
In-Reply-To: <20180607075633.y3tm245jv7nkdrqx@pengutronix.de>

On 07.06.2018 09:56, Uwe Kleine-König wrote:
> On Fri, Apr 20, 2018 at 02:44:07PM +0200, Stefan Agner wrote:
>> To reset the UART the SRST needs be cleared (low active). According
>> to the documentation the bit will remain active for 4 module clocks
>> until it is cleared (set to 1).
>>
>> Hence the real register need to be read in case the cached register
>> indicates that the SRST bit is zero.
>>
>> This bug lead to wrong baudrate because the baud rate register got
>> restored before reset completed in imx_flush_buffer.
>>
>> Fixes: 3a0ab62f43de ("serial: imx: implement shadow registers for UCRx and UFCR")
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
>> Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> 
> For the record, there is a customer of mine who reports that this commit
> breaks rs485 communication on i.MX25 because RTS stops to toggle as
> intended.
> 
> (Some details: uart3, fsl,uart-has-rtscts, fsl,dte-mode,
> linux,rs485-enabled-at-boot-time, native RTS.)
> 
> I didn't debug this yet.

I have seen your patch today "serial: imx: fix comment about UCR2_SRST
and its handling for shadowing" so I assume you looked into this issue?

Was it related to that change?

--
Stefan

^ permalink raw reply

* Re: [PATCH 3/7] MIPS: intel: Add initial support for Intel MIPS SoCs
From: James Hogan @ 2018-06-12 11:23 UTC (permalink / raw)
  To: Songjun Wu
  Cc: hua.ma, yixin.zhu, chuanhua.lei, linux-mips, qi-ming.wu,
	linux-clk, linux-serial, devicetree, linux-kernel, Rob Herring,
	Ralf Baechle, Mark Rutland
In-Reply-To: <20180612054034.4969-4-songjun.wu@linux.intel.com>

[-- Attachment #1: Type: text/plain, Size: 8818 bytes --]

Hi,

Good to see this patch!

On Tue, Jun 12, 2018 at 01:40:30PM +0800, Songjun Wu wrote:
> diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
> index ac7ad54f984f..bcd647060f3e 100644
> --- a/arch/mips/Kbuild.platforms
> +++ b/arch/mips/Kbuild.platforms
> @@ -12,6 +12,7 @@ platforms += cobalt
>  platforms += dec
>  platforms += emma
>  platforms += generic
> +platforms += intel-mips

What are the main things preventing this from moving to the generic
platform? Is it mainly the use of EVA (which generic doesn't yet
support)?

> diff --git a/arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h b/arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h
> new file mode 100644
> index 000000000000..3893855b60c6
> --- /dev/null
> +++ b/arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h
...
> +	/*
> +	 * Get Config.K0 value and use it to program
> +	 * the segmentation registers

Please can you describe (maybe with a table) the segment layout in human
readable terms so the reader doesn't need to decode the SegCtl registers
to understand where everything is in the virtual address space?

> diff --git a/arch/mips/boot/dts/intel-mips/Makefile b/arch/mips/boot/dts/intel-mips/Makefile
> new file mode 100644
> index 000000000000..b16c0081639c
> --- /dev/null
> +++ b/arch/mips/boot/dts/intel-mips/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_DTB_INTEL_MIPS_GRX500)	+= easy350_anywan.dtb
> +obj-y	+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))

This needs updating to obj-$(CONFIG_BUILTIN_DTB) as per commit
fca3aa166422 ("MIPS: dts: Avoid unneeded built-in.a in DTS dirs") in
linux-next.

> diff --git a/arch/mips/intel-mips/Makefile b/arch/mips/intel-mips/Makefile
> new file mode 100644
> index 000000000000..9f272d06eecd
> --- /dev/null
> +++ b/arch/mips/intel-mips/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_INTEL_MIPS)	+= prom.o irq.o time.o

You can use obj-y, since this Makefile is only included if
CONFIG_INTEL_MIPS=y (i.e. via the platform-$(CONFIG_INTEL_MIPS) below).

Also please split each file onto separate "obj-y += whatever.o" lines.

> diff --git a/arch/mips/intel-mips/Platform b/arch/mips/intel-mips/Platform
> new file mode 100644
> index 000000000000..b34750eeaeb0
> --- /dev/null
> +++ b/arch/mips/intel-mips/Platform
> @@ -0,0 +1,11 @@
> +#
> +# MIPs SoC platform
> +#
> +
> +platform-$(CONFIG_INTEL_MIPS)			+= intel-mips/

^^^ (this is what ensures the Makefile is only included for this
platform)

> diff --git a/arch/mips/intel-mips/irq.c b/arch/mips/intel-mips/irq.c
> new file mode 100644
> index 000000000000..00637a5cdd20
> --- /dev/null
> +++ b/arch/mips/intel-mips/irq.c
> @@ -0,0 +1,36 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2016 Intel Corporation.
> + */
> +#include <linux/init.h>
> +#include <linux/irqchip.h>
> +#include <linux/of_irq.h>
> +#include <asm/irq.h>
> +
> +#include <asm/irq_cpu.h>
> +
> +void __init arch_init_irq(void)
> +{
> +	struct device_node *intc_node;
> +
> +	pr_info("EIC is %s\n", cpu_has_veic ? "on" : "off");
> +	pr_info("VINT is %s\n", cpu_has_vint ? "on" : "off");
> +
> +	intc_node = of_find_compatible_node(NULL, NULL,
> +					    "mti,cpu-interrupt-controller");
> +	if (!cpu_has_veic && !intc_node)
> +		mips_cpu_irq_init();
> +
> +	irqchip_init();
> +}
> +
> +int get_c0_perfcount_int(void)
> +{
> +	return gic_get_c0_perfcount_int();
> +}
> +EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
> +
> +unsigned int get_c0_compare_int(void)
> +{
> +	return gic_get_c0_compare_int();
> +}

Worth having get_c0_fdc_int() too for the "Fast Debug Channel"?

> diff --git a/arch/mips/intel-mips/prom.c b/arch/mips/intel-mips/prom.c
> new file mode 100644
> index 000000000000..9407858ddc94
> --- /dev/null
> +++ b/arch/mips/intel-mips/prom.c
> @@ -0,0 +1,184 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2014 Lei Chuanhua <Chuanhua.lei@lantiq.com>
> + * Copyright (C) 2016 Intel Corporation.
> + */
> +#include <linux/init.h>
> +#include <linux/export.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_fdt.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <asm/mips-cps.h>
> +#include <asm/smp-ops.h>
> +#include <asm/dma-coherence.h>
> +#include <asm/prom.h>
> +
> +#define IOPORT_RESOURCE_START   0x10000000
> +#define IOPORT_RESOURCE_END     0xffffffff
> +#define IOMEM_RESOURCE_START    0x10000000
> +#define IOMEM_RESOURCE_END      0xffffffff

The _END ones seem to be unused?

> +static void __init prom_init_cmdline(void)
> +{
> +	int i;
> +	int argc;
> +	char **argv;
> +
> +	/*
> +	 * If u-boot pass parameters, it is ok, however, if without u-boot
> +	 * JTAG or other tool has to reset all register value before it goes
> +	 * emulation most likely belongs to this category
> +	 */
> +	if (fw_arg0 == 0 || fw_arg1 == 0)
> +		return;
> +
> +	argc = fw_arg0;
> +	argv = (char **)KSEG1ADDR(fw_arg1);
> +
> +	arcs_cmdline[0] = '\0';
> +
> +	for (i = 0; i < argc; i++) {
> +		char *p = (char *)KSEG1ADDR(argv[i]);
> +
> +		if (argv[i] && *p) {
> +			strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
> +			strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
> +		}
> +	}

Please describe the boot register protocol in the commit message and/or
a comment in this function.

Is it compatible with the UHI boot protocol, such that this could
potentially be converted to use the generic platform in future?

> +}
> +
> +static int __init plat_enable_iocoherency(void)
> +{
> +	int supported = 0;
> +
> +	if (mips_cps_numiocu(0) != 0) {
> +		/* Nothing special needs to be done to enable coherency */
> +		pr_info("Coherence Manager IOCU detected\n");
> +		/* Second IOCU for MPE or other master access register */
> +		write_gcr_reg0_base(0xa0000000);
> +		write_gcr_reg0_mask(0xf8000000 | CM_GCR_REGn_MASK_CMTGT_IOCU1);
> +		supported = 1;
> +	}
> +
> +	/* hw_coherentio = supported; */
> +
> +	return supported;
> +}
> +
> +static void __init plat_setup_iocoherency(void)
> +{
> +#ifdef CONFIG_DMA_NONCOHERENT
> +	/*
> +	 * Kernel has been configured with software coherency
> +	 * but we might choose to turn it off and use hardware
> +	 * coherency instead.

That sounds a big risky. Software coherency will I think perform cache
line invalidation when syncing buffers from device to CPU (see
__dma_sync_virtual), so that the underlying RAM written by the
supposedly incoherent DMA is visible. If its coherent afterall then it
may be sat in a dirty line in the cache, and not have been written back
to RAM yet before it gets invalidated?

> +	 */
> +	if (plat_enable_iocoherency()) {
> +		if (coherentio == IO_COHERENCE_DISABLED)
> +			pr_info("Hardware DMA cache coherency disabled\n");
> +		else
> +			pr_info("Hardware DMA cache coherency enabled\n");
> +	} else {
> +		if (coherentio == IO_COHERENCE_ENABLED)
> +			pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n");
> +		else
> +			pr_info("Software DMA cache coherency enabled\n");
> +	}
> +#else
> +	if (!plat_enable_iocoherency())
> +		panic("Hardware DMA cache coherency not supported!");
> +#endif
> +}


> +void __init device_tree_init(void)
> +{
> +	if (!initial_boot_params)
> +		return;

Redundant check. unflatten_and_copy_device_tree() now handles that and
emits a message.

> +
> +	unflatten_and_copy_device_tree();
> +}
> +
> +#define CPC_BASE_ADDR		0x12310000

Please put this at the top of the file with other #defines.

> +
> +phys_addr_t mips_cpc_default_phys_base(void)
> +{
> +	return CPC_BASE_ADDR;
> +}

> diff --git a/arch/mips/intel-mips/time.c b/arch/mips/intel-mips/time.c
> new file mode 100644
> index 000000000000..77ad4014fe9d
> --- /dev/null
> +++ b/arch/mips/intel-mips/time.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2016 Intel Corporation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
> +#include <linux/of.h>
> +
> +#include <asm/time.h>
> +
> +static inline u32 get_counter_resolution(void)
> +{
> +	u32 res;
> +
> +	__asm__ __volatile__(".set	push\n"

Preferably each line of asm should end \n\t and the final line doesn't
need \n or \t. Look at the .s compiler output to see the difference.

> +			     ".set	mips32r2\n"
> +			     "rdhwr	%0, $3\n"

Hmm, it'd be nice to abstract this in mipsregs.h, but that can always
wait. You could use MIPS_HWR_CCRES though (i.e. off top of my head
something like "%0, $%1\n" and have a "i" (MIPS_HWR_CCRES) input.

> +			     ".set pop\n"
> +			     : "=&r" (res)

I don't think you strictly need an early clobber there since there are
no register inputs, "=r" should do fine.

> +			     : /* no input */
> +			     : "memory");

I don't think that operation clobbers any memory?

Thanks
James

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox