* [PATCH 3/9] iommu/rockchip: Fix error handling in probe
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
Add missing iommu_device_sysfs_remove in error path.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ee805e1dfba7..a05844cabb45 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1201,8 +1201,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
err = iommu_device_register(&iommu->iommu);
+ if (err) {
+ iommu_device_sysfs_remove(&iommu->iommu);
+ return err;
+ }
- return err;
+ return 0;
}
static int rk_iommu_remove(struct platform_device *pdev)
--
2.11.0
^ permalink raw reply related
* [PATCH 4/9] iommu/rockchip: Fix error handling in init
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
It's hard to undo bus_set_iommu() in the error path, so move it to the
end of init call.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index a05844cabb45..5f141390b4d7 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1247,17 +1247,25 @@ static int __init rk_iommu_init(void)
of_node_put(np);
- ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
- if (ret)
- return ret;
-
ret = platform_driver_register(&rk_iommu_domain_driver);
if (ret)
return ret;
ret = platform_driver_register(&rk_iommu_driver);
if (ret)
- platform_driver_unregister(&rk_iommu_domain_driver);
+ goto err_unreg_domain_drv;
+
+ ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
+ if (ret)
+ goto err_unreg_iommu_drv;
+
+ return 0;
+
+err_unreg_iommu_drv:
+ platform_driver_unregister(&rk_iommu_driver);
+err_unreg_domain_drv:
+ platform_driver_unregister(&rk_iommu_domain_driver);
+
return ret;
}
static void __exit rk_iommu_exit(void)
--
2.11.0
^ permalink raw reply related
* [PATCH 5/9] iommu/rockchip: Use iopoll helpers to wait for hardware
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
This patch converts the rockchip-iommu driver to use the in-kernel
iopoll helpers to wait for certain status bits to change in registers
instead of an open-coded custom macro.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 68 ++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 36 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 5f141390b4d7..6b797e085340 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -13,7 +13,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iommu.h>
-#include <linux/jiffies.h>
+#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -36,7 +36,8 @@
#define RK_MMU_AUTO_GATING 0x24
#define DTE_ADDR_DUMMY 0xCAFEBABE
-#define FORCE_RESET_TIMEOUT 100 /* ms */
+#define FORCE_RESET_TIMEOUT 100000 /* us */
+#define POLL_TIMEOUT 1000 /* us */
/* RK_MMU_STATUS fields */
#define RK_MMU_STATUS_PAGING_ENABLED BIT(0)
@@ -73,8 +74,6 @@
*/
#define RK_IOMMU_PGSIZE_BITMAP 0x007ff000
-#define IOMMU_REG_POLL_COUNT_FAST 1000
-
struct rk_iommu_domain {
struct list_head iommus;
struct platform_device *pdev;
@@ -111,27 +110,6 @@ static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
return container_of(dom, struct rk_iommu_domain, domain);
}
-/**
- * Inspired by _wait_for in intel_drv.h
- * This is NOT safe for use in interrupt context.
- *
- * Note that it's important that we check the condition again after having
- * timed out, since the timeout could be due to preemption or similar and
- * we've never had a chance to check the condition before the timeout.
- */
-#define rk_wait_for(COND, MS) ({ \
- unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
- int ret__ = 0; \
- while (!(COND)) { \
- if (time_after(jiffies, timeout__)) { \
- ret__ = (COND) ? 0 : -ETIMEDOUT; \
- break; \
- } \
- usleep_range(50, 100); \
- } \
- ret__; \
-})
-
/*
* The Rockchip rk3288 iommu uses a 2-level page table.
* The first level is the "Directory Table" (DT).
@@ -335,9 +313,21 @@ static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu)
return enable;
}
+static bool rk_iommu_is_reset_done(struct rk_iommu *iommu)
+{
+ bool done = true;
+ int i;
+
+ for (i = 0; i < iommu->num_mmu; i++)
+ done &= rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0;
+
+ return done;
+}
+
static int rk_iommu_enable_stall(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (rk_iommu_is_stall_active(iommu))
return 0;
@@ -348,7 +338,8 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL);
- ret = rk_wait_for(rk_iommu_is_stall_active(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+ val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n",
@@ -360,13 +351,15 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
static int rk_iommu_disable_stall(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (!rk_iommu_is_stall_active(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_STALL);
- ret = rk_wait_for(!rk_iommu_is_stall_active(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+ !val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n",
@@ -378,13 +371,15 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu)
static int rk_iommu_enable_paging(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (rk_iommu_is_paging_enabled(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_PAGING);
- ret = rk_wait_for(rk_iommu_is_paging_enabled(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+ val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n",
@@ -396,13 +391,15 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu)
static int rk_iommu_disable_paging(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (!rk_iommu_is_paging_enabled(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_PAGING);
- ret = rk_wait_for(!rk_iommu_is_paging_enabled(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+ !val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n",
@@ -415,6 +412,7 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
{
int ret, i;
u32 dte_addr;
+ bool val;
if (iommu->reset_disabled)
return 0;
@@ -435,13 +433,11 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET);
- for (i = 0; i < iommu->num_mmu; i++) {
- ret = rk_wait_for(rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0x00000000,
- FORCE_RESET_TIMEOUT);
- if (ret) {
- dev_err(iommu->dev, "FORCE_RESET command timed out\n");
- return ret;
- }
+ ret = readx_poll_timeout(rk_iommu_is_reset_done, iommu, val,
+ val, 100, FORCE_RESET_TIMEOUT);
+ if (ret) {
+ dev_err(iommu->dev, "FORCE_RESET command timed out\n");
+ return ret;
}
return 0;
--
2.11.0
^ permalink raw reply related
* [PATCH 6/9] iommu/rockchip: Fix TLB flush of secondary IOMMUs
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
Due to the bug in current code, only first IOMMU has the TLB lines
flushed in rk_iommu_zap_lines. This patch fixes the inner loop to
execute for all IOMMUs and properly flush the TLB.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 6b797e085340..cfeafbf54096 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -274,19 +274,21 @@ static void rk_iommu_base_command(void __iomem *base, u32 command)
{
writel(command, base + RK_MMU_COMMAND);
}
-static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova,
+static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova_start,
size_t size)
{
int i;
-
- dma_addr_t iova_end = iova + size;
+ dma_addr_t iova_end = iova_start + size;
/*
* TODO(djkurtz): Figure out when it is more efficient to shootdown the
* entire iotlb rather than iterate over individual iovas.
*/
- for (i = 0; i < iommu->num_mmu; i++)
- for (; iova < iova_end; iova += SPAGE_SIZE)
+ for (i = 0; i < iommu->num_mmu; i++) {
+ dma_addr_t iova;
+
+ for (iova = iova_start; iova < iova_end; iova += SPAGE_SIZE)
rk_iommu_write(iommu->bases[i], RK_MMU_ZAP_ONE_LINE, iova);
+ }
}
static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
--
2.11.0
^ permalink raw reply related
* [PATCH 7/9] iommu/rockchip: Use iommu_group_get_for_dev() for add_device
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
IOMMU drivers are supposed to call this function instead of manually
creating a group in their .add_device callback. This behavior is not
strictly required by ARM DMA mapping implementation, but ARM64 already
relies on it. This patch fixes the rockchip-iommu driver to comply with
this requirement.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 122 +++++++++++++++++++++--------------------
1 file changed, 64 insertions(+), 58 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index cfeafbf54096..86f8190d7bed 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -802,6 +802,40 @@ static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
return rk_iommu;
}
+static void rk_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct rk_iommu *iommu;
+ struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
+ unsigned long flags;
+ int i;
+
+ /* Allow 'virtual devices' (eg drm) to detach from domain */
+ iommu = rk_iommu_from_dev(dev);
+ if (!iommu)
+ return;
+
+ spin_lock_irqsave(&rk_domain->iommus_lock, flags);
+ list_del_init(&iommu->node);
+ spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
+
+ /* Ignore error while disabling, just keep going */
+ rk_iommu_enable_stall(iommu);
+ rk_iommu_disable_paging(iommu);
+ for (i = 0; i < iommu->num_mmu; i++) {
+ rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
+ rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
+ }
+ rk_iommu_disable_stall(iommu);
+
+ for (i = 0; i < iommu->num_irq; i++)
+ devm_free_irq(iommu->dev, iommu->irq[i], iommu);
+
+ iommu->domain = NULL;
+
+ dev_dbg(dev, "Detached from iommu domain\n");
+}
+
static int rk_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
@@ -818,6 +852,9 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
if (!iommu)
return 0;
+ if (iommu->domain)
+ rk_iommu_detach_device(domain, dev);
+
ret = rk_iommu_enable_stall(iommu);
if (ret)
return ret;
@@ -865,40 +902,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
return ret;
}
-static void rk_iommu_detach_device(struct iommu_domain *domain,
- struct device *dev)
-{
- struct rk_iommu *iommu;
- struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
- unsigned long flags;
- int i;
-
- /* Allow 'virtual devices' (eg drm) to detach from domain */
- iommu = rk_iommu_from_dev(dev);
- if (!iommu)
- return;
-
- spin_lock_irqsave(&rk_domain->iommus_lock, flags);
- list_del_init(&iommu->node);
- spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
-
- /* Ignore error while disabling, just keep going */
- rk_iommu_enable_stall(iommu);
- rk_iommu_disable_paging(iommu);
- for (i = 0; i < iommu->num_mmu; i++) {
- rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
- rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
- }
- rk_iommu_disable_stall(iommu);
-
- for (i = 0; i < iommu->num_irq; i++)
- devm_free_irq(iommu->dev, iommu->irq[i], iommu);
-
- iommu->domain = NULL;
-
- dev_dbg(dev, "Detached from iommu domain\n");
-}
-
static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
{
struct rk_iommu_domain *rk_domain;
@@ -1049,41 +1052,20 @@ static int rk_iommu_add_device(struct device *dev)
{
struct iommu_group *group;
struct rk_iommu *iommu;
- int ret;
if (!rk_iommu_is_dev_iommu_master(dev))
return -ENODEV;
- group = iommu_group_get(dev);
- if (!group) {
- group = iommu_group_alloc();
- if (IS_ERR(group)) {
- dev_err(dev, "Failed to allocate IOMMU group\n");
- return PTR_ERR(group);
- }
- }
-
- ret = iommu_group_add_device(group, dev);
- if (ret)
- goto err_put_group;
-
- ret = rk_iommu_group_set_iommudata(group, dev);
- if (ret)
- goto err_remove_device;
+ group = iommu_group_get_for_dev(dev);
+ if (IS_ERR(group))
+ return PTR_ERR(group);
iommu = rk_iommu_from_dev(dev);
if (iommu)
iommu_device_link(&iommu->iommu, dev);
iommu_group_put(group);
-
return 0;
-
-err_remove_device:
- iommu_group_remove_device(dev);
-err_put_group:
- iommu_group_put(group);
- return ret;
}
static void rk_iommu_remove_device(struct device *dev)
@@ -1100,6 +1082,29 @@ static void rk_iommu_remove_device(struct device *dev)
iommu_group_remove_device(dev);
}
+static struct iommu_group *rk_iommu_device_group(struct device *dev)
+{
+ struct iommu_group *group;
+ int ret;
+
+ group = iommu_group_get(dev);
+ if (!group) {
+ group = iommu_group_alloc();
+ if (IS_ERR(group))
+ return group;
+ }
+
+ ret = rk_iommu_group_set_iommudata(group, dev);
+ if (ret)
+ goto err_put_group;
+
+ return group;
+
+err_put_group:
+ iommu_group_put(group);
+ return ERR_PTR(ret);
+}
+
static const struct iommu_ops rk_iommu_ops = {
.domain_alloc = rk_iommu_domain_alloc,
.domain_free = rk_iommu_domain_free,
@@ -1111,6 +1116,7 @@ static const struct iommu_ops rk_iommu_ops = {
.add_device = rk_iommu_add_device,
.remove_device = rk_iommu_remove_device,
.iova_to_phys = rk_iommu_iova_to_phys,
+ .device_group = rk_iommu_device_group,
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
};
--
2.11.0
^ permalink raw reply related
* [PATCH 8/9] iommu/rockchip: Use IOMMU device for dma mapping operations
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
Use the first registered IOMMU device for dma mapping operations, and
drop the domain platform device.
This is similar to exynos iommu driver.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 96 ++++++++++++------------------------------
1 file changed, 28 insertions(+), 68 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 86f8190d7bed..ab18a80fdd12 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -76,7 +76,6 @@
struct rk_iommu_domain {
struct list_head iommus;
- struct platform_device *pdev;
u32 *dt; /* page directory table */
dma_addr_t dt_dma;
spinlock_t iommus_lock; /* lock for iommus list */
@@ -97,12 +96,14 @@ struct rk_iommu {
struct iommu_domain *domain; /* domain to which iommu is attached */
};
+static struct device *dma_dev;
+
static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma,
unsigned int count)
{
size_t size = count * sizeof(u32); /* count of u32 entry */
- dma_sync_single_for_device(&dom->pdev->dev, dma, size, DMA_TO_DEVICE);
+ dma_sync_single_for_device(dma_dev, dma, size, DMA_TO_DEVICE);
}
static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
@@ -606,7 +607,6 @@ static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
dma_addr_t iova)
{
- struct device *dev = &rk_domain->pdev->dev;
u32 *page_table, *dte_addr;
u32 dte_index, dte;
phys_addr_t pt_phys;
@@ -624,9 +624,9 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
if (!page_table)
return ERR_PTR(-ENOMEM);
- pt_dma = dma_map_single(dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
- if (dma_mapping_error(dev, pt_dma)) {
- dev_err(dev, "DMA mapping error while allocating page table\n");
+ pt_dma = dma_map_single(dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
+ if (dma_mapping_error(dma_dev, pt_dma)) {
+ dev_err(dma_dev, "DMA mapping error while allocating page table\n");
free_page((unsigned long)page_table);
return ERR_PTR(-ENOMEM);
}
@@ -905,29 +905,20 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
{
struct rk_iommu_domain *rk_domain;
- struct platform_device *pdev;
- struct device *iommu_dev;
if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
return NULL;
- /* Register a pdev per domain, so DMA API can base on this *dev
- * even some virtual master doesn't have an iommu slave
- */
- pdev = platform_device_register_simple("rk_iommu_domain",
- PLATFORM_DEVID_AUTO, NULL, 0);
- if (IS_ERR(pdev))
+ if (!dma_dev)
return NULL;
- rk_domain = devm_kzalloc(&pdev->dev, sizeof(*rk_domain), GFP_KERNEL);
+ rk_domain = devm_kzalloc(dma_dev, sizeof(*rk_domain), GFP_KERNEL);
if (!rk_domain)
- goto err_unreg_pdev;
-
- rk_domain->pdev = pdev;
+ return NULL;
if (type == IOMMU_DOMAIN_DMA &&
iommu_get_dma_cookie(&rk_domain->domain))
- goto err_unreg_pdev;
+ return NULL;
/*
* rk32xx iommus use a 2 level pagetable.
@@ -938,11 +929,10 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
if (!rk_domain->dt)
goto err_put_cookie;
- iommu_dev = &pdev->dev;
- rk_domain->dt_dma = dma_map_single(iommu_dev, rk_domain->dt,
+ rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,
SPAGE_SIZE, DMA_TO_DEVICE);
- if (dma_mapping_error(iommu_dev, rk_domain->dt_dma)) {
- dev_err(iommu_dev, "DMA map error for DT\n");
+ if (dma_mapping_error(dma_dev, rk_domain->dt_dma)) {
+ dev_err(dma_dev, "DMA map error for DT\n");
goto err_free_dt;
}
@@ -963,8 +953,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
err_put_cookie:
if (type == IOMMU_DOMAIN_DMA)
iommu_put_dma_cookie(&rk_domain->domain);
-err_unreg_pdev:
- platform_device_unregister(pdev);
return NULL;
}
@@ -981,20 +969,18 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
if (rk_dte_is_pt_valid(dte)) {
phys_addr_t pt_phys = rk_dte_pt_address(dte);
u32 *page_table = phys_to_virt(pt_phys);
- dma_unmap_single(&rk_domain->pdev->dev, pt_phys,
+ dma_unmap_single(dma_dev, pt_phys,
SPAGE_SIZE, DMA_TO_DEVICE);
free_page((unsigned long)page_table);
}
}
- dma_unmap_single(&rk_domain->pdev->dev, rk_domain->dt_dma,
+ dma_unmap_single(dma_dev, rk_domain->dt_dma,
SPAGE_SIZE, DMA_TO_DEVICE);
free_page((unsigned long)rk_domain->dt);
if (domain->type == IOMMU_DOMAIN_DMA)
iommu_put_dma_cookie(&rk_domain->domain);
-
- platform_device_unregister(rk_domain->pdev);
}
static bool rk_iommu_is_dev_iommu_master(struct device *dev)
@@ -1120,30 +1106,6 @@ static const struct iommu_ops rk_iommu_ops = {
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
};
-static int rk_iommu_domain_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
-
- dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
- if (!dev->dma_parms)
- return -ENOMEM;
-
- /* Set dma_ops for dev, otherwise it would be dummy_dma_ops */
- arch_setup_dma_ops(dev, 0, DMA_BIT_MASK(32), NULL, false);
-
- dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
- dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
-
- return 0;
-}
-
-static struct platform_driver rk_iommu_domain_driver = {
- .probe = rk_iommu_domain_probe,
- .driver = {
- .name = "rk_iommu_domain",
- },
-};
-
static int rk_iommu_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1210,6 +1172,14 @@ static int rk_iommu_probe(struct platform_device *pdev)
return err;
}
+ /*
+ * Use the first registered IOMMU device for domain to use with DMA
+ * API, since a domain might not physically correspond to a single
+ * IOMMU device..
+ */
+ if (!dma_dev)
+ dma_dev = &pdev->dev;
+
return 0;
}
@@ -1251,31 +1221,21 @@ static int __init rk_iommu_init(void)
of_node_put(np);
- ret = platform_driver_register(&rk_iommu_domain_driver);
- if (ret)
- return ret;
-
ret = platform_driver_register(&rk_iommu_driver);
if (ret)
- goto err_unreg_domain_drv;
+ return ret;
ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
- if (ret)
- goto err_unreg_iommu_drv;
+ if (ret) {
+ platform_driver_unregister(&rk_iommu_driver);
+ return ret;
+ }
return 0;
-
-err_unreg_iommu_drv:
- platform_driver_unregister(&rk_iommu_driver);
-err_unreg_domain_drv:
- platform_driver_unregister(&rk_iommu_domain_driver);
-
- return ret;
}
static void __exit rk_iommu_exit(void)
{
platform_driver_unregister(&rk_iommu_driver);
- platform_driver_unregister(&rk_iommu_domain_driver);
}
subsys_initcall(rk_iommu_init);
--
2.11.0
^ permalink raw reply related
* [PATCH 9/9] iommu/rockchip: Use OF_IOMMU to attach devices automatically
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
Converts the rockchip-iommu driver to use the OF_IOMMU infrastructure,
which allows attaching master devices to their IOMMUs automatically
according to DT properties.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab18a80fdd12..c375a2522bfd 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -18,6 +18,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_iommu.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -1091,6 +1092,13 @@ static struct iommu_group *rk_iommu_device_group(struct device *dev)
return ERR_PTR(ret);
}
+static int rk_iommu_of_xlate(struct device *dev,
+ struct of_phandle_args *spec)
+{
+ /* We don't have any phandle args, so just return 0. */
+ return 0;
+}
+
static const struct iommu_ops rk_iommu_ops = {
.domain_alloc = rk_iommu_domain_alloc,
.domain_free = rk_iommu_domain_free,
@@ -1104,6 +1112,7 @@ static const struct iommu_ops rk_iommu_ops = {
.iova_to_phys = rk_iommu_iova_to_phys,
.device_group = rk_iommu_device_group,
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
+ .of_xlate = rk_iommu_of_xlate,
};
static int rk_iommu_probe(struct platform_device *pdev)
@@ -1166,6 +1175,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
return err;
iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
+ iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
+
err = iommu_device_register(&iommu->iommu);
if (err) {
iommu_device_sysfs_remove(&iommu->iommu);
@@ -1241,6 +1252,8 @@ static void __exit rk_iommu_exit(void)
subsys_initcall(rk_iommu_init);
module_exit(rk_iommu_exit);
+IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu");
+
MODULE_DESCRIPTION("IOMMU API for Rockchip");
MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
MODULE_ALIAS("platform:rockchip-iommu");
--
2.11.0
^ permalink raw reply related
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Joel Stanley @ 2018-01-11 8:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111073038.GA3600@kroah.com>
On Wed, Jan 10, 2018 at 11:30 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Wed, Jan 10, 2018 at 01:46:34PM -0800, Jae Hyun Yoo wrote:
>> Thanks for your pointing it out and I totally agree with you. Actually, we
>> are preparing 4.13 update for now and an another update will be followed up.
>> As I answered above, I'll rebase this patch set onto the latest kernel.org
>> mainline. Sorry for my misunderstanding of upstream process.
>
> 4.13? Why that kernel? It too is obsolete and insecure and
> unsupported.
It contains support for our hardware that I have integrated from work
in progress patches and upstream commits.
The OpenBMC project, with myself as the kernel maintainer, have
intentions to regularly move to upstream releases. This takes time and
effort. This time and effort is balanced with submitting our drivers
upstream.
> What keeps you all from just always tracking the latest tree from Linus?
Linus' tree does not contain all of the drivers required to boot
systems. Many of them are still under review on lkml, and others still
require rewrite from the vendor tree.
> What is in your tree that is not upstream that requires you to have a
> kernel tree at all?
We have PECI, video compression, crypto, USB CDC, DRM (graphics),
serial GPIO, LPC mailbox for the ASPEED SoC.
Another silicon vendor has recently joined the project and that brings
an entire SoC that is not upstream. We have patches on the ARM that
are under review for this SoC, with more drivers undergoing cleanup in
order to submit them to the relevant maintainers.
>
> And if you do have out-of-tree code, why not use a process that makes it
> trivial to update the base kernel version so that you can keep up to
> date very easily? (hint, just using 'git' is not a good way to do
> this...)
We have a process that we've been developing under for the past few
years. I find git to be a great tool for managing Linux kernel trees.
What would you recommend for managing kernel trees?
Cheers,
Joel
^ permalink raw reply
* [PATCH] ARM64: dts: meson-axg: add RMII pins for ethernet controller
From: Jerome Brunet @ 2018-01-11 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111030411.197054-1-yixun.lan@amlogic.com>
On Thu, 2018-01-11 at 11:04 +0800, Yixun Lan wrote:
> Comparing to RGMII interface, the RMII interface require few pins.
> So it's worth describing them here.
>
> Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
The only axg platform we have upstream is the s400 and is using rgmii.
May I ask how this was tested ?
^ permalink raw reply
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Greg KH @ 2018-01-11 8:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACPK8Xe9Jti8S2px=QOcSMA2v+TZ4eGDGQND4qmBUBXeBpsBZQ@mail.gmail.com>
On Thu, Jan 11, 2018 at 12:28:48AM -0800, Joel Stanley wrote:
> On Wed, Jan 10, 2018 at 11:30 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> > On Wed, Jan 10, 2018 at 01:46:34PM -0800, Jae Hyun Yoo wrote:
> >> Thanks for your pointing it out and I totally agree with you. Actually, we
> >> are preparing 4.13 update for now and an another update will be followed up.
> >> As I answered above, I'll rebase this patch set onto the latest kernel.org
> >> mainline. Sorry for my misunderstanding of upstream process.
> >
> > 4.13? Why that kernel? It too is obsolete and insecure and
> > unsupported.
>
> It contains support for our hardware that I have integrated from work
> in progress patches and upstream commits.
>
> The OpenBMC project, with myself as the kernel maintainer, have
> intentions to regularly move to upstream releases. This takes time and
> effort. This time and effort is balanced with submitting our drivers
> upstream.
Of course, but please do not have your "users" use a kernel that is
known to have bugs and can not be supported. That would not be good at
all, don't you think?
> > What keeps you all from just always tracking the latest tree from Linus?
>
> Linus' tree does not contain all of the drivers required to boot
> systems. Many of them are still under review on lkml, and others still
> require rewrite from the vendor tree.
Merging vendor trees into your tree has got to be a complicated mess.
Why try to keep it all together in one place?
And who is responsible for getting the vendor code upstream? The
individual drivers? Individual driver submissions should be quite easy,
what is preventing them from getting merged?
> > What is in your tree that is not upstream that requires you to have a
> > kernel tree at all?
>
> We have PECI, video compression, crypto, USB CDC, DRM (graphics),
> serial GPIO, LPC mailbox for the ASPEED SoC.
What "USB CDC" do you have that is not upstream? I'll pick on this one
specifically as I don't think I've seen any patches recently submitted
for that driver at all. Am I just missing them?
The other ones should also all be easy to get merged, with maybe the
exception of the drm stuff due to the speed that subsystem moves at.
But even there, the community is very helpful in getting stuff upstream,
have you asked for help?
> Another silicon vendor has recently joined the project and that brings
> an entire SoC that is not upstream. We have patches on the ARM that
> are under review for this SoC, with more drivers undergoing cleanup in
> order to submit them to the relevant maintainers.
Why are you merging all SoC trees together into one place? That seems
like a nightmare to manage, especially with git.
> > And if you do have out-of-tree code, why not use a process that makes it
> > trivial to update the base kernel version so that you can keep up to
> > date very easily? (hint, just using 'git' is not a good way to do
> > this...)
>
> We have a process that we've been developing under for the past few
> years. I find git to be a great tool for managing Linux kernel trees.
>
> What would you recommend for managing kernel trees?
quilt is best for a tree that you can not rebase (i.e. a public git
tree). Otherwise you end up getting patches all mushed together and
hard to extract in any simple way.
Take a clue from the distros that have been managing kernels for decades
and deal with an updated kernel all the time easily.
Good luck, it sounds like you will need it :)
thanks,
greg k-h
^ permalink raw reply
* [RFC PATCH 09/12] mmc: sdhci: Use software timer when timeout greater than hardware capablility
From: Adrian Hunter @ 2018-01-11 8:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2da01441-84d0-0d96-610d-2f9a3055ccc7@ti.com>
On 04/01/18 14:59, Kishon Vijay Abraham I wrote:
> Hi Adrian,
>
> On Wednesday 20 December 2017 07:41 PM, Adrian Hunter wrote:
>> On 14/12/17 15:09, Kishon Vijay Abraham I wrote:
>>> Errata i834 in AM572x Sitara Processors Silicon Revision 2.0, 1.1
>>> (SPRZ429K July 2014?Revised March 2017 [1]) mentions
>>> Under high speed HS200 and SDR104 modes, the functional clock for MMC
>>> modules will reach up to 192 MHz. At this frequency, the maximum obtainable
>>> timeout (DTO = 0xE) through MMC host controller is (1/192MHz)*2^27 = 700ms.
>>> Commands taking longer than 700ms may be affected by this small window
>>> frame. Workaround for this errata is use a software timer instead of
>>> hardware timer to provide the delay requested by the upper layer.
>>>
>>> While this errata is specific to AM572x, it is applicable to all sdhci
>>> based controllers when a particular request require timeout greater
>>> than hardware capability.
>>
>> It doesn't work for our controllers. Even if the data timeout interrupt is
>> disabled, it seems like the timeout still "happens" in some fashion - after
>> which the host controller starts misbehaving.
>
> even if the data timeout doesn't get disabled, count = 0xE is still present. So
> ideally this shouldn't break any existing platforms no?
I don't want to hide this kind of variation in the hardware behaviour.
>>
>> So you will need to add a quirk.
>>
>>>
>>> Re-use the software timer already implemented in sdhci to program the
>>> correct timeout value and also disable the hardware timeout when
>>> the required timeout is greater than hardware capabiltiy in order to
>>> avoid spurious timeout interrupts.
>>>
>>> This patch is based on the earlier patch implemented for omap_hsmmc [2]
>>>
>>> [1] -> http://www.ti.com/lit/er/sprz429k/sprz429k.pdf
>>> [2] -> https://patchwork.kernel.org/patch/9791449/
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>> drivers/mmc/host/sdhci.c | 41 +++++++++++++++++++++++++++++++++++++++--
>>> drivers/mmc/host/sdhci.h | 11 +++++++++++
>>> 2 files changed, 50 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>> index e9290a3439d5..d0655e1d2cc7 100644
>>> --- a/drivers/mmc/host/sdhci.c
>>> +++ b/drivers/mmc/host/sdhci.c
>>> @@ -673,6 +673,27 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
>>> }
>>> }
>>>
>>> +static void sdhci_calc_sw_timeout(struct sdhci_host *host,
>>> + struct mmc_command *cmd,
>>> + unsigned int target_timeout)
>>> +{
>>> + struct mmc_host *mmc = host->mmc;
>>> + struct mmc_ios *ios = &mmc->ios;
>>> + struct mmc_data *data = cmd->data;
>>> + unsigned long long transfer_time;
>>> +
>>> + if (data) {
>>> + transfer_time = MMC_BLOCK_TRANSFER_TIME_MS(data->blksz,
>>> + ios->bus_width,
>>> + ios->clock);
>>
>> If it has a value, actual_clock is better than ios->clock.
>
> okay.
>>
>>> + /* calculate timeout for the entire data */
>>> + host->data_timeout = (data->blocks * (target_timeout +
>>> + transfer_time));
>>> + } else if (cmd->flags & MMC_RSP_BUSY) {
>>> + host->data_timeout = cmd->busy_timeout * MSEC_PER_SEC;
>>
>> Doesn't need MSEC_PER_SEC multiplier.
>
> right.
>>
>>> + }
>>> +}
>>> +
>>> static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
>>> {
>>> u8 count;
>>> @@ -732,8 +753,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
>>> }
>>>
>>> if (count >= 0xF) {
>>> - DBG("Too large timeout 0x%x requested for CMD%d!\n",
>>> - count, cmd->opcode);
>>> + DBG("Too large timeout.. using SW timeout for CMD%d!\n",
>>> + cmd->opcode);
>>> + sdhci_calc_sw_timeout(host, cmd, target_timeout);
>>> + host->ier &= ~SDHCI_INT_DATA_TIMEOUT;
>>> + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
>>> + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>>> count = 0xE;
>>> }
>>>
>>> @@ -1198,6 +1223,14 @@ static void sdhci_finish_command(struct sdhci_host *host)
>>> {
>>> struct mmc_command *cmd = host->cmd;
>>>
>>> + if (host->data_timeout) {
>>> + unsigned long timeout;
>>> +
>>> + timeout = jiffies +
>>> + msecs_to_jiffies(host->data_timeout);
>>> + sdhci_mod_timer(host, host->cmd->mrq, timeout);
>>
>> cmd could be the sbc or a stop cmd or a command during transfer, so this
>> needs more logic.
>
> host->data_timeout gets set only for data commands or commands with busy
> timeout. But I guess for commands during data transfer, host->data_timeout
> might still be set?
>
> Checking sdhci_data_line_cmd(mrq->cmd) in addition to host->data_timeout should
> take care of all cases right?
I suggest you make the timeout calculation allow for the commands as well
and then reorder sdhci_mod_timer() to be called after sdhci_prepare_data()
and make sdhci_mod_timer() do the right thing.
>>
>>> + }
>>> +
>>> host->cmd = NULL;
>>>
>>> if (cmd->flags & MMC_RSP_PRESENT) {
>>> @@ -2341,6 +2374,10 @@ static bool sdhci_request_done(struct sdhci_host *host)
>>> return true;
>>> }
>>>
>>> + host->data_timeout = 0;
>>> + host->ier |= SDHCI_INT_DATA_TIMEOUT;
>>> + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
>>> + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>>
>> sdhci can have 2 requests in progress to allow for commands to be sent while
>> a data transfer is in progress, so this is not necessarily the data transfer
>> request that is done. Also we want to avoid unnecessary register writes.
>>
>
> okay.. got it.
>>> sdhci_del_timer(host, mrq);
>>>
>>> /*
>>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>>> index 54bc444c317f..e6e0278bea1a 100644
>>> --- a/drivers/mmc/host/sdhci.h
>>> +++ b/drivers/mmc/host/sdhci.h
>>> @@ -332,6 +332,15 @@ struct sdhci_adma2_64_desc {
>>> /* Allow for a a command request and a data request at the same time */
>>> #define SDHCI_MAX_MRQS 2
>>>
>>> +/*
>>> + * Time taken for transferring one block. It is multiplied by a constant
>>> + * factor '2' to account for any errors
>>> + */
>>> +#define MMC_BLOCK_TRANSFER_TIME_MS(blksz, bus_width, freq) \
>>> + ((unsigned long long) \
>>> + (2 * (((blksz) * MSEC_PER_SEC * \
>>> + (8 / (bus_width))) / (freq))))
>>
>> I don't think the macro helps make the code more readable. Might just as
>> well write a nice function to calculate the entire data request timeout.
>
> okay.
>>
>>> +
>>> enum sdhci_cookie {
>>> COOKIE_UNMAPPED,
>>> COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */
>>> @@ -546,6 +555,8 @@ struct sdhci_host {
>>> /* Host SDMA buffer boundary. */
>>> u32 sdma_boundary;
>>>
>>> + unsigned long long data_timeout;
>>
>> msecs_to_jiffies() will truncate to 'unsigned int' anyway, so this might as
>> well be 'unsigned int'.
>>
>
> okay.
>
> Thanks
> Kishon
>
^ permalink raw reply
* [PATCH RFC v1] arm64: Handle traps from accessing CNTVCT/CNTFRQ for CONFIG_COMPAT
From: Marc Zyngier @ 2018-01-11 8:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515645816-14063-1-git-send-email-nicoleotsuka@gmail.com>
On 11/01/18 04:43, Nicolin Chen wrote:
> CONFIG_COMPAT allows ARM64 machine to run 32-bit instructions.
> Since the ARCH_TIMER_USR_VCT_ACCESS_EN might be disabled if a
> timer workaround is detected, accessing cntvct via mrrc will
> also trigger a trap.
>
> So this patch adds support to handle this situation.
>
> Tested with a user program generated by 32-bit compiler:
> int main()
> {
> unsigned long long cval;
> asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
> return 0;
> }
>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
>
> [ I also added cntfrq here for safety as theoretically it could
> trigger the trap as well. However, my another test case (with
> mrc insturction) doesn't seem to trigger a trap. So I would
> drop it in the next version if someone can confirm it's not
> required. Thanks -- Nicolin ]
See my previous series on this very subject[1] as well as Will's reply.
>
> arch/arm64/include/asm/esr.h | 25 +++++++++++++++++++
> arch/arm64/include/asm/ptrace.h | 15 ++++++++++++
> arch/arm64/kernel/entry.S | 4 ++--
> arch/arm64/kernel/traps.c | 53 +++++++++++++++++++++++++++++++++++++++--
> 4 files changed, 93 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index 014d7d8..55dea62 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -220,6 +220,31 @@
> (((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >> \
> ESR_ELx_SYS64_ISS_OP2_SHIFT))
>
> +/* ISS fields for MRC and MRS are very similar, so reuse SYS64 macros */
> +#define ESR_ELx_CP15_32_ISS_MRC_MASK ESR_ELx_SYS64_ISS_SYS_MASK
> +#define ESR_ELx_CP15_32_ISS_MRC_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(0, 0, 0, 14, 0) | \
> + ESR_ELx_SYS64_ISS_DIR_READ)
> +
> +/* ISS field definitions for CP15 MRRC/MCRR instructions (same for CP14) */
> +#define ESR_ELx_CP15_64_ISS_OPC1_SHIFT 16
> +#define ESR_ELx_CP15_64_ISS_OPC1_MASK (UL(0xf) << ESR_ELx_CP15_64_ISS_OPC1_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_RT2_SHIFT 10
> +#define ESR_ELx_CP15_64_ISS_RT2_MASK (UL(0x1f) << ESR_ELx_CP15_64_ISS_RT2_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_RT_SHIFT 5
> +#define ESR_ELx_CP15_64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_CP15_64_ISS_RT_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_CRM_SHIFT 1
> +#define ESR_ELx_CP15_64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_CP15_64_ISS_CRM_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_MRRC_MASK (ESR_ELx_CP15_64_ISS_OPC1_MASK | \
> + ESR_ELx_CP15_64_ISS_CRM_MASK| \
> + ESR_ELx_SYS64_ISS_DIR_MASK)
> +
> +#define ESR_ELx_CP15_64_ISS_MRRC_VAL(opc1, crm) \
> + (((opc1) << ESR_ELx_CP15_64_ISS_OPC1_SHIFT) | \
> + ((crm) << ESR_ELx_CP15_64_ISS_CRM_SHIFT))
> +
> +#define ESR_ELx_CP15_64_ISS_MRRC_CNTVCT (ESR_ELx_CP15_64_ISS_MRRC_VAL(1, 14) | \
> + ESR_ELx_SYS64_ISS_DIR_READ)
> +
> #ifndef __ASSEMBLY__
> #include <asm/types.h>
>
> diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
> index 6069d66..50caf11 100644
> --- a/arch/arm64/include/asm/ptrace.h
> +++ b/arch/arm64/include/asm/ptrace.h
> @@ -243,6 +243,21 @@ static inline void pt_regs_write_reg(struct pt_regs *regs, int r,
> regs->regs[r] = val;
> }
>
> +/*
> + * Write two registers given architectural register index r and r2.
> + * Used by 32-bit MRRC and MCRR instrutions for 64-bit results
> + */
> +static inline void pt_regs_write_regs(struct pt_regs *regs, int r, int r2,
> + unsigned long val)
> +{
> + if (r != 31 && r2 != 31) {
> + /* Save lower 32 bits to register r */
> + regs->regs[r] = val & 0xffffffff;
> + /* Save higher 32 bits to register r2 */
> + regs->regs[r2] = val >> 32;
> + }
> +}
> +
> /* Valid only for Kernel mode traps. */
> static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
> {
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 6d14b8f..9d6cd95 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -636,9 +636,9 @@ el0_sync_compat:
> cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL0
> b.eq el0_undef
> cmp x24, #ESR_ELx_EC_CP15_32 // CP15 MRC/MCR trap
> - b.eq el0_undef
> + b.eq el0_sys
> cmp x24, #ESR_ELx_EC_CP15_64 // CP15 MRRC/MCRR trap
> - b.eq el0_undef
> + b.eq el0_sys
> cmp x24, #ESR_ELx_EC_CP14_MR // CP14 MRC/MCR trap
> b.eq el0_undef
> cmp x24, #ESR_ELx_EC_CP14_LS // CP14 LDC/STC trap
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 3d3588f..211cce7 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -454,6 +454,17 @@ static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
> arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
> }
>
> +#ifdef CONFIG_COMPAT
> +static void cntvct_read_32_handler(unsigned int esr, struct pt_regs *regs)
> +{
> + int rt2 = (esr & ESR_ELx_CP15_64_ISS_RT2_MASK) >> ESR_ELx_CP15_64_ISS_RT2_SHIFT;
> + int rt = (esr & ESR_ELx_CP15_64_ISS_RT_MASK) >> ESR_ELx_CP15_64_ISS_RT_SHIFT;
> +
> + pt_regs_write_regs(regs, rt, rt2, arch_counter_get_cntvct());
> + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
> +}
> +#endif
> +
> static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
> {
> int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
> @@ -495,11 +506,49 @@ static struct sys64_hook sys64_hooks[] = {
> {},
> };
>
> +#ifdef CONFIG_COMPAT
> +static struct sys64_hook cp15_32_hooks[] = {
> + {
> + /* Trap read access to CNTFRQ via 32-bit insturction MRC */
> + .esr_mask = ESR_ELx_CP15_32_ISS_MRC_MASK,
> + .esr_val = ESR_ELx_CP15_32_ISS_MRC_CNTFRQ,
> + .handler = cntfrq_read_handler,
> + },
> + {},
> +};
> +
> +static struct sys64_hook cp15_64_hooks[] = {
> + {
> + /* Trap read access to CNTVCT via 32-bit insturction MRRC */
> + .esr_mask = ESR_ELx_CP15_64_ISS_MRRC_MASK,
> + .esr_val = ESR_ELx_CP15_64_ISS_MRRC_CNTVCT,
> + .handler = cntvct_read_32_handler,
> + },
> + {},
> +};
> +#endif
> +
> asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
> {
> - struct sys64_hook *hook;
> + struct sys64_hook *hook = NULL;
> +
> + switch (ESR_ELx_EC(esr)) {
> +#ifdef CONFIG_COMPAT
> + case ESR_ELx_EC_CP15_32:
> + hook = cp15_32_hooks;
> + break;
> + case ESR_ELx_EC_CP15_64:
> + hook = cp15_64_hooks;
> + break;
> +#endif
> + case ESR_ELx_EC_SYS64:
> + hook = sys64_hooks;
> + break;
> + default:
> + break;
> + }
>
> - for (hook = sys64_hooks; hook->handler; hook++)
> + for (; hook && hook->handler; hook++)
> if ((hook->esr_mask & esr) == hook->esr_val) {
> hook->handler(esr, regs);
> return;
>
Also, this code is fairly broken in its handling of conditional
instructions.
Thanks,
M.
[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2017-July/520426.html
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Benjamin Herrenschmidt @ 2018-01-11 8:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111073038.GA3600@kroah.com>
On Thu, 2018-01-11 at 08:30 +0100, Greg KH wrote:
> 4.13? Why that kernel? It too is obsolete and insecure and
> unsupported.
Haha, it's n-1. come on :-)
> What keeps you all from just always tracking the latest tree from Linus?
> What is in your tree that is not upstream that requires you to have a
> kernel tree at all?
There are a couple of ARM based SoC families for which we are in the
process of rewriting all the driver in upstreamable form. This takes
time.
To respond to your other email about the USB CDC, it's mine, I haven't
resubmited it yet because it had a dependency on some the aspeed clk
driver to function properly (so is unusable without it) and it took 2
kernel versions to get that clk stuff upstream for a number of reasons.
So it's all getting upstream and eventually there will be (we hope) no
"OpenBMC" kernel, it's just a way for us to get functional code with
non-upstream-quality (read: vendor) drivers until we are one rewriting
& upstreaming them all.
> And if you do have out-of-tree code, why not use a process that makes it
> trivial to update the base kernel version so that you can keep up to
> date very easily? (hint, just using 'git' is not a good way to do
> this...)
Joel and I both find git perfectly fine for that. I've not touched
quilt in eons and frankly don't regret it ;-)
That said, Jae should definitely submit a driver against upstream, not
against some random OpenBMC tree.
Jae, for example when I submitted the original USB stuff back then, I
did it from a local upstream based branch (with just a few hacks to
work around the lack of the clk stuff).
I will rebase it in the next few days to upstream merged with Stephen's
clk tree to get the finally merged clk stuff, verify it works, and
submit patches against upstream.
There should be no mention of dev-4.10 or 4.13 on lkml or other
upstream submission lists. Development work should happen upstream
*first* and eventually be backported to our older kernels while they
exist (hopefully I prefer if we are more aggressive at forward porting
the crappy drivers so we can keep our tree more up to date but that's a
different discussion).
Cheers,
Ben.
> thanks,
>
> greg k-h
^ permalink raw reply
* [PATCH linux dev-4.10 3/6] drivers/misc: Add driver for Aspeed PECI and generic PECI headers
From: Benjamin Herrenschmidt @ 2018-01-11 9:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180110101840.GB5822@kroah.com>
On Wed, 2018-01-10 at 11:18 +0100, Greg KH wrote:
> On Tue, Jan 09, 2018 at 02:31:23PM -0800, Jae Hyun Yoo wrote:
> > This commit adds driver implementation for Aspeed PECI. Also adds
> > generic peci.h and peci_ioctl.h files to provide compatibility
> > to peci drivers that can be implemented later e.g. Nuvoton's BMC
> > SoC family.
>
> We don't add code that could be used "sometime in the future". Only
> include stuff that we use now.
>
> Please fix up this series based on that and resubmit. There should not
> be any need for any uapi file then, right?
No Greg, I think you misunderstood (unless I misread myself).
What Jae means is that since PECI is a standard and other drivers
implementing the same ioctl interface and messages will eventually go
upstream, instead of having the ioctl definitions in a driver specific
locations, they go in a generic spot, as they define a generic API for
all PECI drivers, including the one that's getting merged now.
IE. This doesn't add unused stuff, it just puts the API parts of it
into a generic location.
At least that's my understanding from a, granted cursory, look at the
patch.
That said, I do have a problem with the structure definitions of the
various packet types as they use "long" which has a variable size and
unclear alignment. It should be using __u8, __u16 and __u32...
Cheers,
Ben.
^ permalink raw reply
* [PATCH v2 1/6] arm: Add BTB invalidation on switch_mm for Cortex-A9, A12 and A17
From: Marc Zyngier @ 2018-01-11 9:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87c06809-e035-52d7-0822-5fffb402c1dd@ti.com>
On 10/01/18 21:52, Nishanth Menon wrote:
> On 01/10/2018 11:57 AM, Marc Zyngier wrote:
>> On 10/01/18 17:53, Tony Lindgren wrote:
>>> * Marc Zyngier <marc.zyngier@arm.com> [180108 19:00]:
>>>> In order to avoid aliasing attacks against the branch predictor,
>>>> some implementations require to invalidate the BTB when switching
>>>> from one user context to another.
>>>>
>>>> For this, we reuse the existing implementation for Cortex-A8, and
>>>> apply it to A9, A12 and A17.
>>>
>>> I suspect we now must also make sure Cortex-A8 has the IBE bit
>>> set unconditionally for this to work. Currently the assumption is
>>> that IBE bit needs to be set only on the earlier CPU revisions
>>> that suffer from ARM_ERRATA_430973.
>>>
>>>> --- a/arch/arm/mm/proc-v7-2level.S
>>>> +++ b/arch/arm/mm/proc-v7-2level.S
>>>> @@ -41,7 +41,7 @@
>>>> * even on Cortex-A8 revisions not affected by 430973.
>>>> * If IBE is not set, the flush BTAC/BTB won't do anything.
>>>> */
>>>> -ENTRY(cpu_ca8_switch_mm)
>>>> +ENTRY(cpu_v7_btbinv_switch_mm)
>>>> #ifdef CONFIG_MMU
>>>> mov r2, #0
>>>> mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
>>>
>>> So without IBE set, as the comments above say, the flush won't
>>> do anything.
>>
>> Indeed. Firmware/bootloaders must be updated to set IBE, just like on
>> Cortex-A15. I'll add a note to that effect.
> OK. in u-boot, I had helped on the following:
> http://git.denx.de/?p=u-boot.git;a=commitdiff;h=5902f4ce0f2bd1411e40dc0ece3598a0fc19b2ae
>
> maybe be build off that?
Turn that into something unconditional, and you'll be good.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH linux dev-4.10 3/6] drivers/misc: Add driver for Aspeed PECI and generic PECI headers
From: Benjamin Herrenschmidt @ 2018-01-11 9:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180109223126.13093-4-jae.hyun.yoo@linux.intel.com>
On Tue, 2018-01-09 at 14:31 -0800, Jae Hyun Yoo wrote:
> +struct peci_rd_ia_msr_msg {
> + unsigned char target;
> + unsigned char thread_id;
> + unsigned short address;
> + unsigned long value;
> +};
Those types are representing messages on the wire ?
In that case those types aren't suitable. For example "long" will have
a different size and alignment for 32 and 64-bit userspace. There are
size-explicit userspace types available.
Also I didn't see any endianness annotations in there. Is that expected
? IE are those wire format packets ?
Cheers,
Ben.
^ permalink raw reply
* [PATCH 2/3] ARM: dts: mvebu: add sdram controller node to Armada-38x
From: Gregory CLEMENT @ 2018-01-11 9:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5aa9a523e86e4607a14265790d105168@svr-chch-ex1.atlnz.lc>
Hi Chris,
On mer., janv. 10 2018, Chris Packham <Chris.Packham@alliedtelesis.co.nz> wrote:
> On 10/01/18 21:31, Gregory CLEMENT wrote:
>> Hi Chris,
>>
>> On mar., janv. 09 2018, Chris Packham <chris.packham@alliedtelesis.co.nz> wrote:
>>
>>> The Armada-38x uses an SDRAM controller that is compatible with the
>>> Armada-XP. The key difference is the width of the bus (XP is 64/32, 38x
>>> is 32/16). The SDRAM controller registers are the same between the two
>>> SoCs.
>>>
>>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>>> ---
>>> arch/arm/boot/dts/armada-38x.dtsi | 5 +++++
>>> 1 file changed, 5 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
>>> index 00ff549d4e39..6d34c5ec178f 100644
>>> --- a/arch/arm/boot/dts/armada-38x.dtsi
>>> +++ b/arch/arm/boot/dts/armada-38x.dtsi
>>> @@ -138,6 +138,11 @@
>>> #size-cells = <1>;
>>> ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
>>>
>>> + sdramc at 1400 {
>>
>> Could you add a label? Thanks to this it would be possible to
>> enable/disable it at board level in a esay way.
>>
>
> Sure. Any suggestions for a name better than "sdramc:"?
For me sdramc: is fine.
>
> It's probably worth adding the same label to armada-xp.dtsi and
> armada-xp-98dx3236.dtsi.
Right.
>
>>> + compatible = "marvell,armada-xp-sdram-controller";
>>> + reg = <0x1400 0x500>;
>>
>> What about adding status = "disabled" ?
>>
>> Thanks to this we can enable it at board level only if we really want
>> it, it would avoid nasty regression on boards that don't need it, if an
>> issue occurs. Unless you are sure that it is completely safe to enable
>> it for everyone.
>
> The EDAC driver (which is default n) will not probe the device if ECC
> has not been enabled so that should be safe.
OK in this case no need to disable it by default.
Thanks,
Gregory
>
> Other than the EDAC driver the only other code that looks at this is in
> arch/arm/mach-mvebu/pm.c and it almost seems like an omission that this
> code is not active on armada-38x. The armada-38x platforms I have access
> to don't use suspend/resume so I can't verify this.
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] ARM64: dts: meson-axg: add RMII pins for ethernet controller
From: Yixun Lan @ 2018-01-11 9:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515659863.5048.112.camel@baylibre.com>
Hi Jerome?
On 01/11/18 16:37, Jerome Brunet wrote:
> On Thu, 2018-01-11 at 11:04 +0800, Yixun Lan wrote:
>> Comparing to RGMII interface, the RMII interface require few pins.
>> So it's worth describing them here.
>>
>> Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
>
> The only axg platform we have upstream is the s400 and is using rgmii.
> May I ask how this was tested ?
>
It's true that S400 using RGMII interface.
but, we have customer using RTL8201FR-VB/VD which is a RMII PHY,
This is actually tested with the 'eth_rmii_x_pins' group.
Yixun
^ permalink raw reply
* [PATCH v2 0/3] ARM: mvebu: dts: updates to enable EDAC
From: Gregory CLEMENT @ 2018-01-11 9:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111015903.11322-1-chris.packham@alliedtelesis.co.nz>
Hi Chris,
On jeu., janv. 11 2018, Chris Packham <chris.packham@alliedtelesis.co.nz> wrote:
> I've split this off from my earlier series[1] this is just the dts changes that
> will enable support for the EDAC series when it lands.
>
> The Armada 38x as well as the 98dx3236 and similar switch chips with integrated
> CPUs use the same SDRAM controller block as the Armada XP. The key difference
> is the width of the DDR interface.
>
> [1] - https://marc.info/?l=linux-kernel&m=151545124505964&w=2
The series is looks good now. For patch 1 I still wait for that
the "marvell,,ecc-enable" property was accepted before merging it.
So I can either wait for that it was accepted before applying the series,
or just applying patch 2 and 3 for now, as you want.
Thanks,
Gregory
>
> Changes in v2:
> - update commit message
> - add labels to dts
>
> Chris Packham (3):
> ARM: dts: armada-xp: enable L2 cache parity and ecc on db-xc3-24g4xg
> ARM: dts: armada-xp: add label to sdram-controller node
> ARM: dts: mvebu: add sdram controller node to Armada-38x
>
> arch/arm/boot/dts/armada-38x.dtsi | 5 +++++
> arch/arm/boot/dts/armada-xp-98dx3236.dtsi | 2 +-
> arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts | 5 +++++
> arch/arm/boot/dts/armada-xp.dtsi | 2 +-
> 4 files changed, 12 insertions(+), 2 deletions(-)
>
> --
> 2.15.1
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Arnd Bergmann @ 2018-01-11 9:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111084128.GA16780@kroah.com>
On Thu, Jan 11, 2018 at 9:41 AM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Thu, Jan 11, 2018 at 12:28:48AM -0800, Joel Stanley wrote:
>> On Wed, Jan 10, 2018 at 11:30 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
>> > On Wed, Jan 10, 2018 at 01:46:34PM -0800, Jae Hyun Yoo wrote:
>> >> Thanks for your pointing it out and I totally agree with you. Actually, we
>> >> are preparing 4.13 update for now and an another update will be followed up.
>> >> As I answered above, I'll rebase this patch set onto the latest kernel.org
>> >> mainline. Sorry for my misunderstanding of upstream process.
>> >
>> > 4.13? Why that kernel? It too is obsolete and insecure and
>> > unsupported.
>>
>> It contains support for our hardware that I have integrated from work
>> in progress patches and upstream commits.
>>
>> The OpenBMC project, with myself as the kernel maintainer, have
>> intentions to regularly move to upstream releases. This takes time and
>> effort. This time and effort is balanced with submitting our drivers
>> upstream.
>
> Of course, but please do not have your "users" use a kernel that is
> known to have bugs and can not be supported. That would not be good at
> all, don't you think?
I've been pretty happy with the progress in merging drivers upstream
for OpenBMC. Of course things always take longer than planned,
but they are getting there. Most servers today are probably running
the aspeed vendor kernel based on linux-2.6.28.10, at least that's
what my workstation runs (and no, I did not connect the BMC to my
home network).
The particular choices of mainline versions (4.10 and 4.13) may be
unfortunate as they are both one off from a longterm release, but
not being stuck on 2.6 is the important first step in order to upstream
stuff.
>> Another silicon vendor has recently joined the project and that brings
>> an entire SoC that is not upstream. We have patches on the ARM that
>> are under review for this SoC, with more drivers undergoing cleanup in
>> order to submit them to the relevant maintainers.
>
> Why are you merging all SoC trees together into one place? That seems
> like a nightmare to manage, especially with git.
Why would anyone want to have multiple kernel trees just to run
things on different SoCs? ;-)
It's just a collection of device drivers in different stages of getting
upstreamed.
>> > And if you do have out-of-tree code, why not use a process that makes it
>> > trivial to update the base kernel version so that you can keep up to
>> > date very easily? (hint, just using 'git' is not a good way to do
>> > this...)
>>
>> We have a process that we've been developing under for the past few
>> years. I find git to be a great tool for managing Linux kernel trees.
>>
>> What would you recommend for managing kernel trees?
>
> quilt is best for a tree that you can not rebase (i.e. a public git
> tree). Otherwise you end up getting patches all mushed together and
> hard to extract in any simple way.
I'm ususally happy with having git with topic branches to make the
rebasing easier. In many cases, you can just leave a topic branch
for a particular subsystem unchanged between versions and just
merge the latest version of those branches until the branch goes
away after upstreaming.
Arnd
^ permalink raw reply
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Benjamin Herrenschmidt @ 2018-01-11 9:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111084128.GA16780@kroah.com>
On Thu, 2018-01-11 at 09:41 +0100, Greg KH wrote:
> On Thu, Jan 11, 2018 at 12:28:48AM -0800, Joel Stanley wrote:
> > On Wed, Jan 10, 2018 at 11:30 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> > > On Wed, Jan 10, 2018 at 01:46:34PM -0800, Jae Hyun Yoo wrote:
> > > > Thanks for your pointing it out and I totally agree with you. Actually, we
> > > > are preparing 4.13 update for now and an another update will be followed up.
> > > > As I answered above, I'll rebase this patch set onto the latest kernel.org
> > > > mainline. Sorry for my misunderstanding of upstream process.
> > >
> > > 4.13? Why that kernel? It too is obsolete and insecure and
> > > unsupported.
> >
> > It contains support for our hardware that I have integrated from work
> > in progress patches and upstream commits.
> >
> > The OpenBMC project, with myself as the kernel maintainer, have
> > intentions to regularly move to upstream releases. This takes time and
> > effort. This time and effort is balanced with submitting our drivers
> > upstream.
>
> Of course, but please do not have your "users" use a kernel that is
> known to have bugs and can not be supported. That would not be good at
> all, don't you think?
There is little choice, we don't have the manpower to rewrite/upstream
all the drivers in a day, and rebasing to newer kernel takes time due
to various dependencies, testing requirements etc.
That being said, 4.13 is N-1, not too bad.
> > > What keeps you all from just always tracking the latest tree from Linus?
> >
> > Linus' tree does not contain all of the drivers required to boot
> > systems. Many of them are still under review on lkml, and others still
> > require rewrite from the vendor tree.
>
> Merging vendor trees into your tree has got to be a complicated mess.
> Why try to keep it all together in one place?
There are no vendor trees to speak of that we could merge. At least not
yet. We've been teaching vendors about doing proper drivers that can
work with upstream, device-tree based platforms etc... but it takes
time for them to get up to speed.
So while we are rewriting the drivers (sometimes with the vendor's
help), we keep a tree with the "sub-standard" ones hacked up to work on
our DT based platform and with our other bits and pieces until we can
ditch it.
> And who is responsible for getting the vendor code upstream? The
> individual drivers? Individual driver submissions should be quite easy,
> what is preventing them from getting merged?
It just takes time Greg. The original vendor drivers are in no shape to
get anywhere near upstream. They have to be mostly rewritten one by
one. Sometimes we can teach the vendor and help them along, some times
we do it ourselves, but it's a time consuming process. It took 2 or 3
kernel versions just to get the clk drivers that Joel had written
upstream for example. It took me a long time as well to get ftgmac100
sorted.
> > > What is in your tree that is not upstream that requires you to have a
> > > kernel tree at all?
> >
> > We have PECI, video compression, crypto, USB CDC, DRM (graphics),
> > serial GPIO, LPC mailbox for the ASPEED SoC.
>
> What "USB CDC" do you have that is not upstream?
See my other email :)
> I'll pick on this one
> specifically as I don't think I've seen any patches recently submitted
> for that driver at all. Am I just missing them?
>
> The other ones should also all be easy to get merged, with maybe the
> exception of the drm stuff due to the speed that subsystem moves at.
> But even there, the community is very helpful in getting stuff upstream,
> have you asked for help?
We can't expect the community to rewrite the drivers for us. Some of
the clk and pinmux stuff is intrinsically very complex, and took time
(and we did get valuable feedback).
Now that these basic pieces of infrastructure are in, it's a matter of
tackling the remaining drivers one at a time.
> > Another silicon vendor has recently joined the project and that brings
> > an entire SoC that is not upstream. We have patches on the ARM that
> > are under review for this SoC, with more drivers undergoing cleanup in
> > order to submit them to the relevant maintainers.
>
> Why are you merging all SoC trees together into one place? That seems
> like a nightmare to manage, especially with git.
There are no SoC trees per-se.
There is the OpenBMC tree which has hand-hacked vendor drivers plugged
into it, which are going away one at a time as we clean them up.
There's really one SoC family only in use (aspeed) at the moment with
one other coming around the corner (Nuvoton). For the latter, my
understanding is that we are trying to get the vendor to get their
stuff upstream directly.
> > > And if you do have out-of-tree code, why not use a process that makes it
> > > trivial to update the base kernel version so that you can keep up to
> > > date very easily? (hint, just using 'git' is not a good way to do
> > > this...)
> >
> > We have a process that we've been developing under for the past few
> > years. I find git to be a great tool for managing Linux kernel trees.
> >
> > What would you recommend for managing kernel trees?
>
> quilt is best for a tree that you can not rebase (i.e. a public git
> tree). Otherwise you end up getting patches all mushed together and
> hard to extract in any simple way.
>
> Take a clue from the distros that have been managing kernels for decades
> and deal with an updated kernel all the time easily.
>
> Good luck, it sounds like you will need it :)
Nah, not luck, we just need to get those drivers done one at a time,
it's not a matter of luck.
And I find git to be just fine :)
Cheers,
Ben.
> thanks,
>
> greg k-h
^ permalink raw reply
* [PATCH v2 1/5] pinctrl: imx: use struct imx_pinctrl_soc_info as a const
From: Linus Walleij @ 2018-01-11 9:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180106142553.15322-2-stefan@agner.ch>
On Sat, Jan 6, 2018 at 3:25 PM, Stefan Agner <stefan@agner.ch> wrote:
> For some SoCs the struct imx_pinctrl_soc_info is passed through
> of_device_id.data which is const. Most variables are already const
> or otherwise not written. However, some fields are modified at
> runtime. Move those fields to the dynamically allocated struct
> imx_pinctrl.
>
> Fixes: b3060044e495 ("pinctrl: freescale: imx7d: make of_device_ids const")
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Arvind Yadav <arvind.yadav.cs@gmail.com>
> Cc: Dong Aisheng <aisheng.dong@nxp.com>
> Cc: Gary Bisson <gary.bisson@boundarydevices.com>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2 2/5] pinctrl: imx7d: simplify imx7d_pinctrl_probe
From: Linus Walleij @ 2018-01-11 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180106142553.15322-3-stefan@agner.ch>
On Sat, Jan 6, 2018 at 3:25 PM, Stefan Agner <stefan@agner.ch> wrote:
> Using of_device_get_match_data in imx7d_pinctrl_probe simplifies
> the function. Also get rid of the void pointer cast since
> imx_pinctrl_probe now accepts const struct imx_pinctrl_soc_info.
>
> Cc: Arvind Yadav <arvind.yadav.cs@gmail.com>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2 3/5] pinctrl: imx: constify struct imx_pinctrl_soc_info
From: Linus Walleij @ 2018-01-11 9:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180106142553.15322-4-stefan@agner.ch>
On Sat, Jan 6, 2018 at 3:25 PM, Stefan Agner <stefan@agner.ch> wrote:
> Now that imx_pinctrl_probe accepts const struct imx_pinctrl_soc_info
> we can constify all declarations of struct imx_pinctrl_soc_info.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2 4/5] pinctrl: imx7ulp: constify struct imx_cfg_params_decode
From: Linus Walleij @ 2018-01-11 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180106142553.15322-5-stefan@agner.ch>
On Sat, Jan 6, 2018 at 3:25 PM, Stefan Agner <stefan@agner.ch> wrote:
> The decode parameters are constant mark them const.
>
> Cc: Dong Aisheng <aisheng.dong@nxp.com>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox