Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/6] dts: bindings: Document device tree binding for CATU
From: Suzuki K Poulose @ 2018-06-18 10:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529319379-17895-1-git-send-email-suzuki.poulose@arm.com>

Document CATU device-tree bindings. CATU augments the TMC-ETR
by providing an improved Scatter Gather mechanism for streaming
trace data to non-contiguous system RAM pages.

Cc: devicetree at vger.kernel.org
Cc: frowand.list at gmail.com
Cc: Rob Herring <robh@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 .../devicetree/bindings/arm/coresight.txt          | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index 9aa30a1..5d1ad09 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -39,6 +39,8 @@ its hardware characteristcs.
 
 		- System Trace Macrocell:
 			"arm,coresight-stm", "arm,primecell"; [1]
+		- Coresight Address Translation Unit (CATU)
+			"arm,coresight-catu", "arm,primecell";
 
 	* reg: physical base address and length of the register
 	  set(s) of the component.
@@ -90,6 +92,10 @@ its hardware characteristcs.
 	* arm,scatter-gather: boolean. Indicates that the TMC-ETR can safely
 	  use the SG mode on this system.
 
+* Optional property for CATU :
+	* interrupts : Exactly one SPI may be listed for reporting the address
+	  error
+
 Example:
 
 1. Sinks
@@ -121,6 +127,35 @@ Example:
 		};
 	};
 
+	etr at 20070000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0 0x20070000 0 0x1000>;
+
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* input port */
+			port at 0 {
+				reg =  <0>;
+				etr_in_port: endpoint {
+					slave-mode;
+					remote-endpoint = <&replicator2_out_port0>;
+				};
+			};
+
+			/* CATU link represented by output port */
+			port at 1 {
+				reg = <1>;
+				etr_out_port: endpoint {
+					remote-endpoint = <&catu_in_port>;
+				};
+			};
+		};
+	};
+
 2. Links
 	replicator {
 		/* non-configurable replicators don't show up on the
@@ -250,5 +285,23 @@ Example:
 		};
 	};
 
+5. CATU
+
+	catu at 207e0000 {
+		compatible = "arm,coresight-catu", "arm,primecell";
+		reg = <0 0x207e0000 0 0x1000>;
+
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+
+		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+		port {
+			catu_in_port: endpoint {
+				slave-mode;
+				remote-endpoint = <&etr_out_port>;
+			};
+		};
+	};
+
 [1]. There is currently two version of STM: STM32 and STM500.  Both
 have the same HW interface and as such don't need an explicit binding name.
-- 
2.7.4

^ permalink raw reply related

* [PATCH 5/6] coresight: catu: Add support for scatter gather tables
From: Suzuki K Poulose @ 2018-06-18 10:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529319379-17895-1-git-send-email-suzuki.poulose@arm.com>

This patch adds the support for setting up a SG table for use
by the CATU. We reuse the tmc_sg_table to represent the table/data
pages, even though the table format is different.

Similar to ETR SG table, CATU uses a 4KB page size for data buffers
as well as page tables. All table entries are 64bit wide and have
the following format:

        63                      12      1  0
        x-----------------------------------x
        |        Address [63-12] | SBZ  | V |
        x-----------------------------------x

	Where [V] ->	 0 - Pointer is invalid
			 1 - Pointer is Valid

CATU uses only first half of the page for data page pointers.
i.e, single table page will only have 256 page pointers, addressing
upto 1MB of data. The second half of a table page contains only two
pointers at the end of the page (i.e, pointers at index 510 and 511),
which are used as links to the "Previous" and "Next" page tables
respectively.

The first table page has an "Invalid" previous pointer and the
next pointer entry points to the second page table if there is one.
Similarly the last table page has an "Invalid" next pointer to
indicate the end of the table chain.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/coresight-catu.c | 249 +++++++++++++++++++++++++++
 1 file changed, 249 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 11c84cb..95064c3 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -16,10 +16,259 @@
 
 #include "coresight-catu.h"
 #include "coresight-priv.h"
+#include "coresight-tmc.h"
 
 #define csdev_to_catu_drvdata(csdev)	\
 	dev_get_drvdata(csdev->dev.parent)
 
+/* Verbose output for CATU table contents */
+#ifdef CATU_DEBUG
+#define catu_dbg(x, ...) dev_dbg(x, __VA_ARGS__)
+#else
+#define catu_dbg(x, ...) do {} while (0)
+#endif
+
+/*
+ * CATU uses a page size of 4KB for page tables as well as data pages.
+ * Each 64bit entry in the table has the following format.
+ *
+ *	63			12	1  0
+ *	------------------------------------
+ *	|	 Address [63-12] | SBZ	| V|
+ *	------------------------------------
+ *
+ * Where bit[0] V indicates if the address is valid or not.
+ * Each 4K table pages have upto 256 data page pointers, taking upto 2K
+ * size. There are two Link pointers, pointing to the previous and next
+ * table pages respectively at the end of the 4K page. (i.e, entry 510
+ * and 511).
+ *  E.g, a table of two pages could look like :
+ *
+ *                 Table Page 0               Table Page 1
+ * SLADDR ===> x------------------x  x--> x-----------------x
+ * INADDR    ->|  Page 0      | V |  |    | Page 256    | V | <- INADDR+1M
+ *             |------------------|  |    |-----------------|
+ * INADDR+4K ->|  Page 1      | V |  |    |                 |
+ *             |------------------|  |    |-----------------|
+ *             |  Page 2      | V |  |    |                 |
+ *             |------------------|  |    |-----------------|
+ *             |   ...        | V |  |    |    ...          |
+ *             |------------------|  |    |-----------------|
+ * INADDR+1020K|  Page 255    | V |  |    |   Page 511  | V |
+ * SLADDR+2K==>|------------------|  |    |-----------------|
+ *             |  UNUSED      |   |  |    |                 |
+ *             |------------------|  |    |                 |
+ *             |  UNUSED      |   |  |    |                 |
+ *             |------------------|  |    |                 |
+ *             |    ...       |   |  |    |                 |
+ *             |------------------|  |    |-----------------|
+ *             |   IGNORED    | 0 |  |    | Table Page 0| 1 |
+ *             |------------------|  |    |-----------------|
+ *             |  Table Page 1| 1 |--x    | IGNORED     | 0 |
+ *             x------------------x       x-----------------x
+ * SLADDR+4K==>
+ *
+ * The base input address (used by the ETR, programmed in INADDR_{LO,HI})
+ * must be aligned to 1MB (the size addressable by a single page table).
+ * The CATU maps INADDR{LO:HI} to the first page in the table pointed
+ * to by SLADDR{LO:HI} and so on.
+ *
+ */
+typedef u64 cate_t;
+
+#define CATU_PAGE_SHIFT		12
+#define CATU_PAGE_SIZE		(1UL << CATU_PAGE_SHIFT)
+#define CATU_PAGES_PER_SYSPAGE	(PAGE_SIZE / CATU_PAGE_SIZE)
+
+/* Page pointers are only allocated in the first 2K half */
+#define CATU_PTRS_PER_PAGE	((CATU_PAGE_SIZE >> 1) / sizeof(cate_t))
+#define CATU_PTRS_PER_SYSPAGE	(CATU_PAGES_PER_SYSPAGE * CATU_PTRS_PER_PAGE)
+#define CATU_LINK_PREV		((CATU_PAGE_SIZE / sizeof(cate_t)) - 2)
+#define CATU_LINK_NEXT		((CATU_PAGE_SIZE / sizeof(cate_t)) - 1)
+
+#define CATU_ADDR_SHIFT		12
+#define CATU_ADDR_MASK		~(((cate_t)1 << CATU_ADDR_SHIFT) - 1)
+#define CATU_ENTRY_VALID	((cate_t)0x1)
+#define CATU_VALID_ENTRY(addr) \
+	(((cate_t)(addr) & CATU_ADDR_MASK) | CATU_ENTRY_VALID)
+#define CATU_ENTRY_ADDR(entry)	((cate_t)(entry) & ~((cate_t)CATU_ENTRY_VALID))
+
+/*
+ * catu_get_table : Retrieve the table pointers for the given @offset
+ * within the buffer. The buffer is wrapped around to a valid offset.
+ *
+ * Returns : The CPU virtual address for the beginning of the table
+ * containing the data page pointer for @offset. If @daddrp is not NULL,
+ * @daddrp points the DMA address of the beginning of the table.
+ */
+static inline cate_t *catu_get_table(struct tmc_sg_table *catu_table,
+				     unsigned long offset,
+				     dma_addr_t *daddrp)
+{
+	unsigned long buf_size = tmc_sg_table_buf_size(catu_table);
+	unsigned int table_nr, pg_idx, pg_offset;
+	struct tmc_pages *table_pages = &catu_table->table_pages;
+	void *ptr;
+
+	/* Make sure offset is within the range */
+	offset %= buf_size;
+
+	/*
+	 * Each table can address 1MB and a single kernel page can
+	 * contain "CATU_PAGES_PER_SYSPAGE" CATU tables.
+	 */
+	table_nr = offset >> 20;
+	/* Find the table page where the table_nr lies in */
+	pg_idx = table_nr / CATU_PAGES_PER_SYSPAGE;
+	pg_offset = (table_nr % CATU_PAGES_PER_SYSPAGE) * CATU_PAGE_SIZE;
+	if (daddrp)
+		*daddrp = table_pages->daddrs[pg_idx] + pg_offset;
+	ptr = page_address(table_pages->pages[pg_idx]);
+	return (cate_t *)((unsigned long)ptr + pg_offset);
+}
+
+#ifdef CATU_DEBUG
+static void catu_dump_table(struct tmc_sg_table *catu_table)
+{
+	int i;
+	cate_t *table;
+	unsigned long table_end, buf_size, offset = 0;
+
+	buf_size = tmc_sg_table_buf_size(catu_table);
+	dev_dbg(catu_table->dev,
+		"Dump table %p, tdaddr: %llx\n",
+		catu_table, catu_table->table_daddr);
+
+	while (offset < buf_size) {
+		table_end = offset + SZ_1M < buf_size ?
+			    offset + SZ_1M : buf_size;
+		table = catu_get_table(catu_table, offset, NULL);
+		for (i = 0; offset < table_end; i++, offset += CATU_PAGE_SIZE)
+			dev_dbg(catu_table->dev, "%d: %llx\n", i, table[i]);
+		dev_dbg(catu_table->dev, "Prev : %llx, Next: %llx\n",
+			table[CATU_LINK_PREV], table[CATU_LINK_NEXT]);
+		dev_dbg(catu_table->dev, "== End of sub-table ===");
+	}
+	dev_dbg(catu_table->dev, "== End of Table ===");
+}
+
+#else
+static inline void catu_dump_table(struct tmc_sg_table *catu_table)
+{
+}
+#endif
+
+static inline cate_t catu_make_entry(dma_addr_t addr)
+{
+	return addr ? CATU_VALID_ENTRY(addr) : 0;
+}
+
+/*
+ * catu_populate_table : Populate the given CATU table.
+ * The table is always populated as a circular table.
+ * i.e, the "prev" link of the "first" table points to the "last"
+ * table and the "next" link of the "last" table points to the
+ * "first" table. The buffer should be made linear by calling
+ * catu_set_table().
+ */
+static void
+catu_populate_table(struct tmc_sg_table *catu_table)
+{
+	int i, dpidx, s_dpidx;
+	unsigned long offset, buf_size, last_offset;
+	dma_addr_t data_daddr;
+	dma_addr_t prev_taddr, next_taddr, cur_taddr;
+	cate_t *table_ptr, *next_table;
+
+	buf_size = tmc_sg_table_buf_size(catu_table);
+	dpidx = s_dpidx = 0;
+	offset = 0;
+
+	table_ptr = catu_get_table(catu_table, 0, &cur_taddr);
+	prev_taddr = 0;	/* Prev link for the first table */
+
+	while (offset < buf_size) {
+		/*
+		 * The @offset is always 1M aligned here and we have an
+		 * empty table @table_ptr to fill. Each table can address
+		 * upto 1MB data buffer. The last table may have fewer
+		 * entries if the buffer size is not aligned.
+		 */
+		last_offset = (offset + SZ_1M) < buf_size ?
+			      (offset + SZ_1M) : buf_size;
+		for (i = 0; offset < last_offset;
+		     i++, offset += CATU_PAGE_SIZE) {
+
+			data_daddr = catu_table->data_pages.daddrs[dpidx] +
+				     s_dpidx * CATU_PAGE_SIZE;
+			catu_dbg(catu_table->dev,
+				"[table %5ld:%03d] 0x%llx\n",
+				(offset >> 20), i, data_daddr);
+			table_ptr[i] = catu_make_entry(data_daddr);
+			/* Move the pointers for data pages */
+			s_dpidx = (s_dpidx + 1) % CATU_PAGES_PER_SYSPAGE;
+			if (s_dpidx == 0)
+				dpidx++;
+		}
+
+		/*
+		 * If we have finished all the valid entries, fill the rest of
+		 * the table (i.e, last table page) with invalid entries,
+		 * to fail the lookups.
+		 */
+		if (offset == buf_size) {
+			memset(&table_ptr[i], 0,
+			       sizeof(cate_t) * (CATU_PTRS_PER_PAGE - i));
+			next_taddr = 0;
+		} else {
+			next_table = catu_get_table(catu_table,
+						    offset, &next_taddr);
+		}
+
+		table_ptr[CATU_LINK_PREV] = catu_make_entry(prev_taddr);
+		table_ptr[CATU_LINK_NEXT] = catu_make_entry(next_taddr);
+
+		catu_dbg(catu_table->dev,
+			"[table%5ld]: Cur: 0x%llx Prev: 0x%llx, Next: 0x%llx\n",
+			(offset >> 20) - 1,  cur_taddr, prev_taddr, next_taddr);
+
+		/* Update the prev/next addresses */
+		if (next_taddr) {
+			prev_taddr = cur_taddr;
+			cur_taddr = next_taddr;
+			table_ptr = next_table;
+		}
+	}
+
+	/* Sync the table for device */
+	tmc_sg_table_sync_table(catu_table);
+}
+
+static struct tmc_sg_table __maybe_unused *
+catu_init_sg_table(struct device *catu_dev, int node,
+		   ssize_t size, void **pages)
+{
+	int nr_tpages;
+	struct tmc_sg_table *catu_table;
+
+	/*
+	 * Each table can address upto 1MB and we can have
+	 * CATU_PAGES_PER_SYSPAGE tables in a system page.
+	 */
+	nr_tpages = DIV_ROUND_UP(size, SZ_1M) / CATU_PAGES_PER_SYSPAGE;
+	catu_table = tmc_alloc_sg_table(catu_dev, node, nr_tpages,
+					size >> PAGE_SHIFT, pages);
+	if (IS_ERR(catu_table))
+		return catu_table;
+
+	catu_populate_table(catu_table);
+	dev_dbg(catu_dev,
+		"Setup table %p, size %ldKB, %d table pages\n",
+		catu_table, (unsigned long)size >> 10,  nr_tpages);
+	catu_dump_table(catu_table);
+	return catu_table;
+}
+
 coresight_simple_reg32(struct catu_drvdata, devid, CORESIGHT_DEVID);
 coresight_simple_reg32(struct catu_drvdata, control, CATU_CONTROL);
 coresight_simple_reg32(struct catu_drvdata, status, CATU_STATUS);
-- 
2.7.4

^ permalink raw reply related

* [PATCH 6/6] coresight: catu: Plug in CATU as a backend for ETR buffer
From: Suzuki K Poulose @ 2018-06-18 10:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529319379-17895-1-git-send-email-suzuki.poulose@arm.com>

Now that we can use a CATU with a scatter gather table, add support
for the TMC ETR to make use of the connected CATU in translate mode.
This is done by adding CATU as new buffer mode.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/coresight-catu.c    | 122 +++++++++++++++++++++++-
 drivers/hwtracing/coresight/coresight-catu.h    |  35 +++++++
 drivers/hwtracing/coresight/coresight-tmc-etr.c |  25 +++--
 drivers/hwtracing/coresight/coresight-tmc.h     |   3 +
 4 files changed, 174 insertions(+), 11 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 95064c3..87d28cb 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -28,6 +28,11 @@
 #define catu_dbg(x, ...) do {} while (0)
 #endif
 
+struct catu_etr_buf {
+	struct tmc_sg_table *catu_table;
+	dma_addr_t sladdr;
+};
+
 /*
  * CATU uses a page size of 4KB for page tables as well as data pages.
  * Each 64bit entry in the table has the following format.
@@ -93,6 +98,9 @@ typedef u64 cate_t;
 	(((cate_t)(addr) & CATU_ADDR_MASK) | CATU_ENTRY_VALID)
 #define CATU_ENTRY_ADDR(entry)	((cate_t)(entry) & ~((cate_t)CATU_ENTRY_VALID))
 
+/* CATU expects the INADDR to be aligned to 1M. */
+#define CATU_DEFAULT_INADDR	(1ULL << 20)
+
 /*
  * catu_get_table : Retrieve the table pointers for the given @offset
  * within the buffer. The buffer is wrapped around to a valid offset.
@@ -244,7 +252,7 @@ catu_populate_table(struct tmc_sg_table *catu_table)
 	tmc_sg_table_sync_table(catu_table);
 }
 
-static struct tmc_sg_table __maybe_unused *
+static struct tmc_sg_table *
 catu_init_sg_table(struct device *catu_dev, int node,
 		   ssize_t size, void **pages)
 {
@@ -269,6 +277,91 @@ catu_init_sg_table(struct device *catu_dev, int node,
 	return catu_table;
 }
 
+static void catu_free_etr_buf(struct etr_buf *etr_buf)
+{
+	struct catu_etr_buf *catu_buf;
+
+	if (!etr_buf || etr_buf->mode != ETR_MODE_CATU || !etr_buf->private)
+		return;
+
+	catu_buf = etr_buf->private;
+	tmc_free_sg_table(catu_buf->catu_table);
+	kfree(catu_buf);
+}
+
+static ssize_t catu_get_data_etr_buf(struct etr_buf *etr_buf, u64 offset,
+				     size_t len, char **bufpp)
+{
+	struct catu_etr_buf *catu_buf = etr_buf->private;
+
+	return tmc_sg_table_get_data(catu_buf->catu_table, offset, len, bufpp);
+}
+
+static void catu_sync_etr_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp)
+{
+	struct catu_etr_buf *catu_buf = etr_buf->private;
+	struct tmc_sg_table *catu_table = catu_buf->catu_table;
+	u64 r_offset, w_offset;
+
+	/*
+	 * ETR started off at etr_buf->hwaddr. Convert the RRP/RWP to
+	 * offsets within the trace buffer.
+	 */
+	r_offset = rrp - etr_buf->hwaddr;
+	w_offset = rwp - etr_buf->hwaddr;
+
+	if (!etr_buf->full) {
+		etr_buf->len = w_offset - r_offset;
+		if (w_offset < r_offset)
+			etr_buf->len += etr_buf->size;
+	} else {
+		etr_buf->len = etr_buf->size;
+	}
+
+	etr_buf->offset = r_offset;
+	tmc_sg_table_sync_data_range(catu_table, r_offset, etr_buf->len);
+}
+
+static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata,
+			      struct etr_buf *etr_buf, int node, void **pages)
+{
+	struct coresight_device *csdev;
+	struct device *catu_dev;
+	struct tmc_sg_table *catu_table;
+	struct catu_etr_buf *catu_buf;
+
+	csdev = tmc_etr_get_catu_device(tmc_drvdata);
+	if (!csdev)
+		return -ENODEV;
+	catu_dev = csdev->dev.parent;
+	catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL);
+	if (!catu_buf)
+		return -ENOMEM;
+
+	catu_table = catu_init_sg_table(catu_dev, node, etr_buf->size, pages);
+	if (IS_ERR(catu_table)) {
+		kfree(catu_buf);
+		return PTR_ERR(catu_table);
+	}
+
+	etr_buf->mode = ETR_MODE_CATU;
+	etr_buf->private = catu_buf;
+	etr_buf->hwaddr = CATU_DEFAULT_INADDR;
+
+	catu_buf->catu_table = catu_table;
+	/* Get the table base address */
+	catu_buf->sladdr = catu_table->table_daddr;
+
+	return 0;
+}
+
+const struct etr_buf_operations etr_catu_buf_ops = {
+	.alloc = catu_alloc_etr_buf,
+	.free = catu_free_etr_buf,
+	.sync = catu_sync_etr_buf,
+	.get_data = catu_get_data_etr_buf,
+};
+
 coresight_simple_reg32(struct catu_drvdata, devid, CORESIGHT_DEVID);
 coresight_simple_reg32(struct catu_drvdata, control, CATU_CONTROL);
 coresight_simple_reg32(struct catu_drvdata, status, CATU_STATUS);
@@ -309,9 +402,10 @@ static inline int catu_wait_for_ready(struct catu_drvdata *drvdata)
 				 CATU_STATUS, CATU_STATUS_READY, 1);
 }
 
-static int catu_enable_hw(struct catu_drvdata *drvdata, void *__unused)
+static int catu_enable_hw(struct catu_drvdata *drvdata, void *data)
 {
-	u32 control;
+	u32 control, mode;
+	struct etr_buf *etr_buf = data;
 
 	if (catu_wait_for_ready(drvdata))
 		dev_warn(drvdata->dev, "Timeout while waiting for READY\n");
@@ -323,9 +417,27 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, void *__unused)
 	}
 
 	control |= BIT(CATU_CONTROL_ENABLE);
-	catu_write_mode(drvdata, CATU_MODE_PASS_THROUGH);
+
+	if (etr_buf && etr_buf->mode == ETR_MODE_CATU) {
+		struct catu_etr_buf *catu_buf = etr_buf->private;
+
+		mode = CATU_MODE_TRANSLATE;
+		catu_write_axictrl(drvdata, CATU_OS_AXICTRL);
+		catu_write_sladdr(drvdata, catu_buf->sladdr);
+		catu_write_inaddr(drvdata, CATU_DEFAULT_INADDR);
+	} else {
+		mode = CATU_MODE_PASS_THROUGH;
+		catu_write_sladdr(drvdata, 0);
+		catu_write_inaddr(drvdata, 0);
+	}
+
+	catu_write_irqen(drvdata, 0);
+	catu_write_mode(drvdata, mode);
 	catu_write_control(drvdata, control);
-	dev_dbg(drvdata->dev, "Enabled in Pass through mode\n");
+	dev_dbg(drvdata->dev, "Enabled in %s mode\n",
+		(mode == CATU_MODE_PASS_THROUGH) ?
+		"Pass through" :
+		"Translate");
 	return 0;
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
index 05da33d..53f521c 100644
--- a/drivers/hwtracing/coresight/coresight-catu.h
+++ b/drivers/hwtracing/coresight/coresight-catu.h
@@ -27,6 +27,32 @@
 #define CATU_MODE_PASS_THROUGH	0U
 #define CATU_MODE_TRANSLATE	1U
 
+#define CATU_AXICTRL_ARCACHE_SHIFT	4
+#define CATU_AXICTRL_ARCACHE_MASK	0xf
+#define CATU_AXICTRL_ARPROT_MASK	0x3
+#define CATU_AXICTRL_ARCACHE(arcache)		\
+	(((arcache) & CATU_AXICTRL_ARCACHE_MASK) << CATU_AXICTRL_ARCACHE_SHIFT)
+
+#define CATU_AXICTRL_VAL(arcache, arprot)	\
+	(CATU_AXICTRL_ARCACHE(arcache) | ((arprot) & CATU_AXICTRL_ARPROT_MASK))
+
+#define AXI3_AxCACHE_WB_READ_ALLOC	0x7
+/*
+ * AXI - ARPROT bits:
+ * See AMBA AXI & ACE Protocol specification (ARM IHI 0022E)
+ * sectionA4.7 Access Permissions.
+ *
+ * Bit 0: 0 - Unprivileged access, 1 - Privileged access
+ * Bit 1: 0 - Secure access, 1 - Non-secure access.
+ * Bit 2: 0 - Data access, 1 - instruction access.
+ *
+ * CATU AXICTRL:ARPROT[2] is res0 as we always access data.
+ */
+#define CATU_OS_ARPROT			0x2
+
+#define CATU_OS_AXICTRL		\
+	CATU_AXICTRL_VAL(AXI3_AxCACHE_WB_READ_ALLOC, CATU_OS_ARPROT)
+
 #define CATU_STATUS_READY	8
 #define CATU_STATUS_ADRERR	0
 #define CATU_STATUS_AXIERR	4
@@ -67,6 +93,8 @@ catu_write_##name(struct catu_drvdata *drvdata, u64 val)		\
 
 CATU_REG32(control, CATU_CONTROL);
 CATU_REG32(mode, CATU_MODE);
+CATU_REG32(irqen, CATU_IRQEN);
+CATU_REG32(axictrl, CATU_AXICTRL);
 CATU_REG_PAIR(sladdr, CATU_SLADDRLO, CATU_SLADDRHI)
 CATU_REG_PAIR(inaddr, CATU_INADDRLO, CATU_INADDRHI)
 
@@ -82,4 +110,11 @@ static inline bool coresight_is_catu_device(struct coresight_device *csdev)
 	       subtype == CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
 }
 
+#ifdef CONFIG_CORESIGHT_CATU
+extern const struct etr_buf_operations etr_catu_buf_ops;
+#else
+/* Dummy declaration for the CATU ops */
+static const struct etr_buf_operations etr_catu_buf_ops;
+#endif
+
 #endif
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index e37923a..2eda5de 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -710,7 +710,7 @@ static const struct etr_buf_operations etr_sg_buf_ops = {
  * Returns	: coresight_device ptr for the CATU device if a CATU is found.
  *		: NULL otherwise.
  */
-static inline struct coresight_device *
+struct coresight_device *
 tmc_etr_get_catu_device(struct tmc_drvdata *drvdata)
 {
 	int i;
@@ -733,7 +733,7 @@ static inline void tmc_etr_enable_catu(struct tmc_drvdata *drvdata)
 	struct coresight_device *catu = tmc_etr_get_catu_device(drvdata);
 
 	if (catu && helper_ops(catu)->enable)
-		helper_ops(catu)->enable(catu, NULL);
+		helper_ops(catu)->enable(catu, drvdata->etr_buf);
 }
 
 static inline void tmc_etr_disable_catu(struct tmc_drvdata *drvdata)
@@ -741,12 +741,13 @@ static inline void tmc_etr_disable_catu(struct tmc_drvdata *drvdata)
 	struct coresight_device *catu = tmc_etr_get_catu_device(drvdata);
 
 	if (catu && helper_ops(catu)->disable)
-		helper_ops(catu)->disable(catu, NULL);
+		helper_ops(catu)->disable(catu, drvdata->etr_buf);
 }
 
 static const struct etr_buf_operations *etr_buf_ops[] = {
 	[ETR_MODE_FLAT] = &etr_flat_buf_ops,
 	[ETR_MODE_ETR_SG] = &etr_sg_buf_ops,
+	[ETR_MODE_CATU] = &etr_catu_buf_ops,
 };
 
 static inline int tmc_etr_mode_alloc_buf(int mode,
@@ -754,12 +755,15 @@ static inline int tmc_etr_mode_alloc_buf(int mode,
 					 struct etr_buf *etr_buf, int node,
 					 void **pages)
 {
-	int rc;
+	int rc = -EINVAL;
 
 	switch (mode) {
 	case ETR_MODE_FLAT:
 	case ETR_MODE_ETR_SG:
-		rc = etr_buf_ops[mode]->alloc(drvdata, etr_buf, node, pages);
+	case ETR_MODE_CATU:
+		if (etr_buf_ops[mode]->alloc)
+			rc = etr_buf_ops[mode]->alloc(drvdata, etr_buf,
+						      node, pages);
 		if (!rc)
 			etr_buf->ops = etr_buf_ops[mode];
 		return rc;
@@ -782,10 +786,14 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata,
 {
 	int rc = -ENOMEM;
 	bool has_etr_sg, has_iommu;
+	bool has_sg, has_catu;
 	struct etr_buf *etr_buf;
 
 	has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG);
 	has_iommu = iommu_get_domain_for_dev(drvdata->dev);
+	has_catu = !!tmc_etr_get_catu_device(drvdata);
+
+	has_sg = has_catu || has_etr_sg;
 
 	etr_buf = kzalloc(sizeof(*etr_buf), GFP_KERNEL);
 	if (!etr_buf)
@@ -806,17 +814,22 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata,
 	 *
 	 */
 	if (!pages &&
-	    (!has_etr_sg || has_iommu || size < SZ_1M))
+	    (!has_sg || has_iommu || size < SZ_1M))
 		rc = tmc_etr_mode_alloc_buf(ETR_MODE_FLAT, drvdata,
 					    etr_buf, node, pages);
 	if (rc && has_etr_sg)
 		rc = tmc_etr_mode_alloc_buf(ETR_MODE_ETR_SG, drvdata,
 					    etr_buf, node, pages);
+	if (rc && has_catu)
+		rc = tmc_etr_mode_alloc_buf(ETR_MODE_CATU, drvdata,
+					    etr_buf, node, pages);
 	if (rc) {
 		kfree(etr_buf);
 		return ERR_PTR(rc);
 	}
 
+	dev_dbg(drvdata->dev, "allocated buffer of size %ldKB in mode %d\n",
+		(unsigned long)size >> 10, etr_buf->mode);
 	return etr_buf;
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index e745657..7027bd6 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -126,6 +126,7 @@ enum tmc_mem_intf_width {
 enum etr_mode {
 	ETR_MODE_FLAT,		/* Uses contiguous flat buffer */
 	ETR_MODE_ETR_SG,	/* Uses in-built TMC ETR SG mechanism */
+	ETR_MODE_CATU,		/* Use SG mechanism in CATU */
 };
 
 struct etr_buf_operations;
@@ -303,4 +304,6 @@ tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
 	return sg_table->data_pages.nr_pages << PAGE_SHIFT;
 }
 
+struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
+
 #endif
-- 
2.7.4

^ permalink raw reply related

* [PATCH 01/11] i2c: add helpers for locking the I2C segment
From: Wolfram Sang @ 2018-06-18 11:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-2-peda@axentia.se>


> +static inline void
> +i2c_lock_segment(struct i2c_adapter *adapter)
> +{
> +	i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
> +}
> +
> +static inline int
> +i2c_trylock_segment(struct i2c_adapter *adapter)
> +{
> +	return i2c_trylock_bus(adapter, I2C_LOCK_SEGMENT);
> +}
> +
> +static inline void
> +i2c_unlock_segment(struct i2c_adapter *adapter)
> +{
> +	i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
> +}

I wonder if i2c_lock_segment() and i2c_lock_root_adapter() are really
more readable and convenient than i2c_lock_bus() with the flag. I think
the flags have speaking names, too.

Is that an idea to remove these functions altogether and start using
i2c_lock_bus()?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180618/b15be943/attachment.sig>

^ permalink raw reply

* [PATCH v2 1/2] ARM: dts: imx6qdl-sabreauto: Add sensors
From: Fabio Estevam @ 2018-06-18 11:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1be8dc197f842d3be31a15315594a25c8ad8f298.1529309235.git.leonard.crestez@nxp.com>

On Mon, Jun 18, 2018 at 5:15 AM, Leonard Crestez
<leonard.crestez@nxp.com> wrote:
> The following sensors are on I2C3 on the baseboard:
> * isil,isl29023 light sensor
> * fsl,mag3110 magnetometer
> * fsl,mma8451 accelerometer
>
> Added under i2cmux/i2c at 1 because they're not otherwise accessible.
>
> These are all supported by iio with following configs:
> * CONFIG_SENSORS_ISL29018
> * CONFIG_MAG3110
> * CONFIG_MMA8452
>
> Tested with raw reads from iio sysfs.
>
> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply

* [PATCH 00/11] Split i2c_lock_adapter into i2c_lock_root and i2c_lock_segment
From: Wolfram Sang @ 2018-06-18 11:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>


> I suggest that Wolfram takes this series through the I2C tree
> and creates an immutable branch for the other subsystems. The

I'd prefer this, too. Are the other subsystem maintainers fine with
that?

I am very positive on the series. I just have one comment which I just
posted. It looks good in general.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180618/38e24c06/attachment.sig>

^ permalink raw reply

* [PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
From: Maciej Purski @ 2018-06-18 11:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <6047372.VZe6FOdiCA@avalon>


On 05/30/2018 02:36 PM, Laurent Pinchart wrote:
> Hi Maciej,
> 
> On Wednesday, 30 May 2018 15:15:58 EEST Maciej Purski wrote:
>> From: Andrzej Hajda <a.hajda@samsung.com>
>>
>> The patch adds bindings to Toshiba DSI/LVDS bridge TC358764.
>> Bindings describe power supplies, reset gpio and video interfaces.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Maciej Purski <m.purski@samsung.com>
>> ---
>>   .../bindings/display/bridge/toshiba,tc358764.txt   | 37 +++++++++++++++++++
>>   1 file changed, 37 insertions(+)
>>   create mode 100644
>> Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>>
>> diff --git
>> a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>> b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new
>> file mode 100644
>> index 0000000..6eda14f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>> @@ -0,0 +1,37 @@
>> +TC358764 MIPI-DSI to LVDS panel bridge
>> +
>> +Required properties:
>> +  - compatible: "toshiba,tc358764"
>> +  - reg: the virtual channel number of a DSI peripheral
>> +  - vddc-supply: core voltage supply, 1.2V
>> +  - vddio-supply: I/O voltage supply, 1.8V or 3.3V
>> +  - vddlvds-supply: LVDS1/2 voltage supply, 3.3V
>> +  - reset-gpios: a GPIO spec for the reset pin
>> +
>> +The device node can contain zero to two 'port' child nodes, each with one
>> +child 'endpoint' node, according to the bindings defined in [1].
>> +The following are properties specific to those nodes.
>> +
>> +port:
>> +  - reg: (required) can be 0 for DSI port or 1 for LVDS port;
>> +
>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> 
> Could you please take the comments I made on v1 into account when you'll post
> v3 ?
> 

For now I'm going to stick with the old convention and make port 0 optional,
when the bridge is a DSI child and LVDS port 1 mandatory.

The current policy does not seem to have been changed. There's a quiet new binding,
which follows the old convention:
Documentation/devicetree/bindings/connector/usb-connector.txt

If you can find an example of new bindings, which follow your convention and you
convince Rob, then I'll be completely okay with it and I'll change it the way
you propose.


>> +Example:
>> +
>> +	bridge at 0 {
>> +		reg = <0>;
>> +		compatible = "toshiba,tc358764";
>> +		vddc-supply = <&vcc_1v2_reg>;
>> +		vddio-supply = <&vcc_1v8_reg>;
>> +		vddlvds-supply = <&vcc_3v3_reg>;
>> +		reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +		port at 1 {
>> +			reg = <1>;
>> +			lvds_ep: endpoint {
>> +				remote-endpoint = <&panel_ep>;
>> +			};
>> +		};
>> +	};
> 
> 

Best regards,

Maciej Purski

^ permalink raw reply

* [PATCH 0/5]  Fixes coding style in xilinx_emaclite.c
From: Radhey Shyam Pandey @ 2018-06-18 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset fixes checkpatch and kernel-doc warnings in
xilinx emaclite driver. No functional change.

Radhey Shyam Pandey (5):
  net: emaclite: Use __func__ instead of hardcoded name
  net: emaclite: Balance braces in else statement
  net: emaclite: update kernel-doc comments
  net: emaclite: Fix block comments style
  net: emaclite: Remove unnecessary spaces

 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 101 +++++++++++++++-----------
 1 file changed, 58 insertions(+), 43 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH 1/5] net: emaclite: Use __func__ instead of hardcoded name
From: Radhey Shyam Pandey @ 2018-06-18 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529320103-7711-1-git-send-email-radhey.shyam.pandey@xilinx.com>

Switch hardcoded function name with a reference to __func__ making
the code more maintainable. Address below checkpatch warning:

WARNING: Prefer using '"%s...", __func__' to using 'xemaclite_mdio_read',
this function's name, in a string
+               "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n",

WARNING: Prefer using '"%s...", __func__' to using 'xemaclite_mdio_write',
this function's name, in a string
+               "xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n",

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 2a0c06e..0544134 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -757,7 +757,7 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
 	rc = xemaclite_readl(lp->base_addr + XEL_MDIORD_OFFSET);
 
 	dev_dbg(&lp->ndev->dev,
-		"xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n",
+		"%s(phy_id=%i, reg=%x) == %x\n", __func__,
 		phy_id, reg, rc);
 
 	return rc;
@@ -780,7 +780,7 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
 	u32 ctrl_reg;
 
 	dev_dbg(&lp->ndev->dev,
-		"xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+		"%s(phy_id=%i, reg=%x, val=%x)\n", __func__,
 		phy_id, reg, val);
 
 	if (xemaclite_mdio_wait(lp))
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/5] net: emaclite: Balance braces in else statement
From: Radhey Shyam Pandey @ 2018-06-18 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529320103-7711-1-git-send-email-radhey.shyam.pandey@xilinx.com>

Remove else as it is not required with if doing a return.
Fixes below checkpatch warning.

WARNING: else is not generally useful after a break or return

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 0544134..8d84f58 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -569,13 +569,11 @@ static void xemaclite_tx_handler(struct net_device *dev)
 					(u8 *) lp->deferred_skb->data,
 					lp->deferred_skb->len) != 0)
 			return;
-		else {
-			dev->stats.tx_bytes += lp->deferred_skb->len;
-			dev_kfree_skb_irq(lp->deferred_skb);
-			lp->deferred_skb = NULL;
-			netif_trans_update(dev); /* prevent tx timeout */
-			netif_wake_queue(dev);
-		}
+		dev->stats.tx_bytes += lp->deferred_skb->len;
+		dev_kfree_skb_irq(lp->deferred_skb);
+		lp->deferred_skb = NULL;
+		netif_trans_update(dev); /* prevent tx timeout */
+		netif_wake_queue(dev);
 	}
 }
 
@@ -1052,13 +1050,13 @@ static bool get_bool(struct platform_device *ofdev, const char *s)
 {
 	u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL);
 
-	if (p) {
+	if (p)
 		return (bool)*p;
-	} else {
-		dev_warn(&ofdev->dev, "Parameter %s not found,"
+
+	dev_warn(&ofdev->dev, "Parameter %s not found,"
 			"defaulting to false\n", s);
-		return false;
-	}
+
+	return false;
 }
 
 static const struct net_device_ops xemaclite_netdev_ops;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 3/5] net: emaclite: update kernel-doc comments
From: Radhey Shyam Pandey @ 2018-06-18 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529320103-7711-1-git-send-email-radhey.shyam.pandey@xilinx.com>

This patch fixes below kernel-doc warnings:

Function parameter or member 'maxlen' not described in 'xemaclite_recv_data'
Function parameter or member 'address'not described in 'xemaclite_set_mac_address'
Excess function parameter 'addr' description in 'xemaclite_set_mac_address'
No description found for return value of 'xemaclite_interrupt'
No description found for return value of 'xemaclite_mdio_write'
Function parameter or member 'dev' not described in 'xemaclite_mdio_setup'
Excess function parameter 'ofdev' description in 'xemaclite_mdio_setup'
No description found for return value of 'xemaclite_open'
No description found for return value of 'xemaclite_close'
Excess function parameter 'match' description in 'xemaclite_of_probe'

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 8d84f58..0b41cc5 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -369,6 +369,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
  * xemaclite_recv_data - Receive a frame
  * @drvdata:	Pointer to the Emaclite device private data
  * @data:	Address where the data is to be received
+ * @maxlen:    Maximum supported ethernet packet length
  *
  * This function is intended to be called from the interrupt context or
  * with a wrapper which waits for the receive frame to be available.
@@ -488,7 +489,7 @@ static void xemaclite_update_address(struct net_local *drvdata,
 /**
  * xemaclite_set_mac_address - Set the MAC address for this device
  * @dev:	Pointer to the network device instance
- * @addr:	Void pointer to the sockaddr structure
+ * @address:	Void pointer to the sockaddr structure
  *
  * This function copies the HW address from the sockaddr strucutre to the
  * net_device structure and updates the address in HW.
@@ -637,6 +638,8 @@ static void xemaclite_rx_handler(struct net_device *dev)
  * @dev_id:	Void pointer to the network device instance used as callback
  *		reference
  *
+ * Return:	IRQ_HANDLED
+ *
  * This function handles the Tx and Rx interrupts of the EmacLite device.
  */
 static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
@@ -770,6 +773,8 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
  *
  * This function waits till the device is ready to accept a new MDIO
  * request and then writes the val to the MDIO Write Data register.
+ *
+ * Return:      0 upon success or a negative error upon failure
  */
 static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
 				u16 val)
@@ -803,7 +808,7 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
 /**
  * xemaclite_mdio_setup - Register mii_bus for the Emaclite device
  * @lp:		Pointer to the Emaclite device private data
- * @ofdev:	Pointer to OF device structure
+ * @dev:	Pointer to OF device structure
  *
  * This function enables MDIO bus in the Emaclite device and registers a
  * mii_bus.
@@ -903,6 +908,9 @@ static void xemaclite_adjust_link(struct net_device *ndev)
  * This function sets the MAC address, requests an IRQ and enables interrupts
  * for the Emaclite device and starts the Tx queue.
  * It also connects to the phy device, if MDIO is included in Emaclite device.
+ *
+ * Return:	0 on success. -ENODEV, if PHY cannot be connected.
+ *		Non-zero error value on failure.
  */
 static int xemaclite_open(struct net_device *dev)
 {
@@ -973,6 +981,8 @@ static int xemaclite_open(struct net_device *dev)
  * This function stops the Tx queue, disables interrupts and frees the IRQ for
  * the Emaclite device.
  * It also disconnects the phy device associated with the Emaclite device.
+ *
+ * Return:	0, always.
  */
 static int xemaclite_close(struct net_device *dev)
 {
@@ -1064,7 +1074,6 @@ static const struct net_device_ops xemaclite_netdev_ops;
 /**
  * xemaclite_of_probe - Probe method for the Emaclite device.
  * @ofdev:	Pointer to OF device structure
- * @match:	Pointer to the structure used for matching a device
  *
  * This function probes for the Emaclite device in the device tree.
  * It initializes the driver data structure and the hardware, sets the MAC
-- 
2.7.4

^ permalink raw reply related

* [PATCH 4/5] net: emaclite: Fix block comments style
From: Radhey Shyam Pandey @ 2018-06-18 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529320103-7711-1-git-send-email-radhey.shyam.pandey@xilinx.com>

This patch fixes below checkpatch warnings-

WARNING: Block comments use a trailing */ on a separate line
WARNING: Block comments use * on subsequent lines
WARNING: networking block comments don't use an empty /* line,
use /* Comment

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 34 +++++++++++++++++----------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 0b41cc5..e8bb7b3 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -70,7 +70,8 @@
 #define XEL_TSR_XMIT_IE_MASK	 0x00000008	/* Tx interrupt enable bit */
 #define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000	/* Buffer is active, SW bit
 						 * only. This is not documented
-						 * in the HW spec */
+						 * in the HW spec
+						 */
 
 /* Define for programming the MAC address into the EmacLite */
 #define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
@@ -336,7 +337,8 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
 			drvdata->next_tx_buf_to_use ^= XEL_BUFFER_OFFSET;
 	} else if (drvdata->tx_ping_pong != 0) {
 		/* If the expected buffer is full, try the other buffer,
-		 * if it is configured in HW */
+		 * if it is configured in HW
+		 */
 
 		addr = (void __iomem __force *)((u32 __force)addr ^
 						 XEL_BUFFER_OFFSET);
@@ -357,7 +359,8 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
 	/* Update the Tx Status Register to indicate that there is a
 	 * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which
 	 * is used by the interrupt handler to check whether a frame
-	 * has been transmitted */
+	 * has been transmitted
+	 */
 	reg_data = xemaclite_readl(addr + XEL_TSR_OFFSET);
 	reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK);
 	xemaclite_writel(reg_data, addr + XEL_TSR_OFFSET);
@@ -395,7 +398,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
 		/* The instance is out of sync, try other buffer if other
 		 * buffer is configured, return 0 otherwise. If the instance is
 		 * out of sync, do not update the 'next_rx_buf_to_use' since it
-		 * will correct on subsequent calls */
+		 * will correct on subsequent calls
+		 */
 		if (drvdata->rx_ping_pong != 0)
 			addr = (void __iomem __force *)((u32 __force)addr ^
 							 XEL_BUFFER_OFFSET);
@@ -409,13 +413,15 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
 			return 0;	/* No data was available */
 	}
 
-	/* Get the protocol type of the ethernet frame that arrived */
+	/* Get the protocol type of the ethernet frame that arrived
+	 */
 	proto_type = ((ntohl(xemaclite_readl(addr + XEL_HEADER_OFFSET +
 			XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
 			XEL_RPLR_LENGTH_MASK);
 
 	/* Check if received ethernet frame is a raw ethernet frame
-	 * or an IP packet or an ARP packet */
+	 * or an IP packet or an ARP packet
+	 */
 	if (proto_type > ETH_DATA_LEN) {
 
 		if (proto_type == ETH_P_IP) {
@@ -431,7 +437,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
 			length = XEL_ARP_PACKET_SIZE + ETH_HLEN + ETH_FCS_LEN;
 		else
 			/* Field contains type other than IP or ARP, use max
-			 * frame size and let user parse it */
+			 * frame size and let user parse it
+			 */
 			length = ETH_FRAME_LEN + ETH_FCS_LEN;
 	} else
 		/* Use the length in the frame, plus the header and trailer */
@@ -601,11 +608,11 @@ static void xemaclite_rx_handler(struct net_device *dev)
 		return;
 	}
 
-	/*
-	 * A new skb should have the data halfword aligned, but this code is
+	/* A new skb should have the data halfword aligned, but this code is
 	 * here just in case that isn't true. Calculate how many
 	 * bytes we should reserve to get the data to start on a word
-	 * boundary */
+	 * boundary
+	 */
 	align = BUFFER_ALIGN(skb->data);
 	if (align)
 		skb_reserve(skb, align);
@@ -707,8 +714,8 @@ static int xemaclite_mdio_wait(struct net_local *lp)
 	unsigned long end = jiffies + 2;
 
 	/* wait for the MDIO interface to not be busy or timeout
-	   after some time.
-	*/
+	 * after some time.
+	 */
 	while (xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) &
 			XEL_MDIOCTRL_MDIOSTS_MASK) {
 		if (time_before_eq(end, jiffies)) {
@@ -1028,7 +1035,8 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
 	if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) {
 		/* If the Emaclite Tx buffer is busy, stop the Tx queue and
 		 * defer the skb for transmission during the ISR, after the
-		 * current transmission is complete */
+		 * current transmission is complete
+		 */
 		netif_stop_queue(dev);
 		lp->deferred_skb = new_skb;
 		/* Take the time stamp now, since we can't do this in an ISR. */
-- 
2.7.4

^ permalink raw reply related

* [PATCH 5/5] net: emaclite: Remove unnecessary spaces
From: Radhey Shyam Pandey @ 2018-06-18 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529320103-7711-1-git-send-email-radhey.shyam.pandey@xilinx.com>

This patch fixes below checkpatch checks-

CHECK: spaces preferred around that '*' (ctx:VxV)
CHECK: No space is necessary after a cast

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index e8bb7b3..f62e4b6 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -95,11 +95,11 @@
 
 
 
-#define TX_TIMEOUT		(60*HZ)		/* Tx timeout is 60 seconds. */
+#define TX_TIMEOUT		(60 * HZ)	/* Tx timeout is 60 seconds. */
 #define ALIGNMENT		4
 
 /* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */
-#define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT)
+#define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32)adr)) % ALIGNMENT)
 
 #ifdef __BIG_ENDIAN
 #define xemaclite_readl		ioread32be
@@ -239,8 +239,8 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,
 
 		/* Set up to output the remaining data */
 		align_buffer = 0;
-		to_u8_ptr = (u8 *) &align_buffer;
-		from_u8_ptr = (u8 *) from_u16_ptr;
+		to_u8_ptr = (u8 *)&align_buffer;
+		from_u8_ptr = (u8 *)from_u16_ptr;
 
 		/* Output the remaining data */
 		for (; length > 0; length--)
@@ -273,7 +273,7 @@ static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr,
 	u32 align_buffer;
 
 	from_u32_ptr = src_ptr;
-	to_u16_ptr = (u16 *) dest_ptr;
+	to_u16_ptr = (u16 *)dest_ptr;
 
 	for (; length > 3; length -= 4) {
 		/* Copy each word into the temporary buffer */
@@ -289,9 +289,9 @@ static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr,
 		u8 *to_u8_ptr, *from_u8_ptr;
 
 		/* Set up to read the remaining data */
-		to_u8_ptr = (u8 *) to_u16_ptr;
+		to_u8_ptr = (u8 *)to_u16_ptr;
 		align_buffer = *from_u32_ptr++;
-		from_u8_ptr = (u8 *) &align_buffer;
+		from_u8_ptr = (u8 *)&align_buffer;
 
 		/* Read the remaining data */
 		for (; length > 0; length--)
@@ -351,7 +351,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
 		return -1; /* Buffer was full, return failure */
 
 	/* Write the frame to the buffer */
-	xemaclite_aligned_write(data, (u32 __force *) addr, byte_count);
+	xemaclite_aligned_write(data, (u32 __force *)addr, byte_count);
 
 	xemaclite_writel((byte_count & XEL_TPLR_LENGTH_MASK),
 			 addr + XEL_TPLR_OFFSET);
@@ -448,7 +448,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
 		length = maxlen;
 
 	/* Read from the EmacLite device */
-	xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET),
+	xemaclite_aligned_read((u32 __force *)(addr + XEL_RXBUFF_OFFSET),
 				data, length);
 
 	/* Acknowledge the frame */
@@ -479,7 +479,7 @@ static void xemaclite_update_address(struct net_local *drvdata,
 	/* Determine the expected Tx buffer address */
 	addr = drvdata->base_addr + drvdata->next_tx_buf_to_use;
 
-	xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN);
+	xemaclite_aligned_write(address_ptr, (u32 __force *)addr, ETH_ALEN);
 
 	xemaclite_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET);
 
@@ -574,7 +574,7 @@ static void xemaclite_tx_handler(struct net_device *dev)
 	dev->stats.tx_packets++;
 	if (lp->deferred_skb) {
 		if (xemaclite_send_data(lp,
-					(u8 *) lp->deferred_skb->data,
+					(u8 *)lp->deferred_skb->data,
 					lp->deferred_skb->len) != 0)
 			return;
 		dev->stats.tx_bytes += lp->deferred_skb->len;
@@ -619,7 +619,7 @@ static void xemaclite_rx_handler(struct net_device *dev)
 
 	skb_reserve(skb, 2);
 
-	len = xemaclite_recv_data(lp, (u8 *) skb->data, len);
+	len = xemaclite_recv_data(lp, (u8 *)skb->data, len);
 
 	if (!len) {
 		dev->stats.rx_errors++;
@@ -1032,7 +1032,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
 	new_skb = orig_skb;
 
 	spin_lock_irqsave(&lp->reset_lock, flags);
-	if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) {
+	if (xemaclite_send_data(lp, (u8 *)new_skb->data, len) != 0) {
 		/* If the Emaclite Tx buffer is busy, stop the Tx queue and
 		 * defer the skb for transmission during the ISR, after the
 		 * current transmission is complete
-- 
2.7.4

^ permalink raw reply related

* [PATCH] ARM: dts: exynos: Add missing CPU clocks to secondary CPUs on Exynos542x
From: Anand Moon @ 2018-06-18 11:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530164922.31851-1-krzk@kernel.org>

Hi Krzysztof,


On 30 May 2018 at 22:19, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> Secondary CPUs should have the same information in DeviceTree as booting
> CPU from both correctness point of view and for possible hotplug
> scenarios.
>
> Suggested-by: Viresh Kumar <viresh.kumar@linaro.org>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
>  arch/arm/boot/dts/exynos5420-cpus.dtsi | 6 ++++++
>  arch/arm/boot/dts/exynos5422-cpus.dtsi | 8 +++++++-
>  2 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos5420-cpus.dtsi b/arch/arm/boot/dts/exynos5420-cpus.dtsi
> index a8e449471304..0ee6e92a3c29 100644
> --- a/arch/arm/boot/dts/exynos5420-cpus.dtsi
> +++ b/arch/arm/boot/dts/exynos5420-cpus.dtsi
> @@ -38,6 +38,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
>                         reg = <0x1>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> @@ -49,6 +50,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
>                         reg = <0x2>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> @@ -60,6 +62,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
>                         reg = <0x3>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> @@ -83,6 +86,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a7";
>                         reg = <0x101>;
> +                       clocks = <&clock CLK_KFC_CLK>;
>                         clock-frequency = <1000000000>;
>                         cci-control-port = <&cci_control0>;
>                         operating-points-v2 = <&cluster_a7_opp_table>;
> @@ -94,6 +98,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a7";
>                         reg = <0x102>;
> +                       clocks = <&clock CLK_KFC_CLK>;
>                         clock-frequency = <1000000000>;
>                         cci-control-port = <&cci_control0>;
>                         operating-points-v2 = <&cluster_a7_opp_table>;
> @@ -105,6 +110,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a7";
>                         reg = <0x103>;
> +                       clocks = <&clock CLK_KFC_CLK>;
>                         clock-frequency = <1000000000>;
>                         cci-control-port = <&cci_control0>;
>                         operating-points-v2 = <&cluster_a7_opp_table>;
> diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi
> index 7c130a00d1a8..e4a5857c135f 100644
> --- a/arch/arm/boot/dts/exynos5422-cpus.dtsi
> +++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi
> @@ -37,6 +37,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a7";
>                         reg = <0x101>;
> +                       clocks = <&clock CLK_KFC_CLK>;
>                         clock-frequency = <1000000000>;
>                         cci-control-port = <&cci_control0>;
>                         operating-points-v2 = <&cluster_a7_opp_table>;
> @@ -48,6 +49,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a7";
>                         reg = <0x102>;
> +                       clocks = <&clock CLK_KFC_CLK>;
>                         clock-frequency = <1000000000>;
>                         cci-control-port = <&cci_control0>;
>                         operating-points-v2 = <&cluster_a7_opp_table>;
> @@ -59,6 +61,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a7";
>                         reg = <0x103>;
> +                       clocks = <&clock CLK_KFC_CLK>;
>                         clock-frequency = <1000000000>;
>                         cci-control-port = <&cci_control0>;
>                         operating-points-v2 = <&cluster_a7_opp_table>;
> @@ -69,8 +72,8 @@
>                 cpu4: cpu at 0 {
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
> -                       clocks = <&clock CLK_ARM_CLK>;
>                         reg = <0x0>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> @@ -82,6 +85,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
>                         reg = <0x1>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> @@ -93,6 +97,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
>                         reg = <0x2>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> @@ -104,6 +109,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a15";
>                         reg = <0x3>;
> +                       clocks = <&clock CLK_ARM_CLK>;
>                         clock-frequency = <1800000000>;
>                         cci-control-port = <&cci_control1>;
>                         operating-points-v2 = <&cluster_a15_opp_table>;
> --
[snip]

Actually cpufreq module have more clock to be enabled below is example
from clk_summary.

    fout_kpll                             0            0  1400000000
       0 0
       mout_kpll                          0            0  1400000000
       0 0
          kfcclk                          0            0  1400000000
       0 0
          sclk_kpll                       0            0   350000000
       0 0
          mout_kfc                        0            0  1400000000
       0 0
             div_kfc                      0            0  1400000000
       0 0

    fout_apll                             0            0  2000000000
       0 0
       mout_apll                          0            0  2000000000
       0 0
          armclk                          0            0  2000000000
       0 0
          sclk_apll                       0            0   500000000
       0 0
          mout_cpu                        0            0  2000000000
       0 0
             div_arm                      0            0  2000000000
       0 0
                armclk2                   0            0  2000000000
       0 0

Best Regards
-Anand

^ permalink raw reply

* [PATCH v2 0/1] ASoC: stm32: sai: add iec958 controls support
From: Mark Brown @ 2018-06-18 11:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528730039-15757-1-git-send-email-olivier.moysan@st.com>

On Mon, Jun 11, 2018 at 05:13:58PM +0200, Olivier Moysan wrote:
> Changes v2:
> - Remove iec958 helpers and implement iec958 controls in sai driver 
> 
> Olivier Moysan (1):
>   ASoC: stm32: sai: add iec958 controls support

Please don't send cover letters for single patches, if there is anything
that needs saying put it in the changelog of the patch or after the ---
if it's administrative stuff.  This reduces mail volume and ensures that 
any important information is recorded in the changelog rather than being
lost. 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180618/6fa32360/attachment.sig>

^ permalink raw reply

* [PATCH v2 08/10] drm/bridge: tc358764: Add DSI to LVDS bridge driver
From: Maciej Purski @ 2018-06-18 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9eec949c-f2b8-4d8d-e30e-ade5159255d6@codeaurora.org>

On 05/31/2018 08:51 AM, Archit Taneja wrote:
> Hi,
> 
> On Wednesday 30 May 2018 05:45 PM, Maciej Purski wrote:
>> From: Andrzej Hajda <a.hajda@samsung.com>
>>
>> Add a drm_bridge driver for the Toshiba TC358764 DSI to LVDS bridge.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Maciej Purski <m.purski@samsung.com>
>> ---
>> ? drivers/gpu/drm/bridge/Kconfig??? |?? 9 +
>> ? drivers/gpu/drm/bridge/Makefile?? |?? 1 +
>> ? drivers/gpu/drm/bridge/tc358764.c | 547 ++++++++++++++++++++++++++++++++++++++
>> ? 3 files changed, 557 insertions(+)
>> ? create mode 100644 drivers/gpu/drm/bridge/tc358764.c
>>
>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>> index fa2c799..9bd3eb8 100644
>> --- a/drivers/gpu/drm/bridge/Kconfig
>> +++ b/drivers/gpu/drm/bridge/Kconfig
>> @@ -110,6 +110,15 @@ config DRM_THINE_THC63LVD1024
>> ????? ---help---
>> ??????? Thine THC63LVD1024 LVDS/parallel converter driver.
>> +config DRM_TOSHIBA_TC358764
>> +??? tristate "TC358764 DSI/LVDS bridge"
>> +??? depends on DRM && DRM_PANEL
>> +??? depends on OF
>> +??? select DRM_MIPI_DSI
>> +??? select VIDEOMODE_HELPERS
> 
> I don't see videomode usage in the driver, can we drop this if it isn't
> used?
> 

It seems that those are some remains of old versions. It is not required now.

>> +??? help
>> +????? Toshiba TC358764 DSI/LVDS bridge driver
>> +
>> ? config DRM_TOSHIBA_TC358767
>> ????? tristate "Toshiba TC358767 eDP bridge"
>> ????? depends on OF
>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>> index 35f88d4..bf7c0ce 100644
>> --- a/drivers/gpu/drm/bridge/Makefile
>> +++ b/drivers/gpu/drm/bridge/Makefile
>> @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
>> ? obj-$(CONFIG_DRM_SII902X) += sii902x.o
>> ? obj-$(CONFIG_DRM_SII9234) += sii9234.o
>> ? obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o
>> +obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o
>> ? obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
>> ? obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
>> ? obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
>> diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c
>> new file mode 100644
>> index 0000000..3109eba
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/tc358764.c
>> @@ -0,0 +1,547 @@
> 
> We'd need a SPDX license here?
>> +/*
>> + * Copyright (C) 2018 Samsung Electronics Co., Ltd
>> + *
>> + * Authors:
>> + *??? Andrzej Hajda <a.hajda@samsung.com>
>> + *??? Maciej Purski <m.purski@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.? See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.
>> + *
>> + */
>> +
>> +#include <drm/drm_atomic_helper.h>
>> +
>> +#include <drm/drmP.h>
>> +#include <drm/drm_mipi_dsi.h>
>> +#include <drm/drm_panel.h>
>> +
>> +#include <drm/drm_crtc.h>
>> +#include <drm/drm_crtc_helper.h>
>> +
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/of_graph.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +#include <video/mipi_display.h>
>> +#include <video/of_videomode.h>
>> +#include <video/videomode.h>
>> +
>> +#define FLD_MASK(start, end)??? (((1 << ((start) - (end) + 1)) - 1) << (end))
>> +#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
>> +
>> +/* PPI layer registers */
>> +#define PPI_STARTPPI??????? 0x0104 /* START control bit */
>> +#define PPI_LPTXTIMECNT??????? 0x0114 /* LPTX timing signal */
>> +#define PPI_LANEENABLE??????? 0x0134 /* Enables each lane */
>> +#define PPI_TX_RX_TA??????? 0x013C /* BTA timing parameters */
>> +#define PPI_D0S_CLRSIPOCOUNT??? 0x0164 /* Assertion timer for Lane 0 */
>> +#define PPI_D1S_CLRSIPOCOUNT??? 0x0168 /* Assertion timer for Lane 1 */
>> +#define PPI_D2S_CLRSIPOCOUNT??? 0x016C /* Assertion timer for Lane 2 */
>> +#define PPI_D3S_CLRSIPOCOUNT??? 0x0170 /* Assertion timer for Lane 3 */
>> +#define PPI_START_FUNCTION??? 1
>> +
>> +/* DSI layer registers */
>> +#define DSI_STARTDSI??????? 0x0204 /* START control bit of DSI-TX */
>> +#define DSI_LANEENABLE??????? 0x0210 /* Enables each lane */
>> +#define DSI_RX_START??????? 1
>> +
>> +/* Video path registers */
>> +#define VP_CTRL??????????? 0x0450 /* Video Path Control */
>> +#define VP_CTRL_MSF(v)??????? FLD_VAL(v, 0, 0) /* Magic square in RGB666 */
>> +#define VP_CTRL_VTGEN(v)??? FLD_VAL(v, 4, 4) /* Use chip clock for timing */
>> +#define VP_CTRL_EVTMODE(v)??? FLD_VAL(v, 5, 5) /* Event mode */
>> +#define VP_CTRL_RGB888(v)??? FLD_VAL(v, 8, 8) /* RGB888 mode */
>> +#define VP_CTRL_VSDELAY(v)??? FLD_VAL(v, 31, 20) /* VSYNC delay */
>> +#define VP_CTRL_HSPOL??????? BIT(17) /* Polarity of HSYNC signal */
>> +#define VP_CTRL_DEPOL??????? BIT(18) /* Polarity of DE signal */
>> +#define VP_CTRL_VSPOL??????? BIT(19) /* Polarity of VSYNC signal */
>> +#define VP_HTIM1??????? 0x0454 /* Horizontal Timing Control 1 */
>> +#define VP_HTIM1_HBP(v)??????? FLD_VAL(v, 24, 16)
>> +#define VP_HTIM1_HSYNC(v)??? FLD_VAL(v, 8, 0)
>> +#define VP_HTIM2??????? 0x0458 /* Horizontal Timing Control 2 */
>> +#define VP_HTIM2_HFP(v)??????? FLD_VAL(v, 24, 16)
>> +#define VP_HTIM2_HACT(v)??? FLD_VAL(v, 10, 0)
>> +#define VP_VTIM1??????? 0x045C /* Vertical Timing Control 1 */
>> +#define VP_VTIM1_VBP(v)??????? FLD_VAL(v, 23, 16)
>> +#define VP_VTIM1_VSYNC(v)??? FLD_VAL(v, 7, 0)
>> +#define VP_VTIM2??????? 0x0460 /* Vertical Timing Control 2 */
>> +#define VP_VTIM2_VFP(v)??????? FLD_VAL(v, 23, 16)
>> +#define VP_VTIM2_VACT(v)??? FLD_VAL(v, 10, 0)
>> +#define VP_VFUEN??????? 0x0464 /* Video Frame Timing Update Enable */
>> +
>> +/* LVDS registers */
>> +#define LV_MX0003??????? 0x0480 /* Mux input bit 0 to 3 */
>> +#define LV_MX0407??????? 0x0484 /* Mux input bit 4 to 7 */
>> +#define LV_MX0811??????? 0x0488 /* Mux input bit 8 to 11 */
>> +#define LV_MX1215??????? 0x048C /* Mux input bit 12 to 15 */
>> +#define LV_MX1619??????? 0x0490 /* Mux input bit 16 to 19 */
>> +#define LV_MX2023??????? 0x0494 /* Mux input bit 20 to 23 */
>> +#define LV_MX2427??????? 0x0498 /* Mux input bit 24 to 27 */
>> +#define LV_MX(b0, b1, b2, b3)??? (FLD_VAL(b0, 4, 0) | FLD_VAL(b1, 12, 8) | \
>> +??????????????? FLD_VAL(b2, 20, 16) | FLD_VAL(b3, 28, 24))
>> +
>> +/* Input bit numbers used in mux registers */
>> +enum {
>> +??? LVI_R0,
>> +??? LVI_R1,
>> +??? LVI_R2,
>> +??? LVI_R3,
>> +??? LVI_R4,
>> +??? LVI_R5,
>> +??? LVI_R6,
>> +??? LVI_R7,
>> +??? LVI_G0,
>> +??? LVI_G1,
>> +??? LVI_G2,
>> +??? LVI_G3,
>> +??? LVI_G4,
>> +??? LVI_G5,
>> +??? LVI_G6,
>> +??? LVI_G7,
>> +??? LVI_B0,
>> +??? LVI_B1,
>> +??? LVI_B2,
>> +??? LVI_B3,
>> +??? LVI_B4,
>> +??? LVI_B5,
>> +??? LVI_B6,
>> +??? LVI_B7,
>> +??? LVI_HS,
>> +??? LVI_VS,
>> +??? LVI_DE,
>> +??? LVI_L0
>> +};
>> +
>> +#define LV_CFG??????????? 0x049C /* LVDS Configuration */
>> +#define LV_PHY0??????????? 0x04A0 /* LVDS PHY 0 */
>> +#define LV_PHY0_RST(v)??????? FLD_VAL(v, 22, 22) /* PHY reset */
>> +#define LV_PHY0_IS(v)??????? FLD_VAL(v, 15, 14)
>> +#define LV_PHY0_ND(v)??????? FLD_VAL(v, 4, 0) /* Frequency range select */
>> +#define LV_PHY0_PRBS_ON(v)??? FLD_VAL(v, 20, 16) /* Clock/Data Flag pins */
>> +
>> +/* System registers */
>> +#define SYS_RST??????????? 0x0504 /* System Reset */
>> +#define SYS_ID??????????? 0x0580 /* System ID */
>> +
>> +#define SYS_RST_I2CS??????? BIT(0) /* Reset I2C-Slave controller */
>> +#define SYS_RST_I2CM??????? BIT(1) /* Reset I2C-Master controller */
>> +#define SYS_RST_LCD??????? BIT(2) /* Reset LCD controller */
>> +#define SYS_RST_BM??????? BIT(3) /* Reset Bus Management controller */
>> +#define SYS_RST_DSIRX??????? BIT(4) /* Reset DSI-RX and App controller */
>> +#define SYS_RST_REG??????? BIT(5) /* Reset Register module */
>> +
>> +#define LPX_PERIOD??????? 2
>> +#define TTA_SURE??????? 3
>> +#define TTA_GET??????????? 0x20000
>> +
>> +/* Lane enable PPI and DSI register bits */
>> +#define LANEENABLE_CLEN??????? BIT(0)
>> +#define LANEENABLE_L0EN??????? BIT(1)
>> +#define LANEENABLE_L1EN??????? BIT(2)
>> +#define LANEENABLE_L2EN??????? BIT(3)
>> +#define LANEENABLE_L3EN??????? BIT(4)
>> +
>> +/* LVCFG fields */
>> +#define LV_CFG_LVEN??????? BIT(0)
>> +#define LV_CFG_LVDLINK??????? BIT(1)
>> +#define LV_CFG_CLKPOL1??????? BIT(2)
>> +#define LV_CFG_CLKPOL2??????? BIT(3)
>> +
>> +static const char * const tc358764_supplies[] = {
>> +??? "vddc", "vddio", "vddmipi", "vddlvds133", "vddlvds112"
>> +};
>> +
>> +struct tc358764 {
>> +??? struct device *dev;
>> +??? struct drm_bridge bridge;
>> +??? struct drm_connector connector;
>> +??? struct regulator_bulk_data supplies[ARRAY_SIZE(tc358764_supplies)];
>> +??? struct gpio_desc *gpio_reset;
>> +
>> +??? struct drm_panel *panel;
>> +};
>> +
>> +static int tc358764_read(struct tc358764 *ctx, u16 addr, u32 *val)
>> +{
>> +??? struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
>> +??? const struct mipi_dsi_host_ops *ops = dsi->host->ops;
>> +??? struct mipi_dsi_msg msg = {
>> +??????? .type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
>> +??????? .channel = dsi->channel,
>> +??????? .flags = MIPI_DSI_MSG_USE_LPM,
>> +??????? .tx_buf = &addr,
>> +??????? .tx_len = 2,
>> +??????? .rx_buf = val,
>> +??????? .rx_len = 4
>> +??? };
>> +??? ssize_t ret;
>> +
>> +??? if (!ops || !ops->transfer)
>> +??????? return -EINVAL;
>> +
>> +??? cpu_to_le16s(&addr);
>> +
>> +??? ret = ops->transfer(dsi->host, &msg);
>> +??? if (ret >= 0)
>> +??????? le32_to_cpus(val); > +
>> +??? dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val);
>> +
>> +??? return ret;
>> +}
>> +
>> +static int tc358764_write(struct tc358764 *ctx, u16 addr, u32 val)
>> +{
>> +??? struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
>> +??? const struct mipi_dsi_host_ops *ops = dsi->host->ops;
>> +??? u8 data[6];
>> +??? int ret;
>> +??? struct mipi_dsi_msg msg = {
>> +??????? .type = MIPI_DSI_GENERIC_LONG_WRITE,
>> +??????? .channel = dsi->channel,
>> +??????? .flags = MIPI_DSI_MSG_USE_LPM | MIPI_DSI_MSG_REQ_ACK,
>> +??????? .tx_buf = data,
>> +??????? .tx_len = 6
>> +??? };
>> +
>> +??? if (!ops || !ops->transfer)
>> +??????? return -EINVAL;
>> +
>> +??? data[0] = addr;
>> +??? data[1] = addr >> 8;
>> +??? data[2] = val;
>> +??? data[3] = val >> 8;
>> +??? data[4] = val >> 16;
>> +??? data[5] = val >> 24;
>> +
>> +??? ret = ops->transfer(dsi->host, &msg);
>> +
>> +??? return ret;
>> +}
>> +
>> +static inline struct tc358764 *bridge_to_tc358764(struct drm_bridge *bridge)
>> +{
>> +??? return container_of(bridge, struct tc358764, bridge);
>> +}
>> +
>> +static inline
>> +struct tc358764 *connector_to_tc358764(struct drm_connector *connector)
>> +{
>> +??? return container_of(connector, struct tc358764, connector);
>> +}
>> +
>> +static int tc358764_init(struct tc358764 *ctx)
>> +{
>> +??? u32 v = 0;
>> +
>> +??? tc358764_read(ctx, SYS_ID, &v);
>> +??? dev_info(ctx->dev, "ID: %#x\n", v);
>> +
>> +??? /* configure PPI counters */
>> +??? tc358764_write(ctx, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
>> +??? tc358764_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD);
>> +??? tc358764_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5);
>> +??? tc358764_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5);
>> +??? tc358764_write(ctx, PPI_D2S_CLRSIPOCOUNT, 5);
>> +??? tc358764_write(ctx, PPI_D3S_CLRSIPOCOUNT, 5);
>> +
>> +??? /* enable four data lanes and clock lane */
>> +??? tc358764_write(ctx, PPI_LANEENABLE, LANEENABLE_L3EN | LANEENABLE_L2EN |
>> +?????????????? LANEENABLE_L1EN | LANEENABLE_L0EN | LANEENABLE_CLEN);
>> +??? tc358764_write(ctx, DSI_LANEENABLE, LANEENABLE_L3EN | LANEENABLE_L2EN |
>> +?????????????? LANEENABLE_L1EN | LANEENABLE_L0EN | LANEENABLE_CLEN);
>> +
>> +??? /* start */
>> +??? tc358764_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION);
>> +??? tc358764_write(ctx, DSI_STARTDSI, DSI_RX_START);
>> +
>> +??? /* configure video path */
>> +??? tc358764_write(ctx, VP_CTRL, VP_CTRL_VSDELAY(15) | VP_CTRL_RGB888(1) |
>> +?????????????? VP_CTRL_EVTMODE(1) | VP_CTRL_HSPOL | VP_CTRL_VSPOL);
> 
> Could we specify somewhere that

Could you clarify, what do you mean here?

>> +
>> +??? /* reset PHY */
>> +??? tc358764_write(ctx, LV_PHY0, LV_PHY0_RST(1) |
>> +?????????????? LV_PHY0_PRBS_ON(4) | LV_PHY0_IS(2) | LV_PHY0_ND(6));
>> +??? tc358764_write(ctx, LV_PHY0, LV_PHY0_PRBS_ON(4) | LV_PHY0_IS(2) |
>> +?????????????? LV_PHY0_ND(6));
>> +
>> +??? /* reset bridge */
>> +??? tc358764_write(ctx, SYS_RST, SYS_RST_LCD);
>> +
>> +??? /* set bit order */
>> +??? tc358764_write(ctx, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
>> +??? tc358764_write(ctx, LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, LVI_G0));
>> +??? tc358764_write(ctx, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_G6, LVI_G7));
>> +??? tc358764_write(ctx, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
>> +??? tc358764_write(ctx, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2));
>> +??? tc358764_write(ctx, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
>> +??? tc358764_write(ctx, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6));
>> +??? tc358764_write(ctx, LV_CFG, LV_CFG_CLKPOL2 | LV_CFG_CLKPOL1 |
>> +?????????????? LV_CFG_LVEN);
>> +
>> +??? return 0;
>> +}
>> +
>> +static void tc358764_reset(struct tc358764 *ctx)
>> +{
>> +??? msleep(20);
>> +??? gpiod_set_value(ctx->gpio_reset, 0);
>> +??? msleep(20);
>> +??? gpiod_set_value(ctx->gpio_reset, 1);
>> +??? msleep(40);
>> +}
>> +
>> +static void tc358764_poweroff(struct tc358764 *ctx)
>> +{
>> +??? int ret;
>> +
>> +??? tc358764_reset(ctx);
>> +
>> +??? drm_panel_disable(ctx->panel);
>> +??? msleep(40);
>> +
>> +??? ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
>> +??? if (ret < 0)
>> +??????? dev_err(ctx->dev, "error disabling regulators (%d)\n", ret);
>> +}
>> +
>> +static int tc358764_get_modes(struct drm_connector *connector)
>> +{
>> +??? struct tc358764 *ctx = connector_to_tc358764(connector);
>> +
>> +??? if (ctx->panel && ctx->panel->funcs && ctx->panel->funcs->get_modes)
>> +??????? return ctx->panel->funcs->get_modes(ctx->panel);
>> +
>> +??? return 0;
>> +}
>> +
>> +static const
>> +struct drm_connector_helper_funcs tc358764_connector_helper_funcs = {
>> +??? .get_modes = tc358764_get_modes,
>> +};
>> +
>> +static const struct drm_connector_funcs tc358764_connector_funcs = {
>> +??? .fill_modes = drm_helper_probe_single_connector_modes,
>> +??? .destroy = drm_connector_cleanup,
>> +??? .reset = drm_atomic_helper_connector_reset,
>> +??? .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
>> +??? .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
>> +};
>> +
>> +static void tc358764_disable(struct drm_bridge *bridge)
>> +{
>> +??? struct tc358764 *ctx = bridge_to_tc358764(bridge);
>> +
>> +??? tc358764_poweroff(ctx);
>> +}
>> +
>> +static void tc358764_pre_enable(struct drm_bridge *bridge)
>> +{
>> +??? struct tc358764 *ctx = bridge_to_tc358764(bridge);
>> +??? int ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies),
>> +??????????????????? ctx->supplies);
>> +??? if (ret < 0)
>> +??????? dev_err(ctx->dev, "error enabling regulators (%d)\n", ret);
>> +
>> +??? tc358764_reset(ctx);
>> +??? tc358764_init(ctx);
>> +}
>> +
>> +static void tc358764_enable(struct drm_bridge *bridge)
>> +{
>> +??? struct tc358764 *ctx = bridge_to_tc358764(bridge);
>> +??? int ret;
>> +
>> +??? drm_panel_prepare(ctx->panel);
>> +
>> +??? ret = drm_panel_enable(ctx->panel);
>> +??? if (ret < 0)
>> +??????? pr_err("panel enable failed\n");
>> +
>> +??? msleep(40);
>> +}
>> +
>> +static int tc358764_attach(struct drm_bridge *bridge)
>> +{
>> +??? struct tc358764 *ctx = bridge_to_tc358764(bridge);
>> +??? struct drm_device *drm = bridge->dev;
>> +??? int ret;
>> +
>> +??? if (!bridge->encoder) {
>> +??????? DRM_ERROR("Encoder not found\n");
>> +??????? return -ENODEV;
>> +??? }
>> +
>> +??? ctx->connector.polled = DRM_CONNECTOR_POLL_HPD;
>> +??? ret = drm_connector_init(drm, &ctx->connector,
>> +???????????????? &tc358764_connector_funcs,
>> +???????????????? DRM_MODE_CONNECTOR_LVDS);
>> +??? if (ret) {
>> +??????? DRM_ERROR("Failed to initialize connector\n");
>> +??????? return ret;
>> +??? }
>> +
>> +??? drm_connector_helper_add(&ctx->connector,
>> +???????????????? &tc358764_connector_helper_funcs);
>> +
>> +??? drm_mode_connector_attach_encoder(&ctx->connector, bridge->encoder);
>> +
>> +??? if (ctx->panel)
>> +??????? drm_panel_attach(ctx->panel, &ctx->connector);
>> +
>> +??? drm_atomic_helper_connector_reset(&ctx->connector);
>> +??? drm_connector_register(&ctx->connector);
>> +
>> +??? return 0;
>> +}
>> +
>> +static const struct drm_bridge_funcs tc358764_bridge_funcs = {
>> +??? .disable = tc358764_disable,
>> +??? .enable = tc358764_enable,
>> +??? .pre_enable = tc358764_pre_enable,
>> +??? .attach = tc358764_attach,
>> +};
>> +
>> +static struct device_node *tc358764_of_find_panel_node(struct device *dev)
>> +{
>> +??? struct device_node *np, *ep;
>> +
>> +??? ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0);
>> +??? if (!ep) {
>> +??????? pr_err("faile to get endpoint\n");
>> +??????? return NULL;
>> +??? }
>> +
>> +??? np = of_graph_get_remote_port_parent(ep);
>> +
>> +??? return np;
>> +}
>> +
>> +static int tc358764_parse_dt(struct tc358764 *ctx)
>> +{
>> +??? struct device *dev = ctx->dev;
>> +??? struct device_node *np = dev->of_node;
>> +??? struct device_node *lvds;
>> +
>> +??? ctx->gpio_reset = devm_gpiod_get_from_of_node(dev, np, "reset", 0,
>> +????????????????????????????? GPIOD_OUT_LOW,
>> +????????????????????????????? "tc358764-reset");
>> +??? if (IS_ERR(ctx->gpio_reset)) {
>> +??????? dev_err(dev, "no reset GPIO pin provided\n");
>> +??????? return PTR_ERR(ctx->gpio_reset);
>> +??? }
>> +
>> +??? lvds = tc358764_of_find_panel_node(ctx->dev);
>> +??? if (!lvds) {
>> +??????? dev_err(dev, "cannot find panel node\n");
>> +??????? return -EINVAL;
>> +??? }
>> +
>> +??? ctx->panel = of_drm_find_panel(lvds);
>> +??? if (!ctx->panel) {
>> +??????? dev_err(dev, "panel not registered\n");
>> +??????? return -EPROBE_DEFER;
>> +??? }
>> +
>> +??? return 0;
>> +}
>> +
>> +static int tc358764_configure_regulators(struct tc358764 *ctx)
>> +{
>> +??? int i, ret;
>> +
>> +??? for (i = 0; i < ARRAY_SIZE(ctx->supplies); ++i)
>> +??????? ctx->supplies[i].supply = tc358764_supplies[i];
>> +
>> +??? ret = devm_regulator_bulk_get(ctx->dev, ARRAY_SIZE(ctx->supplies),
>> +????????????????????? ctx->supplies);
>> +??? if (ret < 0)
>> +??????? dev_err(ctx->dev, "failed to get regulators: %d\n", ret);
>> +
>> +??? return ret;
>> +}
>> +
>> +static int tc358764_probe(struct mipi_dsi_device *dsi)
>> +{
>> +??? struct device *dev = &dsi->dev;
>> +??? struct tc358764 *ctx;
>> +??? int ret;
>> +
>> +??? ctx = devm_kzalloc(dev, sizeof(struct tc358764), GFP_KERNEL);
>> +??? if (!ctx)
>> +??????? return -ENOMEM;
>> +
>> +??? mipi_dsi_set_drvdata(dsi, ctx);
>> +
>> +??? ctx->dev = dev;
>> +
>> +??? dsi->lanes = 4;
>> +??? dsi->format = MIPI_DSI_FMT_RGB888;
>> +??? dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
>> +??????? | MIPI_DSI_MODE_VIDEO_AUTO_VERT;
> 
> if you use the mipi_dsi_device_transfer() helper, I guess you'd need to
> add the LPM flag here.
> 

I'll check, if we can use the helper instead of calling ops->transfer() directly.

Thanks,

Maciej Purski

> Looks good to me otherwise. Once the DT port issue is concluded:
> 
> Reviewed-by: Archit Taneja <architt@codeaurora.org>
> 
>> +
>> +??? ret = tc358764_parse_dt(ctx);
>> +??? if (ret < 0)
>> +??????? return ret;
>> +
>> +??? ret = tc358764_configure_regulators(ctx);
>> +??? if (ret < 0)
>> +??????? return ret;
>> +
>> +??? ctx->bridge.funcs = &tc358764_bridge_funcs;
>> +??? ctx->bridge.of_node = dev->of_node;
>> +
>> +??? drm_bridge_add(&ctx->bridge);
>> +
>> +??? ret = mipi_dsi_attach(dsi);
>> +??? if (ret < 0) {
>> +??????? drm_bridge_remove(&ctx->bridge);
>> +??????? dev_err(dev, "failed to attach dsi\n");
>> +??? }
>> +
>> +??? return ret;
>> +}
>> +
>> +static int tc358764_remove(struct mipi_dsi_device *dsi)
>> +{
>> +??? struct tc358764 *ctx = mipi_dsi_get_drvdata(dsi);
>> +
>> +??? tc358764_poweroff(ctx);
>> +
>> +??? mipi_dsi_detach(dsi);
>> +??? drm_bridge_remove(&ctx->bridge);
>> +
>> +??? return 0;
>> +}
>> +
>> +static const struct of_device_id tc358764_of_match[] = {
>> +??? { .compatible = "toshiba,tc358764" },
>> +??? { }
>> +};
>> +MODULE_DEVICE_TABLE(of, tc358764_of_match);
>> +
>> +static struct mipi_dsi_driver tc358764_driver = {
>> +??? .probe = tc358764_probe,
>> +??? .remove = tc358764_remove,
>> +??? .driver = {
>> +??????? .name = "tc358764",
>> +??????? .owner = THIS_MODULE,
>> +??????? .of_match_table = tc358764_of_match,
>> +??? },
>> +};
>> +module_mipi_dsi_driver(tc358764_driver);
>> +
>> +MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
>> +MODULE_AUTHOR("Maciej Purski <m.purski@samsung.com>");
>> +MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358764 DSI/LVDS Bridge");
>> +MODULE_LICENSE("GPL v2");
>>
> 
> 
> 

^ permalink raw reply

* [PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
From: Maciej Purski @ 2018-06-18 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180531040211.GA23051@rob-hp-laptop>



On 05/31/2018 06:02 AM, Rob Herring wrote:
> On Wed, May 30, 2018 at 02:15:58PM +0200, Maciej Purski wrote:
>> From: Andrzej Hajda <a.hajda@samsung.com>
>>
>> The patch adds bindings to Toshiba DSI/LVDS bridge TC358764.
>> Bindings describe power supplies, reset gpio and video interfaces.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Maciej Purski <m.purski@samsung.com>
>> ---
>>   .../bindings/display/bridge/toshiba,tc358764.txt   | 37 ++++++++++++++++++++++
>>   1 file changed, 37 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>>
>> diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>> new file mode 100644
>> index 0000000..6eda14f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>> @@ -0,0 +1,37 @@
>> +TC358764 MIPI-DSI to LVDS panel bridge
>> +
>> +Required properties:
>> +  - compatible: "toshiba,tc358764"
>> +  - reg: the virtual channel number of a DSI peripheral
>> +  - vddc-supply: core voltage supply, 1.2V
>> +  - vddio-supply: I/O voltage supply, 1.8V or 3.3V
>> +  - vddlvds-supply: LVDS1/2 voltage supply, 3.3V
>> +  - reset-gpios: a GPIO spec for the reset pin
>> +
>> +The device node can contain zero to two 'port' child nodes, each with one
> 
> How would 0 ports be valid?
> 

I'll fix this. In my opinion the output LVDS port should be mandatory
and the input DSI port should be optional, as the bridge might be a DSI
child node. According to documentation, the bridge can also be I2C controlled.
In this case, it should contain a DSI input port and LVDS output port.


>> +child 'endpoint' node, according to the bindings defined in [1].
>> +The following are properties specific to those nodes.
>> +
>> +port:
>> +  - reg: (required) can be 0 for DSI port or 1 for LVDS port;
>> +
>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +
>> +Example:
>> +
>> +	bridge at 0 {
>> +		reg = <0>;
>> +		compatible = "toshiba,tc358764";
>> +		vddc-supply = <&vcc_1v2_reg>;
>> +		vddio-supply = <&vcc_1v8_reg>;
>> +		vddlvds-supply = <&vcc_3v3_reg>;
>> +		reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +		port at 1 {
>> +			reg = <1>;
>> +			lvds_ep: endpoint {
>> +				remote-endpoint = <&panel_ep>;
>> +			};
>> +		};
>> +	};
>> -- 
>> 2.7.4
>>
> 
> 
> 

^ permalink raw reply

* [PATCH] iommu/io-pgtable-arm: Fix pgtable allocation in selftest
From: Jean-Philippe Brucker @ 2018-06-18 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Commit 4b123757eeaa ("iommu/io-pgtable-arm: Make allocations
NUMA-aware") added a NUMA hint to page table allocation, but the pgtable
selftest doesn't provide an SMMU device parameter. Since dev_to_node
doesn't accept a NULL argument, add a special case for selftest.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 drivers/iommu/io-pgtable-arm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 010a254305dd..88641b4560bc 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -237,7 +237,8 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
 	void *pages;
 
 	VM_BUG_ON((gfp & __GFP_HIGHMEM));
-	p = alloc_pages_node(dev_to_node(dev), gfp | __GFP_ZERO, order);
+	p = alloc_pages_node(dev ? dev_to_node(dev) : NUMA_NO_NODE,
+			     gfp | __GFP_ZERO, order);
 	if (!p)
 		return NULL;
 
-- 
2.17.0

^ permalink raw reply related

* [PATCH 01/11] i2c: add helpers for locking the I2C segment
From: Peter Rosin @ 2018-06-18 11:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180618110502.cb5s24srp4frahm6@ninjato>

On 2018-06-18 13:05, Wolfram Sang wrote:
> 
>> +static inline void
>> +i2c_lock_segment(struct i2c_adapter *adapter)
>> +{
>> +	i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
>> +}
>> +
>> +static inline int
>> +i2c_trylock_segment(struct i2c_adapter *adapter)
>> +{
>> +	return i2c_trylock_bus(adapter, I2C_LOCK_SEGMENT);
>> +}
>> +
>> +static inline void
>> +i2c_unlock_segment(struct i2c_adapter *adapter)
>> +{
>> +	i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
>> +}
> 
> I wonder if i2c_lock_segment() and i2c_lock_root_adapter() are really
> more readable and convenient than i2c_lock_bus() with the flag. I think
> the flags have speaking names, too.
> 
> Is that an idea to remove these functions altogether and start using
> i2c_lock_bus()?

That would be fine with me. I don't have a strong opinion and agree that
both are readable enough...

It would make for a reduction of the number of lines so that's nice, but
the macro in drivers/i2c/busses/i2c-gpio.c (patch 11) would not fit in
the current \-width (or whatever you'd call that line of backslashes to
the right in a multi-line macro).

Does anyone have a strong opinion?

Cheers,
Peter

^ permalink raw reply

* [PATCH] power: vexpress: fix corruption in notifier registration
From: Sudeep Holla @ 2018-06-18 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

Vexpress platforms provide two different restart handlers: SYS_REBOOT
that restart the entire system, while DB_RESET only restarts the
daughter board containing the CPU. DB_RESET is overridden by SYS_REBOOT
if it exists.

notifier_chain_register used in register_restart_handler by design
allows notifier to be registered once only, however vexpress restart
notifier can get registered twice. When this happen it corrupts list
of notifiers, as result some notifiers can be not called on proper
event, traverse on list can be cycled forever, and second unregister
can access already freed memory.

So far, since this was the only restart handler in the system, no issue
was observed even if the same notifier was registered twice. However
commit 6c5c0d48b686 ("watchdog: sp805: add restart handler") added
support for SP805 restart handlers and since the system under test
contains two vexpress restart and two SP805 watchdog instances, it was
observed that during the boot traversing the restart handler list looped
forever as there's a cycle in that list resulting in boot hang.

This patch fixes the issues by ensuring that the notifier is installed
only once.

Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/power/reset/vexpress-poweroff.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c
index 102f95a09460..cdc68eb06a91 100644
--- a/drivers/power/reset/vexpress-poweroff.c
+++ b/drivers/power/reset/vexpress-poweroff.c
@@ -35,6 +35,7 @@ static void vexpress_reset_do(struct device *dev, const char *what)
 }
 
 static struct device *vexpress_power_off_device;
+static atomic_t vexpress_restart_nb_refcnt = ATOMIC_INIT(0);
 
 static void vexpress_power_off(void)
 {
@@ -96,13 +97,16 @@ static const struct of_device_id vexpress_reset_of_match[] = {
 
 static int _vexpress_register_restart_handler(struct device *dev)
 {
-	int err;
+	int err = 0;
 
 	vexpress_restart_device = dev;
-	err = register_restart_handler(&vexpress_restart_nb);
-	if (err) {
-		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
-		return err;
+	if (atomic_inc_return(&vexpress_restart_nb_refcnt) == 1) {
+		err = register_restart_handler(&vexpress_restart_nb);
+		if (err) {
+			dev_err(dev, "cannot register restart handler (err=%d)\n", err);
+			atomic_dec(&vexpress_restart_nb_refcnt);
+			return err;
+		}
 	}
 	device_create_file(dev, &dev_attr_active);
 
-- 
2.7.4

^ permalink raw reply related

* Charge counter on droid 4
From: Tony Lindgren @ 2018-06-18 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180618093459.GA21391@amd>

* Pavel Machek <pavel@ucw.cz> [180618 09:37]:
> On Mon 2018-06-18 01:28:58, Tony Lindgren wrote:
> > * Pavel Machek <pavel@ucw.cz> [180618 07:43]:
> > > 
> > > So... there are mA, mAh values. Those come from hardware, and I
> > > believe we should keep them.
> > > 
> > > But there are also mW, mWh values, which are synthetic. Userland can
> > > compute them from mV, mA values... and it is confusing that kernel
> > > provides them. (My tendency was to start computing these synthetic
> > > values in userland, to compare them with "real hardware" values from
> > > kernel. But then I looked at kernel implementation, and realized they
> > > are synthetic, tooo...)
> > 
> > Hmm mWh value is based on the hardware sampled shunt
> > values and number of samples gathered between the
> > two readings. I'd rather call the calculated values
> > based on userland reading mV and mA values "synthetic" :)
> 
> As far as I know, shunt resistors provide you with current (mA) not
> power (mW) measurement... and cpcap-battery computes power_now as
> voltage * current. I'd rather have kernel tell me "hardware can't
> measure power" and do "voltage*current" computation in userspace.

Yup you are correct the hardware samples mA and we still need
to calculate mW based on the voltage.

But considering it works and seems to match the power supply
provided average power consumption numbers pretty well and at
least I'm using it.. What is your reasoning for removing such
a usable interface?

Regards,

Tony

^ permalink raw reply

* [PATCH 0/5]  Fixes coding style in xilinx_emaclite.c
From: Radhey Shyam Pandey @ 2018-06-18 11:50 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset fixes checkpatch and kernel-doc warnings in
xilinx emaclite driver. No functional change.

Radhey Shyam Pandey (5):
  net: emaclite: Use __func__ instead of hardcoded name
  net: emaclite: Balance braces in else statement
  net: emaclite: update kernel-doc comments
  net: emaclite: Fix block comments style
  net: emaclite: Remove unnecessary spaces

 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 101 +++++++++++++++-----------
 1 file changed, 58 insertions(+), 43 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH 1/5] net: emaclite: Use __func__ instead of hardcoded name
From: Radhey Shyam Pandey @ 2018-06-18 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529322610-27215-1-git-send-email-radhey.shyam.pandey@xilinx.com>

Switch hardcoded function name with a reference to __func__ making
the code more maintainable. Address below checkpatch warning:

WARNING: Prefer using '"%s...", __func__' to using 'xemaclite_mdio_read',
this function's name, in a string
+               "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n",

WARNING: Prefer using '"%s...", __func__' to using 'xemaclite_mdio_write',
this function's name, in a string
+               "xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n",

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 2a0c06e..0544134 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -757,7 +757,7 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
 	rc = xemaclite_readl(lp->base_addr + XEL_MDIORD_OFFSET);
 
 	dev_dbg(&lp->ndev->dev,
-		"xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n",
+		"%s(phy_id=%i, reg=%x) == %x\n", __func__,
 		phy_id, reg, rc);
 
 	return rc;
@@ -780,7 +780,7 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
 	u32 ctrl_reg;
 
 	dev_dbg(&lp->ndev->dev,
-		"xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+		"%s(phy_id=%i, reg=%x, val=%x)\n", __func__,
 		phy_id, reg, val);
 
 	if (xemaclite_mdio_wait(lp))
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/5] net: emaclite: Balance braces in else statement
From: Radhey Shyam Pandey @ 2018-06-18 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529322610-27215-1-git-send-email-radhey.shyam.pandey@xilinx.com>

Remove else as it is not required with if doing a return.
Fixes below checkpatch warning.

WARNING: else is not generally useful after a break or return

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 0544134..8d84f58 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -569,13 +569,11 @@ static void xemaclite_tx_handler(struct net_device *dev)
 					(u8 *) lp->deferred_skb->data,
 					lp->deferred_skb->len) != 0)
 			return;
-		else {
-			dev->stats.tx_bytes += lp->deferred_skb->len;
-			dev_kfree_skb_irq(lp->deferred_skb);
-			lp->deferred_skb = NULL;
-			netif_trans_update(dev); /* prevent tx timeout */
-			netif_wake_queue(dev);
-		}
+		dev->stats.tx_bytes += lp->deferred_skb->len;
+		dev_kfree_skb_irq(lp->deferred_skb);
+		lp->deferred_skb = NULL;
+		netif_trans_update(dev); /* prevent tx timeout */
+		netif_wake_queue(dev);
 	}
 }
 
@@ -1052,13 +1050,13 @@ static bool get_bool(struct platform_device *ofdev, const char *s)
 {
 	u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL);
 
-	if (p) {
+	if (p)
 		return (bool)*p;
-	} else {
-		dev_warn(&ofdev->dev, "Parameter %s not found,"
+
+	dev_warn(&ofdev->dev, "Parameter %s not found,"
 			"defaulting to false\n", s);
-		return false;
-	}
+
+	return false;
 }
 
 static const struct net_device_ops xemaclite_netdev_ops;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 3/5] net: emaclite: update kernel-doc comments
From: Radhey Shyam Pandey @ 2018-06-18 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529322610-27215-1-git-send-email-radhey.shyam.pandey@xilinx.com>

This patch fixes below kernel-doc warnings:

Function parameter or member 'maxlen' not described in 'xemaclite_recv_data'
Function parameter or member 'address'not described in 'xemaclite_set_mac_address'
Excess function parameter 'addr' description in 'xemaclite_set_mac_address'
No description found for return value of 'xemaclite_interrupt'
No description found for return value of 'xemaclite_mdio_write'
Function parameter or member 'dev' not described in 'xemaclite_mdio_setup'
Excess function parameter 'ofdev' description in 'xemaclite_mdio_setup'
No description found for return value of 'xemaclite_open'
No description found for return value of 'xemaclite_close'
Excess function parameter 'match' description in 'xemaclite_of_probe'

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 8d84f58..0b41cc5 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -369,6 +369,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
  * xemaclite_recv_data - Receive a frame
  * @drvdata:	Pointer to the Emaclite device private data
  * @data:	Address where the data is to be received
+ * @maxlen:    Maximum supported ethernet packet length
  *
  * This function is intended to be called from the interrupt context or
  * with a wrapper which waits for the receive frame to be available.
@@ -488,7 +489,7 @@ static void xemaclite_update_address(struct net_local *drvdata,
 /**
  * xemaclite_set_mac_address - Set the MAC address for this device
  * @dev:	Pointer to the network device instance
- * @addr:	Void pointer to the sockaddr structure
+ * @address:	Void pointer to the sockaddr structure
  *
  * This function copies the HW address from the sockaddr strucutre to the
  * net_device structure and updates the address in HW.
@@ -637,6 +638,8 @@ static void xemaclite_rx_handler(struct net_device *dev)
  * @dev_id:	Void pointer to the network device instance used as callback
  *		reference
  *
+ * Return:	IRQ_HANDLED
+ *
  * This function handles the Tx and Rx interrupts of the EmacLite device.
  */
 static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
@@ -770,6 +773,8 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
  *
  * This function waits till the device is ready to accept a new MDIO
  * request and then writes the val to the MDIO Write Data register.
+ *
+ * Return:      0 upon success or a negative error upon failure
  */
 static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
 				u16 val)
@@ -803,7 +808,7 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
 /**
  * xemaclite_mdio_setup - Register mii_bus for the Emaclite device
  * @lp:		Pointer to the Emaclite device private data
- * @ofdev:	Pointer to OF device structure
+ * @dev:	Pointer to OF device structure
  *
  * This function enables MDIO bus in the Emaclite device and registers a
  * mii_bus.
@@ -903,6 +908,9 @@ static void xemaclite_adjust_link(struct net_device *ndev)
  * This function sets the MAC address, requests an IRQ and enables interrupts
  * for the Emaclite device and starts the Tx queue.
  * It also connects to the phy device, if MDIO is included in Emaclite device.
+ *
+ * Return:	0 on success. -ENODEV, if PHY cannot be connected.
+ *		Non-zero error value on failure.
  */
 static int xemaclite_open(struct net_device *dev)
 {
@@ -973,6 +981,8 @@ static int xemaclite_open(struct net_device *dev)
  * This function stops the Tx queue, disables interrupts and frees the IRQ for
  * the Emaclite device.
  * It also disconnects the phy device associated with the Emaclite device.
+ *
+ * Return:	0, always.
  */
 static int xemaclite_close(struct net_device *dev)
 {
@@ -1064,7 +1074,6 @@ static const struct net_device_ops xemaclite_netdev_ops;
 /**
  * xemaclite_of_probe - Probe method for the Emaclite device.
  * @ofdev:	Pointer to OF device structure
- * @match:	Pointer to the structure used for matching a device
  *
  * This function probes for the Emaclite device in the device tree.
  * It initializes the driver data structure and the hardware, sets the MAC
-- 
2.7.4

^ permalink raw reply related


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