* [PATCH 01/29] pm: Add PM domain notifications
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 02/29] ARM: Exynos: bind power domains earlier, on device creation Marek Szyprowski
` (28 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
This patch adds notifiers to the runtime PM/genpd subsystem. It is now
possible to register a notifier, which will be called before and after
the generic power domain subsystem calls the power domain's power_on
and power_off callbacks.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Documentation/power/notifiers.txt | 14 ++++++++
drivers/base/power/domain.c | 70 ++++++++++++++++++++++++++++++++++++---
include/linux/pm.h | 2 ++
include/linux/pm_domain.h | 19 +++++++++++
4 files changed, 101 insertions(+), 4 deletions(-)
diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt
index a81fa25..62303f6 100644
--- a/Documentation/power/notifiers.txt
+++ b/Documentation/power/notifiers.txt
@@ -53,3 +53,17 @@ NULL). To register and/or unregister a suspend notifier use the functions
register_pm_notifier() and unregister_pm_notifier(), respectively, defined in
include/linux/suspend.h . If you don't need to unregister the notifier, you can
also use the pm_notifier() macro defined in include/linux/suspend.h .
+
+Power Domain notifiers
+----------------------
+
+The power domain notifiers allow subsystems or drivers to register for power
+domain on/off notifications, should they need to perform any actions right
+before or right after the power domain on/off. The device must be already
+added to a power domain before its subsystem or driver registers the notifier.
+Following events are supported:
+
+PM_GENPD_POWER_ON_PREPARE The power domain is about to turn on.
+PM_GENPD_POST_POWER_ON The power domain has just turned on.
+PM_GENPD_POWER_OFF_PREPARE The power domain is about to turn off.
+PM_GENPD_POST_POWER_OFF The power domain has just turned off.
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index eee55c1..5fe0966 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -70,6 +70,45 @@ static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
return genpd;
}
+int pm_genpd_register_notifier(struct device *dev, struct notifier_block *nb)
+{
+ struct pm_domain_data *pdd;
+ int ret = -EINVAL;
+
+ spin_lock_irq(&dev->power.lock);
+ if (dev->power.subsys_data) {
+ pdd = dev->power.subsys_data->domain_data;
+ ret = blocking_notifier_chain_register(&pdd->notify_chain_head,
+ nb);
+ }
+ spin_unlock_irq(&dev->power.lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pm_genpd_register_notifier);
+
+void pm_genpd_unregister_notifier(struct device *dev, struct notifier_block *nb)
+{
+ struct pm_domain_data *pdd;
+
+ spin_lock_irq(&dev->power.lock);
+ if (dev->power.subsys_data) {
+ pdd = dev->power.subsys_data->domain_data;
+ blocking_notifier_chain_unregister(&pdd->notify_chain_head, nb);
+ }
+ spin_unlock_irq(&dev->power.lock);
+}
+EXPORT_SYMBOL_GPL(pm_genpd_unregister_notifier);
+
+static void pm_genpd_notifier_call(unsigned long event,
+ struct generic_pm_domain *genpd)
+{
+ struct pm_domain_data *pdd;
+
+ list_for_each_entry(pdd, &genpd->dev_list, list_node)
+ blocking_notifier_call_chain(&pdd->notify_chain_head,
+ event, pdd->dev);
+}
+
#ifdef CONFIG_PM
struct generic_pm_domain *dev_to_genpd(struct device *dev)
@@ -231,10 +270,14 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
ktime_t time_start = ktime_get();
s64 elapsed_ns;
+ pm_genpd_notifier_call(PM_GENPD_POWER_ON_PREPARE, genpd);
+
ret = genpd->power_on(genpd);
if (ret)
goto err;
+ pm_genpd_notifier_call(PM_GENPD_POST_POWER_ON, genpd);
+
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns > genpd->power_on_latency_ns) {
genpd->power_on_latency_ns = elapsed_ns;
@@ -554,13 +597,17 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
* the pm_genpd_poweron() restore power for us (this shouldn't
* happen very often).
*/
+ pm_genpd_notifier_call(PM_GENPD_POWER_OFF_PREPARE, genpd);
+
ret = genpd->power_off(genpd);
if (ret == -EBUSY) {
genpd_set_active(genpd);
goto out;
}
-
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
+
+ pm_genpd_notifier_call(PM_GENPD_POST_POWER_OFF, genpd);
+
if (elapsed_ns > genpd->power_off_latency_ns) {
genpd->power_off_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
@@ -837,9 +884,13 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
|| atomic_read(&genpd->sd_count) > 0)
return;
- if (genpd->power_off)
+ if (genpd->power_off) {
+ pm_genpd_notifier_call(PM_GENPD_POWER_OFF_PREPARE, genpd);
genpd->power_off(genpd);
+ pm_genpd_notifier_call(PM_GENPD_POST_POWER_OFF, genpd);
+ }
+
genpd->status = GPD_STATE_POWER_OFF;
list_for_each_entry(link, &genpd->slave_links, slave_node) {
@@ -869,8 +920,11 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
genpd_sd_counter_inc(link->master);
}
- if (genpd->power_on)
+ if (genpd->power_on) {
+ pm_genpd_notifier_call(PM_GENPD_POWER_ON_PREPARE, genpd);
genpd->power_on(genpd);
+ pm_genpd_notifier_call(PM_GENPD_POST_POWER_ON, genpd);
+ }
genpd->status = GPD_STATE_ACTIVE;
}
@@ -1292,9 +1346,16 @@ static int pm_genpd_restore_noirq(struct device *dev)
* If the domain was off before the hibernation, make
* sure it will be off going forward.
*/
- if (genpd->power_off)
+ if (genpd->power_off) {
+ pm_genpd_notifier_call(PM_GENPD_POWER_OFF_PREPARE,
+ genpd);
+
genpd->power_off(genpd);
+ pm_genpd_notifier_call(PM_GENPD_POST_POWER_OFF,
+ genpd);
+ }
+
return 0;
}
}
@@ -1467,6 +1528,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
spin_unlock_irq(&dev->power.lock);
mutex_lock(&gpd_data->lock);
+ BLOCKING_INIT_NOTIFIER_HEAD(&gpd_data->base.notify_chain_head);
gpd_data->base.dev = dev;
list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 72c0fe0..bfc55d4 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -22,6 +22,7 @@
#define _LINUX_PM_H
#include <linux/list.h>
+#include <linux/notifier.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
@@ -542,6 +543,7 @@ struct wakeup_source;
struct pm_domain_data {
struct list_head list_node;
struct device *dev;
+ struct blocking_notifier_head notify_chain_head;
};
struct pm_subsys_data {
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7c1d252..569ab16 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -17,6 +17,12 @@
#include <linux/notifier.h>
#include <linux/cpuidle.h>
+/* PM domain state transition notifications */
+#define PM_GENPD_POWER_ON_PREPARE 0x01
+#define PM_GENPD_POST_POWER_ON 0x02
+#define PM_GENPD_POWER_OFF_PREPARE 0x03
+#define PM_GENPD_POST_POWER_OFF 0x04
+
enum gpd_status {
GPD_STATE_ACTIVE = 0, /* PM domain is active */
GPD_STATE_WAIT_MASTER, /* PM domain's master is being waited for */
@@ -167,6 +173,11 @@ extern int pm_genpd_name_poweron(const char *domain_name);
extern bool default_stop_ok(struct device *dev);
+extern int pm_genpd_register_notifier(struct device *dev,
+ struct notifier_block *nb);
+extern void pm_genpd_unregister_notifier(struct device *dev,
+ struct notifier_block *nb);
+
extern struct dev_power_governor pm_domain_always_on_gov;
#else
@@ -259,6 +270,14 @@ static inline bool default_stop_ok(struct device *dev)
{
return false;
}
+static inline int pm_genpd_register_notifier(struct device *dev,
+ struct notifier_block *nb)
+{
+ return -ENOSYS;
+}
+static inline void pm_genpd_unregister_notifier(struct device *dev,
+ struct notifier_block *nb) {}
+
#define simple_qos_governor NULL
#define pm_domain_always_on_gov NULL
#endif
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 02/29] ARM: Exynos: bind power domains earlier, on device creation
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
2014-08-05 10:47 ` [PATCH 01/29] pm: Add PM domain notifications Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 03/29] clk: exynos: add missing smmu_g2d clock and update comments Marek Szyprowski
` (27 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patches change initialization time of power domain driver from client
device driver bind to device creation. This lets other core drivers to
register power domain notifiers before client driver is bound.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/mach-exynos/pm_domains.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index fd76e1b..1d368a2 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -159,13 +159,13 @@ static int exynos_pm_notifier_call(struct notifier_block *nb,
struct device *dev = data;
switch (event) {
- case BUS_NOTIFY_BIND_DRIVER:
+ case BUS_NOTIFY_ADD_DEVICE:
if (dev->of_node)
exynos_read_domain_from_dt(dev);
break;
- case BUS_NOTIFY_UNBOUND_DRIVER:
+ case BUS_NOTIFY_DEL_DEVICE:
exynos_remove_device_from_domain(dev);
break;
@@ -177,6 +177,13 @@ static struct notifier_block platform_nb = {
.notifier_call = exynos_pm_notifier_call,
};
+static int exynos_pm_domain_add(struct device *dev, void *priv)
+{
+ if (dev->of_node)
+ exynos_read_domain_from_dt(dev);
+ return 0;
+}
+
static __init int exynos4_pm_init_power_domain(void)
{
struct platform_device *pdev;
@@ -236,6 +243,7 @@ no_clk:
}
bus_register_notifier(&platform_bus_type, &platform_nb);
+ bus_for_each_dev(&platform_bus_type, NULL, NULL, exynos_pm_domain_add);
return 0;
}
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 03/29] clk: exynos: add missing smmu_g2d clock and update comments
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
2014-08-05 10:47 ` [PATCH 01/29] pm: Add PM domain notifications Marek Szyprowski
2014-08-05 10:47 ` [PATCH 02/29] ARM: Exynos: bind power domains earlier, on device creation Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-18 11:26 ` Tomasz Figa
2014-08-05 10:47 ` [PATCH 04/29] drivers: base: add notifier for failed driver bind Marek Szyprowski
` (26 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds missing smmu_g2d clock implementation and updates
comment about Exynos4 clocks from 278-282 range. Those clocks are
available on all Exynos4 SoC series, so the misleading comment has been
removed.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/clk/samsung/clk-exynos4.c | 1 +
include/dt-bindings/clock/exynos4.h | 10 +++++-----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index ac163d7..12a7cc3 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1183,6 +1183,7 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
+ GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", GATE_IP_DMC, 24, 0, 0),
GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0,
0),
};
diff --git a/include/dt-bindings/clock/exynos4.h b/include/dt-bindings/clock/exynos4.h
index 459bd2b..fb981635 100644
--- a/include/dt-bindings/clock/exynos4.h
+++ b/include/dt-bindings/clock/exynos4.h
@@ -115,11 +115,11 @@
#define CLK_SMMU_MFCR 275
#define CLK_G3D 276
#define CLK_G2D 277
-#define CLK_ROTATOR 278 /* Exynos4210 only */
-#define CLK_MDMA 279 /* Exynos4210 only */
-#define CLK_SMMU_G2D 280 /* Exynos4210 only */
-#define CLK_SMMU_ROTATOR 281 /* Exynos4210 only */
-#define CLK_SMMU_MDMA 282 /* Exynos4210 only */
+#define CLK_ROTATOR 278
+#define CLK_MDMA 279
+#define CLK_SMMU_G2D 280
+#define CLK_SMMU_ROTATOR 281
+#define CLK_SMMU_MDMA 282
#define CLK_FIMD0 283
#define CLK_MIE0 284
#define CLK_MDNIE0 285 /* Exynos4412 only */
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH 03/29] clk: exynos: add missing smmu_g2d clock and update comments
2014-08-05 10:47 ` [PATCH 03/29] clk: exynos: add missing smmu_g2d clock and update comments Marek Szyprowski
@ 2014-08-18 11:26 ` Tomasz Figa
0 siblings, 0 replies; 50+ messages in thread
From: Tomasz Figa @ 2014-08-18 11:26 UTC (permalink / raw)
To: Marek Szyprowski, iommu, linux-samsung-soc, linux-arm-kernel,
linux-kernel
Cc: linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae,
Kukjin Kim, Sylwester Nawrocki, Kyungmin Park
On 05.08.2014 12:47, Marek Szyprowski wrote:
> This patch adds missing smmu_g2d clock implementation and updates
> comment about Exynos4 clocks from 278-282 range. Those clocks are
> available on all Exynos4 SoC series, so the misleading comment has been
> removed.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/clk/samsung/clk-exynos4.c | 1 +
> include/dt-bindings/clock/exynos4.h | 10 +++++-----
> 2 files changed, 6 insertions(+), 5 deletions(-)
Acked-by: Tomasz Figa <t.figa@samsung.com>
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH 04/29] drivers: base: add notifier for failed driver bind
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (2 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 03/29] clk: exynos: add missing smmu_g2d clock and update comments Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-21 19:46 ` Laurent Pinchart
` (2 more replies)
2014-08-05 10:47 ` [PATCH 05/29] drivers: convert suppress_bind_attrs parameter into flags Marek Szyprowski
` (25 subsequent siblings)
29 siblings, 3 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds support for getting a notify for failed device driver
bind, so all the items done in BUS_NOTIFY_BIND_DRIVER event can be
cleaned if the driver fails to bind.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/base/dd.c | 10 +++++++---
include/linux/device.h | 4 +++-
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index e4ffbcf..541a41f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -237,10 +237,14 @@ static int driver_sysfs_add(struct device *dev)
return ret;
}
-static void driver_sysfs_remove(struct device *dev)
+static void driver_sysfs_remove(struct device *dev, int failed)
{
struct device_driver *drv = dev->driver;
+ if (failed && dev->bus)
+ blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+ BUS_NOTIFY_DRVBIND_FAILED, dev);
+
if (drv) {
sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
sysfs_remove_link(&dev->kobj, "driver");
@@ -316,7 +320,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
probe_failed:
devres_release_all(dev);
- driver_sysfs_remove(dev);
+ driver_sysfs_remove(dev, true);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
@@ -509,7 +513,7 @@ static void __device_release_driver(struct device *dev)
if (drv) {
pm_runtime_get_sync(dev);
- driver_sysfs_remove(dev);
+ driver_sysfs_remove(dev, false);
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
diff --git a/include/linux/device.h b/include/linux/device.h
index b387710..92daded 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -176,7 +176,7 @@ extern int bus_register_notifier(struct bus_type *bus,
extern int bus_unregister_notifier(struct bus_type *bus,
struct notifier_block *nb);
-/* All 4 notifers below get called with the target struct device *
+/* All 7 notifers below get called with the target struct device *
* as an argument. Note that those functions are likely to be called
* with the device lock held in the core, so be careful.
*/
@@ -189,6 +189,8 @@ extern int bus_unregister_notifier(struct bus_type *bus,
unbound */
#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000006 /* driver is unbound
from the device */
+#define BUS_NOTIFY_DRVBIND_FAILED 0x00000007 /* driver failed to bind
+ to device */
extern struct kset *bus_get_kset(struct bus_type *bus);
extern struct klist *bus_get_device_klist(struct bus_type *bus);
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH 04/29] drivers: base: add notifier for failed driver bind
2014-08-05 10:47 ` [PATCH 04/29] drivers: base: add notifier for failed driver bind Marek Szyprowski
@ 2014-08-21 19:46 ` Laurent Pinchart
2014-08-25 20:05 ` Greg Kroah-Hartman
2014-08-25 21:18 ` Joerg Roedel
2 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2014-08-21 19:46 UTC (permalink / raw)
To: Marek Szyprowski
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Thierry Reding, Olof Johansson, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hi Marek,
Thank you for the patch.
On Tuesday 05 August 2014 12:47:32 Marek Szyprowski wrote:
> This patch adds support for getting a notify for failed device driver
> bind, so all the items done in BUS_NOTIFY_BIND_DRIVER event can be
> cleaned if the driver fails to bind.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/base/dd.c | 10 +++++++---
> include/linux/device.h | 4 +++-
> 2 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index e4ffbcf..541a41f 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -237,10 +237,14 @@ static int driver_sysfs_add(struct device *dev)
> return ret;
> }
>
> -static void driver_sysfs_remove(struct device *dev)
> +static void driver_sysfs_remove(struct device *dev, int failed)
> {
> struct device_driver *drv = dev->driver;
>
> + if (failed && dev->bus)
> + blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> + BUS_NOTIFY_DRVBIND_FAILED, dev);
This might be a stupid question, but as you only call driver_sysfs_remove with
failed set to true in a single location (in the failure path of really_probe),
how about moving the blocking_notifier_call_chain to that location ? The code
seems to be a bit out of place here.
> +
> if (drv) {
> sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
> sysfs_remove_link(&dev->kobj, "driver");
> @@ -316,7 +320,7 @@ static int really_probe(struct device *dev, struct
> device_driver *drv)
>
> probe_failed:
> devres_release_all(dev);
> - driver_sysfs_remove(dev);
> + driver_sysfs_remove(dev, true);
> dev->driver = NULL;
> dev_set_drvdata(dev, NULL);
>
> @@ -509,7 +513,7 @@ static void __device_release_driver(struct device *dev)
> if (drv) {
> pm_runtime_get_sync(dev);
>
> - driver_sysfs_remove(dev);
> + driver_sysfs_remove(dev, false);
>
> if (dev->bus)
> blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> diff --git a/include/linux/device.h b/include/linux/device.h
> index b387710..92daded 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -176,7 +176,7 @@ extern int bus_register_notifier(struct bus_type *bus,
> extern int bus_unregister_notifier(struct bus_type *bus,
> struct notifier_block *nb);
>
> -/* All 4 notifers below get called with the target struct device *
> +/* All 7 notifers below get called with the target struct device *
> * as an argument. Note that those functions are likely to be called
> * with the device lock held in the core, so be careful.
> */
> @@ -189,6 +189,8 @@ extern int bus_unregister_notifier(struct bus_type *bus,
> unbound */
> #define BUS_NOTIFY_UNBOUND_DRIVER 0x00000006 /* driver is unbound
> from the device */
> +#define BUS_NOTIFY_DRVBIND_FAILED 0x00000007 /* driver failed to bind
> + to device */
>
> extern struct kset *bus_get_kset(struct bus_type *bus);
> extern struct klist *bus_get_device_klist(struct bus_type *bus);
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 04/29] drivers: base: add notifier for failed driver bind
2014-08-05 10:47 ` [PATCH 04/29] drivers: base: add notifier for failed driver bind Marek Szyprowski
2014-08-21 19:46 ` Laurent Pinchart
@ 2014-08-25 20:05 ` Greg Kroah-Hartman
2014-08-26 6:23 ` Marek Szyprowski
2014-08-25 21:18 ` Joerg Roedel
2 siblings, 1 reply; 50+ messages in thread
From: Greg Kroah-Hartman @ 2014-08-25 20:05 UTC (permalink / raw)
To: Marek Szyprowski
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
On Tue, Aug 05, 2014 at 12:47:32PM +0200, Marek Szyprowski wrote:
> This patch adds support for getting a notify for failed device driver
> bind, so all the items done in BUS_NOTIFY_BIND_DRIVER event can be
> cleaned if the driver fails to bind.
But doesn't the bus know if the driver fails to bind, so why would a
notifier be needed here? Can't it unwind any problems then?
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/base/dd.c | 10 +++++++---
> include/linux/device.h | 4 +++-
> 2 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index e4ffbcf..541a41f 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -237,10 +237,14 @@ static int driver_sysfs_add(struct device *dev)
> return ret;
> }
>
> -static void driver_sysfs_remove(struct device *dev)
> +static void driver_sysfs_remove(struct device *dev, int failed)
I _hate_ having functions with a flag that does something different
depending on it. If you _really_ need this, just make the notifier call
before calling this function, which should work just fine, right?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 04/29] drivers: base: add notifier for failed driver bind
2014-08-25 20:05 ` Greg Kroah-Hartman
@ 2014-08-26 6:23 ` Marek Szyprowski
0 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-26 6:23 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hello,
On 2014-08-25 22:05, Greg Kroah-Hartman wrote:
> On Tue, Aug 05, 2014 at 12:47:32PM +0200, Marek Szyprowski wrote:
>> This patch adds support for getting a notify for failed device driver
>> bind, so all the items done in BUS_NOTIFY_BIND_DRIVER event can be
>> cleaned if the driver fails to bind.
> But doesn't the bus know if the driver fails to bind, so why would a
> notifier be needed here? Can't it unwind any problems then?
Some other subsystems (like IOMMU) might register its own notifiers on
the given bus. Such notifier is called before driver probe
(BUS_NOTIFY_BIND_DRIVER event), so one can allocate some resources there.
However there is no way to do the cleanup if the driver fails to bind,
because no notifier is called in such case.
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>> drivers/base/dd.c | 10 +++++++---
>> include/linux/device.h | 4 +++-
>> 2 files changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
>> index e4ffbcf..541a41f 100644
>> --- a/drivers/base/dd.c
>> +++ b/drivers/base/dd.c
>> @@ -237,10 +237,14 @@ static int driver_sysfs_add(struct device *dev)
>> return ret;
>> }
>>
>> -static void driver_sysfs_remove(struct device *dev)
>> +static void driver_sysfs_remove(struct device *dev, int failed)
> I _hate_ having functions with a flag that does something different
> depending on it. If you _really_ need this, just make the notifier call
> before calling this function, which should work just fine, right?
Ok, I will fix this. If I remember correctly I followed the
driver_sysfs_add()
function pattern, which (surprisingly, especially when one considers only
the function name) also calls the bus notifiers.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 04/29] drivers: base: add notifier for failed driver bind
2014-08-05 10:47 ` [PATCH 04/29] drivers: base: add notifier for failed driver bind Marek Szyprowski
2014-08-21 19:46 ` Laurent Pinchart
2014-08-25 20:05 ` Greg Kroah-Hartman
@ 2014-08-25 21:18 ` Joerg Roedel
2014-08-26 6:30 ` Marek Szyprowski
2 siblings, 1 reply; 50+ messages in thread
From: Joerg Roedel @ 2014-08-25 21:18 UTC (permalink / raw)
To: Marek Szyprowski
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
On Tue, Aug 05, 2014 at 12:47:32PM +0200, Marek Szyprowski wrote:
> + if (failed && dev->bus)
> + blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> + BUS_NOTIFY_DRVBIND_FAILED, dev);
> +
Why can't you just use the notifier for BUS_NOTIFY_UNBIND_DRIVER or
BUS_NOTIFY_UNBOUND_DRIVER when something goes wrong in driver
initialization?
Joerg
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 04/29] drivers: base: add notifier for failed driver bind
2014-08-25 21:18 ` Joerg Roedel
@ 2014-08-26 6:30 ` Marek Szyprowski
0 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-26 6:30 UTC (permalink / raw)
To: Joerg Roedel
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hello,
On 2014-08-25 23:18, Joerg Roedel wrote:
> On Tue, Aug 05, 2014 at 12:47:32PM +0200, Marek Szyprowski wrote:
>> + if (failed && dev->bus)
>> + blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
>> + BUS_NOTIFY_DRVBIND_FAILED, dev);
>> +
> Why can't you just use the notifier for BUS_NOTIFY_UNBIND_DRIVER or
> BUS_NOTIFY_UNBOUND_DRIVER when something goes wrong in driver
> initialization?
Hmmm, you might be right. BUS_NOTIFY_UNBIND_DRIVER event happens before
unbinding
the driver, but BUS_NOTIFY_UNBOUND_DRIVER is called when driver remove
has been
finished, so it can be considered as a symmetrical pair for
BUS_NOTIFY_BIND_DRIVER.
Driver which registered bus notifiers is mainly interested in doing
right cleanup,
so the code executed for IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER and
IOMMU_GROUP_NOTIFY_DRVBIND_FAILED is same.
I will remove this additional event and simply add a call to
BUS_NOTIFY_UNBOUND_DRIVER event when driver probe fails.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH 05/29] drivers: convert suppress_bind_attrs parameter into flags
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (3 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 04/29] drivers: base: add notifier for failed driver bind Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 06/29] drivers: iommu: add notify about failed bind Marek Szyprowski
` (24 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch extends struct device_driver with a flags member and converts
existing suppress_bind_attrs bool field to a flag. This way new flags
can be easily added in the future without changing the structure itself.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/mach-integrator/impd1.c | 2 +-
drivers/base/bus.c | 4 ++--
drivers/base/platform.c | 2 +-
drivers/pci/host/pci-mvebu.c | 2 +-
drivers/pci/host/pci-rcar-gen2.c | 2 +-
drivers/pci/host/pci-tegra.c | 2 +-
drivers/pci/host/pcie-rcar.c | 2 +-
drivers/soc/tegra/pmc.c | 2 +-
include/linux/device.h | 6 ++++--
9 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 3ce8807..a7e7330 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -406,7 +406,7 @@ static struct lm_driver impd1_driver = {
* As we're dropping the probe() function, suppress driver
* binding from sysfs.
*/
- .suppress_bind_attrs = true,
+ .flags = DRIVER_SUPPRESS_BIND_ATTRS,
},
.probe = impd1_probe,
.remove = impd1_remove,
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 83e910a..f223f26 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -707,7 +707,7 @@ int bus_add_driver(struct device_driver *drv)
__func__, drv->name);
}
- if (!drv->suppress_bind_attrs) {
+ if (!(drv->flags & DRIVER_SUPPRESS_BIND_ATTRS)) {
error = add_bind_files(drv);
if (error) {
/* Ditto */
@@ -740,7 +740,7 @@ void bus_remove_driver(struct device_driver *drv)
if (!drv->bus)
return;
- if (!drv->suppress_bind_attrs)
+ if (!(drv->flags & DRIVER_SUPPRESS_BIND_ATTRS))
remove_bind_files(drv);
driver_remove_groups(drv, drv->bus->drv_groups);
driver_remove_file(drv, &driver_attr_uevent);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 68a8b77..c696058 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -608,7 +608,7 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
drv->prevent_deferred_probe = true;
/* make sure driver won't have bind/unbind attributes */
- drv->driver.suppress_bind_attrs = true;
+ drv->driver.flags = DRIVER_SUPPRESS_BIND_ATTRS;
/* temporary section violation during probe() */
drv->probe = probe;
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index a8c6f1a..6815c50 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -1086,7 +1086,7 @@ static struct platform_driver mvebu_pcie_driver = {
.name = "mvebu-pcie",
.of_match_table = mvebu_pcie_of_match_table,
/* driver unloading/unbinding currently not supported */
- .suppress_bind_attrs = true,
+ .flags = DRIVER_SUPPRESS_BIND_ATTRS,
},
.probe = mvebu_pcie_probe,
};
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index 3ef854f..6f1b890 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -413,7 +413,7 @@ static struct platform_driver rcar_pci_driver = {
.driver = {
.name = "pci-rcar-gen2",
.owner = THIS_MODULE,
- .suppress_bind_attrs = true,
+ .flags = DRIVER_SUPPRESS_BIND_ATTRS,
.of_match_table = rcar_pci_of_match,
},
.probe = rcar_pci_probe,
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..2e1698d 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1927,7 +1927,7 @@ static struct platform_driver tegra_pcie_driver = {
.name = "tegra-pcie",
.owner = THIS_MODULE,
.of_match_table = tegra_pcie_of_match,
- .suppress_bind_attrs = true,
+ .flags = DRIVER_SUPPRESS_BIND_ATTRS,
},
.probe = tegra_pcie_probe,
};
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..9a1936e 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -981,7 +981,7 @@ static struct platform_driver rcar_pcie_driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = rcar_pcie_of_match,
- .suppress_bind_attrs = true,
+ .flags = DRIVER_SUPPRESS_BIND_ATTRS,
},
.probe = rcar_pcie_probe,
};
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index a2c0ceb..77c3eb3 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -892,7 +892,7 @@ static const struct of_device_id tegra_pmc_match[] = {
static struct platform_driver tegra_pmc_driver = {
.driver = {
.name = "tegra-pmc",
- .suppress_bind_attrs = true,
+ .flags = DRIVER_SUPPRESS_BIND_ATTRS,
.of_match_table = tegra_pmc_match,
.pm = &tegra_pmc_pm_ops,
},
diff --git a/include/linux/device.h b/include/linux/device.h
index 92daded..5f4ff02 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -201,7 +201,7 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus);
* @bus: The bus which the device of this driver belongs to.
* @owner: The module owner.
* @mod_name: Used for built-in modules.
- * @suppress_bind_attrs: Disables bind/unbind via sysfs.
+ * @flags: Flags defining driver behaviour, see below.
* @of_match_table: The open firmware table.
* @acpi_match_table: The ACPI match table.
* @probe: Called to query the existence of a specific device,
@@ -234,7 +234,7 @@ struct device_driver {
struct module *owner;
const char *mod_name; /* used for built-in modules */
- bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
+ unsigned long flags;
const struct of_device_id *of_match_table;
const struct acpi_device_id *acpi_match_table;
@@ -251,6 +251,8 @@ struct device_driver {
struct driver_private *p;
};
+/* disables bind/unbind via sysfs */
+#define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
extern int __must_check driver_register(struct device_driver *drv);
extern void driver_unregister(struct device_driver *drv);
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 06/29] drivers: iommu: add notify about failed bind
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (4 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 05/29] drivers: convert suppress_bind_attrs parameter into flags Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 07/29] ARM: dma-mapping: arm_iommu_attach_device: automatically set max_seg_size Marek Szyprowski
` (23 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds support for forwarding recently introduced
BUS_NOTIFY_DRVBIND_FAILED event to iommu groups. This lets us getting a
notify for failed device driver bind, so all the items done in
IOMMU_GROUP_NOTIFY_BIND_DRIVER event can be cleaned if the driver fails
to bind.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/iommu.c | 3 +++
include/linux/iommu.h | 1 +
2 files changed, 4 insertions(+)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1698360..516e93a 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -758,6 +758,9 @@ static int iommu_bus_notifier(struct notifier_block *nb,
case BUS_NOTIFY_UNBOUND_DRIVER:
group_action = IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER;
break;
+ case BUS_NOTIFY_DRVBIND_FAILED:
+ group_action = IOMMU_GROUP_NOTIFY_DRVBIND_FAILED;
+ break;
}
if (group_action)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 20f9a52..f9fdae5 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -139,6 +139,7 @@ struct iommu_ops {
#define IOMMU_GROUP_NOTIFY_BOUND_DRIVER 4 /* Post Driver bind */
#define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER 5 /* Pre Driver unbind */
#define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */
+#define IOMMU_GROUP_NOTIFY_DRVBIND_FAILED 7 /* Driver failed to bind */
extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
extern bool iommu_present(struct bus_type *bus);
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 07/29] ARM: dma-mapping: arm_iommu_attach_device: automatically set max_seg_size
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (5 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 06/29] drivers: iommu: add notify about failed bind Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 08/29] ARM: dma-mapping: add helpers for managing default per-device dma mappings Marek Szyprowski
` (22 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
If device has no max_seg_size set, we assume that there is no limit and
force it to DMA_BIT_MASK(32) to always use contiguous mappings in DMA
address space.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/mm/dma-mapping.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7a996aa..8161102 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2051,6 +2051,22 @@ int arm_iommu_attach_device(struct device *dev,
{
int err;
+ /*
+ * if device has no max_seg_size set, we assume that there is no limit
+ * and force it to DMA_BIT_MASK(32) to always use contiguous mappings
+ * in DMA address space
+ */
+ if (!dev->dma_parms) {
+ dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
+ if (!dev->dma_parms)
+ return -ENOMEM;
+ }
+ if (!dev->dma_parms->max_segment_size) {
+ err = dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
+ }
+
err = iommu_attach_device(mapping->domain, dev);
if (err)
return err;
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 08/29] ARM: dma-mapping: add helpers for managing default per-device dma mappings
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (6 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 07/29] ARM: dma-mapping: arm_iommu_attach_device: automatically set max_seg_size Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 09/29] ARM: dma-mapping: provide stubs if no ARM_DMA_USE_IOMMU has been selected Marek Szyprowski
` (21 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds 2 helpers: arm_iommu_create_default_mapping and
arm_iommu_release_default_mapping for managing default iommu-based
dma-mapping address space, created for exlusive use only by the given
device. Those helpers are convenient for setting up iommu-based
dma-mapping for most typical devices in the system.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/include/asm/dma-iommu.h | 5 +++++
arch/arm/mm/dma-mapping.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index 8e3fcb9..ae3dac0 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -33,5 +33,10 @@ int arm_iommu_attach_device(struct device *dev,
struct dma_iommu_mapping *mapping);
void arm_iommu_detach_device(struct device *dev);
+int arm_iommu_create_default_mapping(struct device *dev, dma_addr_t base,
+ size_t size);
+
+void arm_iommu_release_default_mapping(struct device *dev);
+
#endif /* __KERNEL__ */
#endif
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 8161102..233a8cf 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2106,4 +2106,35 @@ void arm_iommu_detach_device(struct device *dev)
}
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
+int arm_iommu_create_default_mapping(struct device *dev, dma_addr_t base,
+ size_t size)
+{
+ struct dma_iommu_mapping *mapping;
+ int ret;
+
+ mapping = arm_iommu_create_mapping(dev->bus, base, size);
+ if (IS_ERR(mapping))
+ return PTR_ERR(mapping);
+
+ ret = arm_iommu_attach_device(dev, mapping);
+ if (ret) {
+ arm_iommu_release_mapping(mapping);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(arm_iommu_create_default_mapping);
+
+void arm_iommu_release_default_mapping(struct device *dev)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ if (!mapping)
+ return;
+
+ arm_iommu_detach_device(dev);
+ arm_iommu_release_mapping(mapping);
+}
+EXPORT_SYMBOL_GPL(arm_iommu_release_default_mapping);
+
#endif
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 09/29] ARM: dma-mapping: provide stubs if no ARM_DMA_USE_IOMMU has been selected
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (7 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 08/29] ARM: dma-mapping: add helpers for managing default per-device dma mappings Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag Marek Szyprowski
` (20 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch provides stubs returing errors for all iommu related arm
dma-mapping functions, which are used when CONFIG_ARM_DMA_USE_IOMMU is
not set. This let drivers to use common code for iommu and non-iommu
cases without additional ifdefs.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/include/asm/dma-iommu.h | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index ae3dac0..1e57569 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -9,6 +9,8 @@
#include <linux/kmemcheck.h>
#include <linux/kref.h>
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+
struct dma_iommu_mapping {
/* iommu specific data */
struct iommu_domain *domain;
@@ -38,5 +40,34 @@ int arm_iommu_create_default_mapping(struct device *dev, dma_addr_t base,
void arm_iommu_release_default_mapping(struct device *dev);
+#else
+
+static inline struct dma_iommu_mapping *
+arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void
+arm_iommu_release_mapping(struct dma_iommu_mapping *mapping) { }
+
+static inline int arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping)
+{
+ return -ENOSYS;
+}
+
+static inline void arm_iommu_detach_device(struct device *dev) { }
+
+static inline int arm_iommu_create_default_mapping(struct device *dev,
+ dma_addr_t base, size_t size)
+{
+ return -ENOSYS;
+}
+
+static inline void arm_iommu_release_default_mapping(struct device *dev) { }
+
+#endif
+
#endif /* __KERNEL__ */
#endif
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (8 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 09/29] ARM: dma-mapping: provide stubs if no ARM_DMA_USE_IOMMU has been selected Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-09-01 5:22 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 11/29] DRM: exynos: add DRIVER_HAS_OWN_IOMMU_MANAGER flag to all sub-drivers Marek Szyprowski
` (19 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds a new flags for device drivers. This flag instructs
kernel that the device driver does it own management of IOMMU assisted
IO address space translations, so no default dma-mapping structures
should be initialized.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
include/linux/device.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/device.h b/include/linux/device.h
index 5f4ff02..2e62371 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -253,6 +253,8 @@ struct device_driver {
/* disables bind/unbind via sysfs */
#define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
+/* driver uses own methods to manage IO address space */
+#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 << 1)
extern int __must_check driver_register(struct device_driver *drv);
extern void driver_unregister(struct device_driver *drv);
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-08-05 10:47 ` [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag Marek Szyprowski
@ 2014-09-01 5:22 ` Marek Szyprowski
2014-09-01 7:07 ` Thierry Reding
0 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-09-01 5:22 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae,
Kukjin Kim, Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hi Greg,
On 2014-08-05 12:47, Marek Szyprowski wrote:
> This patch adds a new flags for device drivers. This flag instructs
> kernel that the device driver does it own management of IOMMU assisted
> IO address space translations, so no default dma-mapping structures
> should be initialized.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> include/linux/device.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 5f4ff02..2e62371 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -253,6 +253,8 @@ struct device_driver {
>
> /* disables bind/unbind via sysfs */
> #define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
> +/* driver uses own methods to manage IO address space */
> +#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 << 1)
>
> extern int __must_check driver_register(struct device_driver *drv);
> extern void driver_unregister(struct device_driver *drv);
Could you comment if the approach of using flags in the struct driver
could be accepted? I've converted suppress_bind_attrs entry to flags to
avoid extending the structure, please see patch "[PATCH 05/29] drivers:
convert suppress_bind_attrs parameter into flags".
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 5:22 ` Marek Szyprowski
@ 2014-09-01 7:07 ` Thierry Reding
2014-09-01 7:53 ` Marek Szyprowski
0 siblings, 1 reply; 50+ messages in thread
From: Thierry Reding @ 2014-09-01 7:07 UTC (permalink / raw)
To: Marek Szyprowski
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
[-- Attachment #1: Type: text/plain, Size: 1855 bytes --]
On Mon, Sep 01, 2014 at 07:22:32AM +0200, Marek Szyprowski wrote:
> Hi Greg,
>
> On 2014-08-05 12:47, Marek Szyprowski wrote:
> > This patch adds a new flags for device drivers. This flag instructs
> > kernel that the device driver does it own management of IOMMU assisted
> > IO address space translations, so no default dma-mapping structures
> > should be initialized.
> >
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > ---
> > include/linux/device.h | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/include/linux/device.h b/include/linux/device.h
> > index 5f4ff02..2e62371 100644
> > --- a/include/linux/device.h
> > +++ b/include/linux/device.h
> > @@ -253,6 +253,8 @@ struct device_driver {
> >
> > /* disables bind/unbind via sysfs */
> > #define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
> > +/* driver uses own methods to manage IO address space */
> > +#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 << 1)
> >
> > extern int __must_check driver_register(struct device_driver *drv);
> > extern void driver_unregister(struct device_driver *drv);
>
> Could you comment if the approach of using flags in the struct driver
> could be accepted? I've converted suppress_bind_attrs entry to flags to
> avoid extending the structure, please see patch "[PATCH 05/29] drivers:
> convert suppress_bind_attrs parameter into flags".
Is this really necessary? What I did as part of an RFC series for Tegra
IOMMU support is keep this knowledge within the IOMMU driver rather than
export it to the driver core.
The idea being that the IOMMU driver wouldn't create an ARM DMA/IOMMU
mapping by default but rather allow individual drivers to be marked as
"kernel-internal" and use the DMA/IOMMU glue in that case. Drivers such
as DRM would use the IOMMU API directly.
Thierry
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 7:07 ` Thierry Reding
@ 2014-09-01 7:53 ` Marek Szyprowski
2014-09-01 9:38 ` Arnd Bergmann
0 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-09-01 7:53 UTC (permalink / raw)
To: Thierry Reding
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hello,
On 2014-09-01 09:07, Thierry Reding wrote:
> On Mon, Sep 01, 2014 at 07:22:32AM +0200, Marek Szyprowski wrote:
>> Hi Greg,
>>
>> On 2014-08-05 12:47, Marek Szyprowski wrote:
>>> This patch adds a new flags for device drivers. This flag instructs
>>> kernel that the device driver does it own management of IOMMU assisted
>>> IO address space translations, so no default dma-mapping structures
>>> should be initialized.
>>>
>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> ---
>>> include/linux/device.h | 2 ++
>>> 1 file changed, 2 insertions(+)
>>>
>>> diff --git a/include/linux/device.h b/include/linux/device.h
>>> index 5f4ff02..2e62371 100644
>>> --- a/include/linux/device.h
>>> +++ b/include/linux/device.h
>>> @@ -253,6 +253,8 @@ struct device_driver {
>>>
>>> /* disables bind/unbind via sysfs */
>>> #define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
>>> +/* driver uses own methods to manage IO address space */
>>> +#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 << 1)
>>>
>>> extern int __must_check driver_register(struct device_driver *drv);
>>> extern void driver_unregister(struct device_driver *drv);
>> Could you comment if the approach of using flags in the struct driver
>> could be accepted? I've converted suppress_bind_attrs entry to flags to
>> avoid extending the structure, please see patch "[PATCH 05/29] drivers:
>> convert suppress_bind_attrs parameter into flags".
> Is this really necessary? What I did as part of an RFC series for Tegra
> IOMMU support is keep this knowledge within the IOMMU driver rather than
> export it to the driver core.i
The problem with embedding the list of drivers that you would need to update
it everytime when you modify or extend iommu support in the other drivers.
I've tried also other approach, like adding respective notifiers to
individual
drivers to initialize custom iommu support (or disable default iommu
mapping)
before iommu driver gets initialized, but such solution is in my opinion too
complex and hard to understand if one is not familiar will all this stuff.
All in all it turned out that the simplest and most generic way is to simply
add the flag to the driver core. Flags might be also used in the future
to model other kinds of dependencies between device drivers and/or driver
core.
> The idea being that the IOMMU driver wouldn't create an ARM DMA/IOMMU
> mapping by default but rather allow individual drivers to be marked as
> "kernel-internal" and use the DMA/IOMMU glue in that case. Drivers such
> as DRM would use the IOMMU API directly.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 7:53 ` Marek Szyprowski
@ 2014-09-01 9:38 ` Arnd Bergmann
2014-09-01 10:47 ` Marek Szyprowski
0 siblings, 1 reply; 50+ messages in thread
From: Arnd Bergmann @ 2014-09-01 9:38 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Marek Szyprowski, Thierry Reding, Rob Herring, linux-samsung-soc,
Shaik Ameer Basha, Inki Dae, Greg Kroah-Hartman, Joerg Roedel,
Rafael J. Wysocki, linux-kernel, Tomasz Figa, linaro-mm-sig,
iommu, Kukjin Kim, Laurent Pinchart, Sylwester Nawrocki,
Olof Johansson, Kyungmin Park, Cho KyongHo
On Monday 01 September 2014 09:53:29 Marek Szyprowski wrote:
> On 2014-09-01 09:07, Thierry Reding wrote:
> > On Mon, Sep 01, 2014 at 07:22:32AM +0200, Marek Szyprowski wrote:
> >> Hi Greg,
> >>
> >> On 2014-08-05 12:47, Marek Szyprowski wrote:
> >>> This patch adds a new flags for device drivers. This flag instructs
> >>> kernel that the device driver does it own management of IOMMU assisted
> >>> IO address space translations, so no default dma-mapping structures
> >>> should be initialized.
> >>>
> >>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> >>> ---
> >>> include/linux/device.h | 2 ++
> >>> 1 file changed, 2 insertions(+)
> >>>
> >>> diff --git a/include/linux/device.h b/include/linux/device.h
> >>> index 5f4ff02..2e62371 100644
> >>> --- a/include/linux/device.h
> >>> +++ b/include/linux/device.h
> >>> @@ -253,6 +253,8 @@ struct device_driver {
> >>>
> >>> /* disables bind/unbind via sysfs */
> >>> #define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
> >>> +/* driver uses own methods to manage IO address space */
> >>> +#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 << 1)
> >>>
> >>> extern int __must_check driver_register(struct device_driver *drv);
> >>> extern void driver_unregister(struct device_driver *drv);
> >> Could you comment if the approach of using flags in the struct driver
> >> could be accepted? I've converted suppress_bind_attrs entry to flags to
> >> avoid extending the structure, please see patch "[PATCH 05/29] drivers:
> >> convert suppress_bind_attrs parameter into flags".
> > Is this really necessary? What I did as part of an RFC series for Tegra
> > IOMMU support is keep this knowledge within the IOMMU driver rather than
> > export it to the driver core.i
>
> The problem with embedding the list of drivers that you would need to update
> it everytime when you modify or extend iommu support in the other drivers.
> I've tried also other approach, like adding respective notifiers to
> individual
> drivers to initialize custom iommu support (or disable default iommu
> mapping)
> before iommu driver gets initialized, but such solution is in my opinion too
> complex and hard to understand if one is not familiar will all this stuff.
>
> All in all it turned out that the simplest and most generic way is to simply
> add the flag to the driver core. Flags might be also used in the future
> to model other kinds of dependencies between device drivers and/or driver
> core.
I don't get it yet. I would expect that a driver doing its own management
of the iommu gets to use the linux/iommu.h interfaces, while a driver
using the default iommu setup uses linux/dma-mapping.h. Who do you think
needs to set this flag, and who needs to read it?
Arnd
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 9:38 ` Arnd Bergmann
@ 2014-09-01 10:47 ` Marek Szyprowski
2014-09-01 11:56 ` Arnd Bergmann
0 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-09-01 10:47 UTC (permalink / raw)
To: Arnd Bergmann, linux-arm-kernel
Cc: Thierry Reding, Rob Herring, linux-samsung-soc,
Shaik Ameer Basha, Inki Dae, Greg Kroah-Hartman, Joerg Roedel,
Rafael J. Wysocki, linux-kernel, Tomasz Figa, linaro-mm-sig,
iommu, Kukjin Kim, Laurent Pinchart, Sylwester Nawrocki,
Olof Johansson, Kyungmin Park, Cho KyongHo
Hello,
On 2014-09-01 11:38, Arnd Bergmann wrote:
> On Monday 01 September 2014 09:53:29 Marek Szyprowski wrote:
>> On 2014-09-01 09:07, Thierry Reding wrote:
>>> On Mon, Sep 01, 2014 at 07:22:32AM +0200, Marek Szyprowski wrote:
>>>> Hi Greg,
>>>>
>>>> On 2014-08-05 12:47, Marek Szyprowski wrote:
>>>>> This patch adds a new flags for device drivers. This flag instructs
>>>>> kernel that the device driver does it own management of IOMMU assisted
>>>>> IO address space translations, so no default dma-mapping structures
>>>>> should be initialized.
>>>>>
>>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>>> ---
>>>>> include/linux/device.h | 2 ++
>>>>> 1 file changed, 2 insertions(+)
>>>>>
>>>>> diff --git a/include/linux/device.h b/include/linux/device.h
>>>>> index 5f4ff02..2e62371 100644
>>>>> --- a/include/linux/device.h
>>>>> +++ b/include/linux/device.h
>>>>> @@ -253,6 +253,8 @@ struct device_driver {
>>>>>
>>>>> /* disables bind/unbind via sysfs */
>>>>> #define DRIVER_SUPPRESS_BIND_ATTRS (1 << 0)
>>>>> +/* driver uses own methods to manage IO address space */
>>>>> +#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 << 1)
>>>>>
>>>>> extern int __must_check driver_register(struct device_driver *drv);
>>>>> extern void driver_unregister(struct device_driver *drv);
>>>> Could you comment if the approach of using flags in the struct driver
>>>> could be accepted? I've converted suppress_bind_attrs entry to flags to
>>>> avoid extending the structure, please see patch "[PATCH 05/29] drivers:
>>>> convert suppress_bind_attrs parameter into flags".
>>> Is this really necessary? What I did as part of an RFC series for Tegra
>>> IOMMU support is keep this knowledge within the IOMMU driver rather than
>>> export it to the driver core.i
>> The problem with embedding the list of drivers that you would need to update
>> it everytime when you modify or extend iommu support in the other drivers.
>> I've tried also other approach, like adding respective notifiers to
>> individual
>> drivers to initialize custom iommu support (or disable default iommu
>> mapping)
>> before iommu driver gets initialized, but such solution is in my opinion too
>> complex and hard to understand if one is not familiar will all this stuff.
>>
>> All in all it turned out that the simplest and most generic way is to simply
>> add the flag to the driver core. Flags might be also used in the future
>> to model other kinds of dependencies between device drivers and/or driver
>> core.
> I don't get it yet. I would expect that a driver doing its own management
> of the iommu gets to use the linux/iommu.h interfaces, while a driver
> using the default iommu setup uses linux/dma-mapping.h.
You are right.
> Who do you think needs to set this flag, and who needs to read it?
In the proposed solution Exynos IOMMU driver creates a separate IO
address space
for every client device in a system and binds it to the default
dma-mapping space
for the given device. When drivers are doing its own management of IO
address
space, instead of relying on what is available by default with dma-mapping
interface, this will require releasing of the previously created default
structures and resources. So this flag is set by the driver doing its own
management of io address space. The flags is then checked by Exynos
IOMMU driver
to avoid creating the default dma-mapping address space for devices
which driver
does its own management.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 10:47 ` Marek Szyprowski
@ 2014-09-01 11:56 ` Arnd Bergmann
2014-09-01 12:07 ` Marek Szyprowski
0 siblings, 1 reply; 50+ messages in thread
From: Arnd Bergmann @ 2014-09-01 11:56 UTC (permalink / raw)
To: Marek Szyprowski
Cc: linux-arm-kernel, Thierry Reding, Rob Herring, linux-samsung-soc,
Shaik Ameer Basha, Inki Dae, Greg Kroah-Hartman, Joerg Roedel,
Rafael J. Wysocki, linux-kernel, Tomasz Figa, linaro-mm-sig,
iommu, Kukjin Kim, Laurent Pinchart, Sylwester Nawrocki,
Olof Johansson, Kyungmin Park, Cho KyongHo
On Monday 01 September 2014 12:47:08 Marek Szyprowski wrote:
> > Who do you think needs to set this flag, and who needs to read it?
>
> In the proposed solution Exynos IOMMU driver creates a separate IO
> address space
> for every client device in a system and binds it to the default
> dma-mapping space
> for the given device. When drivers are doing its own management of IO
> address
> space, instead of relying on what is available by default with dma-mapping
> interface, this will require releasing of the previously created default
> structures and resources. So this flag is set by the driver doing its own
> management of io address space. The flags is then checked by Exynos
> IOMMU driver
> to avoid creating the default dma-mapping address space for devices
> which driver
> does its own management.
I don't completely understand it yet. I would assume the device
to be added to the default domain at device creation time
(of_platform_populate), way before we know which device driver
is going to be used. How can this prevent the iommu driver
from doing the association with the domain?
Arnd
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 11:56 ` Arnd Bergmann
@ 2014-09-01 12:07 ` Marek Szyprowski
2014-09-01 13:14 ` [Linaro-mm-sig] " Arnd Bergmann
0 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-09-01 12:07 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arm-kernel, Thierry Reding, Rob Herring, linux-samsung-soc,
Shaik Ameer Basha, Inki Dae, Greg Kroah-Hartman, Joerg Roedel,
Rafael J. Wysocki, linux-kernel, Tomasz Figa, linaro-mm-sig,
iommu, Kukjin Kim, Laurent Pinchart, Sylwester Nawrocki,
Olof Johansson, Kyungmin Park, Cho KyongHo
Hello,
On 2014-09-01 13:56, Arnd Bergmann wrote:
> On Monday 01 September 2014 12:47:08 Marek Szyprowski wrote:
>>> Who do you think needs to set this flag, and who needs to read it?
>> In the proposed solution Exynos IOMMU driver creates a separate IO
>> address space
>> for every client device in a system and binds it to the default
>> dma-mapping space
>> for the given device. When drivers are doing its own management of IO
>> address
>> space, instead of relying on what is available by default with dma-mapping
>> interface, this will require releasing of the previously created default
>> structures and resources. So this flag is set by the driver doing its own
>> management of io address space. The flags is then checked by Exynos
>> IOMMU driver
>> to avoid creating the default dma-mapping address space for devices
>> which driver
>> does its own management.
> I don't completely understand it yet. I would assume the device
> to be added to the default domain at device creation time
> (of_platform_populate), way before we know which device driver
> is going to be used. How can this prevent the iommu driver
> from doing the association with the domain?
of_platform_populate() is too early to do the association, because that
time the
exynos iommu driver is even not yet probed.
The association with default dma-mapping domain is done in
IOMMU_GROUP_NOTIFY_BIND_DRIVER notifier, just before binding the driver
to the
given device. This way iommu driver can check dev->driver->flags and
skip creating
default dma-mapping domain if driver announces that it wants to handle it by
itself.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [Linaro-mm-sig] [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
2014-09-01 12:07 ` Marek Szyprowski
@ 2014-09-01 13:14 ` Arnd Bergmann
0 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-09-01 13:14 UTC (permalink / raw)
To: linaro-mm-sig
Cc: Marek Szyprowski, Rob Herring, linux-samsung-soc,
Shaik Ameer Basha, Greg Kroah-Hartman, Joerg Roedel,
Rafael J. Wysocki, linux-kernel, Cho KyongHo, Tomasz Figa,
Inki Dae, iommu, Kukjin Kim, Laurent Pinchart,
Sylwester Nawrocki, Olof Johansson, Kyungmin Park,
Thierry Reding, linux-arm-kernel, will.deacon
On Monday 01 September 2014 14:07:34 Marek Szyprowski wrote:
> On 2014-09-01 13:56, Arnd Bergmann wrote:
> > On Monday 01 September 2014 12:47:08 Marek Szyprowski wrote:
> >>> Who do you think needs to set this flag, and who needs to read it?
> >> In the proposed solution Exynos IOMMU driver creates a separate IO
> >> address space
> >> for every client device in a system and binds it to the default
> >> dma-mapping space
> >> for the given device. When drivers are doing its own management of IO
> >> address
> >> space, instead of relying on what is available by default with dma-mapping
> >> interface, this will require releasing of the previously created default
> >> structures and resources. So this flag is set by the driver doing its own
> >> management of io address space. The flags is then checked by Exynos
> >> IOMMU driver
> >> to avoid creating the default dma-mapping address space for devices
> >> which driver
> >> does its own management.
> > I don't completely understand it yet. I would assume the device
> > to be added to the default domain at device creation time
> > (of_platform_populate), way before we know which device driver
> > is going to be used. How can this prevent the iommu driver
> > from doing the association with the domain?
>
> of_platform_populate() is too early to do the association, because that
> time the
> exynos iommu driver is even not yet probed.
Please have a look at the "Introduce automatic DMA configuration for IOMMU
masters" series that Will Deacon sent out the other day. The idea is that
we are changing the probe order so that the iommu gets initialized early
enough for all IOMMU association to be done there.
> The association with default dma-mapping domain is done in
> IOMMU_GROUP_NOTIFY_BIND_DRIVER notifier, just before binding the driver
> to the
> given device. This way iommu driver can check dev->driver->flags and
> skip creating
> default dma-mapping domain if driver announces that it wants to handle it by
> itself.
I really want to kill off those notifiers.
Arnd
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH 11/29] DRM: exynos: add DRIVER_HAS_OWN_IOMMU_MANAGER flag to all sub-drivers
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (9 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 12/29] DRM: Exynos: fix window clear code Marek Szyprowski
` (18 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Exynos DRM drivers do their own management of IO address space of all
controlled devices, so set DRIVER_HAS_OWN_IOMMU_MANAGER flag to instruct
IOMMU subsystem not to create any defaults for them.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/gpu/drm/exynos/exynos_drm_fimc.c | 1 +
drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 +
drivers/gpu/drm/exynos/exynos_drm_g2d.c | 1 +
drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 +
drivers/gpu/drm/exynos/exynos_drm_rotator.c | 1 +
drivers/gpu/drm/exynos/exynos_mixer.c | 1 +
6 files changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 831dde9..fe84215 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -1896,6 +1896,7 @@ struct platform_driver fimc_driver = {
.name = "exynos-drm-fimc",
.owner = THIS_MODULE,
.pm = &fimc_pm_ops,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 33161ad..41904df 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1031,5 +1031,6 @@ struct platform_driver fimd_driver = {
.name = "exynos4-fb",
.owner = THIS_MODULE,
.of_match_table = fimd_driver_dt_match,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 8001587..dddeae3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1555,5 +1555,6 @@ struct platform_driver g2d_driver = {
.owner = THIS_MODULE,
.pm = &g2d_pm_ops,
.of_match_table = exynos_g2d_match,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 9e3ff16..76e8b1e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1797,6 +1797,7 @@ struct platform_driver gsc_driver = {
.name = "exynos-drm-gsc",
.owner = THIS_MODULE,
.pm = &gsc_pm_ops,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index f01fbb6..2da91c4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -852,5 +852,6 @@ struct platform_driver rotator_driver = {
.owner = THIS_MODULE,
.pm = &rotator_pm_ops,
.of_match_table = exynos_rotator_match,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
};
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 7529946..79b1309a 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1320,6 +1320,7 @@ struct platform_driver mixer_driver = {
.name = "exynos-mixer",
.owner = THIS_MODULE,
.of_match_table = mixer_match_types,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
.probe = mixer_probe,
.remove = mixer_remove,
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 12/29] DRM: Exynos: fix window clear code
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (10 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 11/29] DRM: exynos: add DRIVER_HAS_OWN_IOMMU_MANAGER flag to all sub-drivers Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-09-01 13:37 ` Inki Dae
2014-08-05 10:47 ` [PATCH 13/29] temporary: media: s5p-mfc: remove DT hacks & initialization custom memory init code Marek Szyprowski
` (17 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
To correctly disable hardware window during driver init, both enable bits
(WINCONx_ENWIN in WINCON and SHADOWCON_CHx_ENABLE in SHADOWCON) must be
cleared, otherwise hardware fails to re-enable such window later.
While touching this function, also temporarily disable ctx->suspended flag
to let fimd_wait_for_vblank function really to do its job.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/gpu/drm/exynos/exynos_drm_fimd.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 41904df..7a363d2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -165,27 +165,38 @@ static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
DRM_DEBUG_KMS("vblank wait timed out.\n");
}
-
static void fimd_clear_channel(struct exynos_drm_manager *mgr)
{
struct fimd_context *ctx = mgr->ctx;
- int win, ch_enabled = 0;
+ int state, win, ch_enabled = 0;
DRM_DEBUG_KMS("%s\n", __FILE__);
/* Check if any channel is enabled. */
for (win = 0; win < WINDOWS_NR; win++) {
- u32 val = readl(ctx->regs + SHADOWCON);
- if (val & SHADOWCON_CHx_ENABLE(win)) {
- val &= ~SHADOWCON_CHx_ENABLE(win);
- writel(val, ctx->regs + SHADOWCON);
+ u32 val = readl(ctx->regs + WINCON(win));
+ if (val & WINCONx_ENWIN) {
+ /* wincon */
+ val &= ~WINCONx_ENWIN;
+ writel(val, ctx->regs + WINCON(win));
+
+ /* unprotect windows */
+ if (ctx->driver_data->has_shadowcon) {
+ val = readl(ctx->regs + SHADOWCON);
+ val &= ~SHADOWCON_CHx_ENABLE(win);
+ writel(val, ctx->regs + SHADOWCON);
+ }
ch_enabled = 1;
}
}
/* Wait for vsync, as disable channel takes effect at next vsync */
- if (ch_enabled)
+ if (ch_enabled) {
+ state = ctx->suspended;
+ ctx->suspended = 0;
fimd_wait_for_vblank(mgr);
+ ctx->suspended = state;
+ }
}
static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH 12/29] DRM: Exynos: fix window clear code
2014-08-05 10:47 ` [PATCH 12/29] DRM: Exynos: fix window clear code Marek Szyprowski
@ 2014-09-01 13:37 ` Inki Dae
0 siblings, 0 replies; 50+ messages in thread
From: Inki Dae @ 2014-09-01 13:37 UTC (permalink / raw)
To: Marek Szyprowski
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Joerg Roedel, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hi Marek,
On 2014년 08월 05일 19:47, Marek Szyprowski wrote:
> To correctly disable hardware window during driver init, both enable bits
> (WINCONx_ENWIN in WINCON and SHADOWCON_CHx_ENABLE in SHADOWCON) must be
> cleared, otherwise hardware fails to re-enable such window later.
>
> While touching this function, also temporarily disable ctx->suspended flag
> to let fimd_wait_for_vblank function really to do its job.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/gpu/drm/exynos/exynos_drm_fimd.c | 25 ++++++++++++++++++-------
> 1 file changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 41904df..7a363d2 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -165,27 +165,38 @@ static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
> DRM_DEBUG_KMS("vblank wait timed out.\n");
> }
>
> -
> static void fimd_clear_channel(struct exynos_drm_manager *mgr)
> {
> struct fimd_context *ctx = mgr->ctx;
> - int win, ch_enabled = 0;
> + int state, win, ch_enabled = 0;
It doesn't need to declare state variable here because this variable is
used only when ch_enabled is 1.
>
> DRM_DEBUG_KMS("%s\n", __FILE__);
>
> /* Check if any channel is enabled. */
> for (win = 0; win < WINDOWS_NR; win++) {
> - u32 val = readl(ctx->regs + SHADOWCON);
> - if (val & SHADOWCON_CHx_ENABLE(win)) {
> - val &= ~SHADOWCON_CHx_ENABLE(win);
> - writel(val, ctx->regs + SHADOWCON);
> + u32 val = readl(ctx->regs + WINCON(win));
WARNING: Missing a blank line after declarations
> + if (val & WINCONx_ENWIN) {
> + /* wincon */
> + val &= ~WINCONx_ENWIN;
> + writel(val, ctx->regs + WINCON(win));
> +
> + /* unprotect windows */
> + if (ctx->driver_data->has_shadowcon) {
> + val = readl(ctx->regs + SHADOWCON);
> + val &= ~SHADOWCON_CHx_ENABLE(win);
> + writel(val, ctx->regs + SHADOWCON);
> + }
> ch_enabled = 1;
> }
> }
>
> /* Wait for vsync, as disable channel takes effect at next vsync */
> - if (ch_enabled)
> + if (ch_enabled) {
> + state = ctx->suspended;
int state = ctx->suspended;
> + ctx->suspended = 0;
> fimd_wait_for_vblank(mgr);
> + ctx->suspended = state;
> + }
> }
>
> static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
>
Above is trivial so I fixed them. Picked it up.
Thanks,
Inki Dae
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH 13/29] temporary: media: s5p-mfc: remove DT hacks & initialization custom memory init code
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (11 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 12/29] DRM: Exynos: fix window clear code Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 14/29] devicetree: Update Exynos SYSMMU device tree bindings Marek Szyprowski
` (16 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch removes custom initialization of reserved memory regions from
s5p-mfc driver. Driver will use main device pointer for all memory allocations.
This patch is temporary, do not merge it yet.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/media/platform/s5p-mfc/s5p_mfc.c | 73 +-------------------------------
1 file changed, 2 insertions(+), 71 deletions(-)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index d35b041..77b99ae 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -996,55 +996,8 @@ static const struct v4l2_file_operations s5p_mfc_fops = {
.mmap = s5p_mfc_mmap,
};
-static int match_child(struct device *dev, void *data)
-{
- if (!dev_name(dev))
- return 0;
- return !strcmp(dev_name(dev), (char *)data);
-}
-
static void *mfc_get_drv_data(struct platform_device *pdev);
-static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
-{
- unsigned int mem_info[2] = { };
-
- dev->mem_dev_l = devm_kzalloc(&dev->plat_dev->dev,
- sizeof(struct device), GFP_KERNEL);
- if (!dev->mem_dev_l) {
- mfc_err("Not enough memory\n");
- return -ENOMEM;
- }
- device_initialize(dev->mem_dev_l);
- of_property_read_u32_array(dev->plat_dev->dev.of_node,
- "samsung,mfc-l", mem_info, 2);
- if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0],
- mem_info[0], mem_info[1],
- DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
- mfc_err("Failed to declare coherent memory for\n"
- "MFC device\n");
- return -ENOMEM;
- }
-
- dev->mem_dev_r = devm_kzalloc(&dev->plat_dev->dev,
- sizeof(struct device), GFP_KERNEL);
- if (!dev->mem_dev_r) {
- mfc_err("Not enough memory\n");
- return -ENOMEM;
- }
- device_initialize(dev->mem_dev_r);
- of_property_read_u32_array(dev->plat_dev->dev.of_node,
- "samsung,mfc-r", mem_info, 2);
- if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0],
- mem_info[0], mem_info[1],
- DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
- pr_err("Failed to declare coherent memory for\n"
- "MFC device\n");
- return -ENOMEM;
- }
- return 0;
-}
-
/* MFC probe function */
static int s5p_mfc_probe(struct platform_device *pdev)
{
@@ -1096,26 +1049,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
goto err_res;
}
- if (pdev->dev.of_node) {
- ret = s5p_mfc_alloc_memdevs(dev);
- if (ret < 0)
- goto err_res;
- } else {
- dev->mem_dev_l = device_find_child(&dev->plat_dev->dev,
- "s5p-mfc-l", match_child);
- if (!dev->mem_dev_l) {
- mfc_err("Mem child (L) device get failed\n");
- ret = -ENODEV;
- goto err_res;
- }
- dev->mem_dev_r = device_find_child(&dev->plat_dev->dev,
- "s5p-mfc-r", match_child);
- if (!dev->mem_dev_r) {
- mfc_err("Mem child (R) device get failed\n");
- ret = -ENODEV;
- goto err_res;
- }
- }
+ dev->mem_dev_l = &dev->plat_dev->dev;
+ dev->mem_dev_r = &dev->plat_dev->dev;
dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
if (IS_ERR(dev->alloc_ctx[0])) {
@@ -1246,10 +1181,6 @@ static int s5p_mfc_remove(struct platform_device *pdev)
s5p_mfc_release_firmware(dev);
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
- if (pdev->dev.of_node) {
- put_device(dev->mem_dev_l);
- put_device(dev->mem_dev_r);
- }
s5p_mfc_final_pm(dev);
return 0;
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 14/29] devicetree: Update Exynos SYSMMU device tree bindings
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (12 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 13/29] temporary: media: s5p-mfc: remove DT hacks & initialization custom memory init code Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 15/29] ARM: DTS: Exynos4: add System MMU nodes Marek Szyprowski
` (15 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch describes how generic iommu bindings are implemented by
Exynos SYSMMU driver.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
.../devicetree/bindings/iommu/samsung,sysmmu.txt | 93 +++++++++++++++++++---
1 file changed, 84 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
index 6fa4c73..999ba6d 100644
--- a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
+++ b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
@@ -23,16 +23,33 @@ MMUs.
for window 1, 2 and 3.
* M2M Scalers and G2D in Exynos5420 has one System MMU on the read channel and
the other System MMU on the write channel.
-The drivers must consider how to handle those System MMUs. One of the idea is
-to implement child devices or sub-devices which are the client devices of the
-System MMU.
-Note:
-The current DT binding for the Exynos System MMU is incomplete.
-The following properties can be removed or changed, if found incompatible with
-the "Generic IOMMU Binding" support for attaching devices to the IOMMU.
+The drivers must consider how to handle those System MMUs. When device
+have more than one SYSMMU controller it is neccessary to add
+"iommu-names" property, which specifies which SYSMMU controller operates
+on which bus or memory channel.
-Required properties:
+It is up to the master device driver to decide how such case will be
+handled. It is possible to create separate IO address spaces for each
+SYSMMU or to bind them together to one common IO address space. It is
+also possible to bind more than one device to one IO address space. All
+this has to be handled by master device driver in its initialization
+procedure or flags and no changes to device tree nodes are needed.
+
+In Linux kernel, the general idea is that presence of the SYSMMU
+controllers is transparent to master drivers if they use standard DMA
+API. When driver wants to use IO separate address spaces for each bus or
+memory channel (each SYSMMU) or to bind more than one device to one IO
+address space, it has to specify this to SYSMMU driver by
+DRIVER_HAS_OWN_IOMMU_MANAGER flag. To get access to each SYSMMU bound to
+the given device, additional child devices with special names (matching
+"parent:bus" scheme) have to be registered. Once then, all standard
+IOMMU operations can be performed on such child devices, what will
+result in respective operations done on IO address space managed by
+SYSMMU of the given name. Other operating systems might implement those
+features differently.
+
+Required properties for SYSMMU controller node:
- compatible: Should be "samsung,exynos-sysmmu"
- reg: A tuple of base address and size of System MMU registers.
- interrupt-parent: The phandle of the interrupt controller of System MMU
@@ -45,11 +62,27 @@ Required properties:
Exynos4 SoCs, there needs no "master" clock.
Exynos5 SoCs, some System MMUs must have "master" clocks.
- clocks: Required if the System MMU is needed to gate its clock.
+- #iommu-cells: Specify number of cells describing IO address space parameters,
+ can be: 0 (zero), meaning all 32bit address space is available,
+ or 2, if address space is limited, first cell then stores
+ base IO address, second cell contains IO window size in bytes.
- samsung,power-domain: Required if the System MMU is needed to gate its power.
Please refer to the following document:
Documentation/devicetree/bindings/arm/exynos/power_domain.txt
-Examples:
+Required properties for master device:
+- iommus: one or more phandles to the SYSMMU controller node, with optionally
+ specified IO address space (see #iommu-cells property above)
+- iommu-names: if more than one SYSMMU controller is specified, this property
+ must contain names for each of them. Those names are defined by
+ the bindings for a particular master device.
+
+For more information, please refer to generic iommu bindings defined in
+iommu.txt file.
+
+Example 1:
+GScaller device with one SYSMMU controller
+
gsc_0: gsc@13e00000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
@@ -57,6 +90,7 @@ Examples:
samsung,power-domain = <&pd_gsc>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
+ iommus = <&sysmmu_gsc0>;
};
sysmmu_gsc0: sysmmu@13E80000 {
@@ -67,4 +101,45 @@ Examples:
clock-names = "sysmmu", "master";
clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>;
samsung,power-domain = <&pd_gsc>;
+ #iommu-cells = <0>;
+ };
+
+Example 2:
+MFC Codec with two SYSMMU controllers (on "left" and "right" bus), with address
+space limited to 256MiB each, left bus starts IO address space at 0x20000000,
+while right bus at 0x30000000
+
+ mfc: codec@13400000 {
+ compatible = "samsung,mfc-v5";
+ reg = <0x13400000 0x10000>;
+ interrupts = <0 94 0>;
+ samsung,power-domain = <&pd_mfc>;
+ clocks = <&clock CLK_MFC>;
+ clock-names = "mfc";
+ status = "disabled";
+ iommus = <&sysmmu_mfc_l 0x20000000 0x10000000>,
+ <&sysmmu_mfc_r 0x30000000 0x10000000>;
+ iommu-names = "left", "right";
+ };
+
+ sysmmu_mfc_l: sysmmu@13620000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13620000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 5>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+ samsung,power-domain = <&pd_mfc>;
+ #iommu-cells = <2>;
+ };
+
+ sysmmu_mfc_r: sysmmu@13630000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13630000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 6>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+ samsung,power-domain = <&pd_mfc>;
+ #iommu-cells = <2>;
};
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 15/29] ARM: DTS: Exynos4: add System MMU nodes
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (13 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 14/29] devicetree: Update Exynos SYSMMU device tree bindings Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 16/29] iommu: exynos: make driver multiarch friendly Marek Szyprowski
` (14 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds System MMU nodes that are specific to Exynos4210/4x12 series.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/boot/dts/exynos4.dtsi | 118 ++++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/exynos4210.dtsi | 23 ++++++++
arch/arm/boot/dts/exynos4x12.dtsi | 82 ++++++++++++++++++++++++++
3 files changed, 223 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 3385b17..a76b4e5 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -174,6 +174,7 @@
clock-names = "fimc", "sclk_fimc";
samsung,power-domain = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
+ iommus = <&sysmmu_fimc0>;
status = "disabled";
};
@@ -185,6 +186,7 @@
clock-names = "fimc", "sclk_fimc";
samsung,power-domain = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
+ iommus = <&sysmmu_fimc1>;
status = "disabled";
};
@@ -196,6 +198,7 @@
clock-names = "fimc", "sclk_fimc";
samsung,power-domain = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
+ iommus = <&sysmmu_fimc2>;
status = "disabled";
};
@@ -207,6 +210,7 @@
clock-names = "fimc", "sclk_fimc";
samsung,power-domain = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
+ iommus = <&sysmmu_fimc3>;
status = "disabled";
};
@@ -395,6 +399,9 @@
clocks = <&clock CLK_MFC>;
clock-names = "mfc";
status = "disabled";
+ iommus = <&sysmmu_mfc_l 0x20000000 0x10000000>,
+ <&sysmmu_mfc_r 0x30000000 0x10000000>;
+ iommu-names = "left", "right";
};
serial_0: serial@13800000 {
@@ -642,6 +649,117 @@
clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
clock-names = "sclk_fimd", "fimd";
samsung,power-domain = <&pd_lcd0>;
+ iommus = <&sysmmu_fimd0>;
status = "disabled";
};
+
+ sysmmu_mfc_l: sysmmu@13620000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13620000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 5>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+ samsung,power-domain = <&pd_mfc>;
+ #iommu-cells = <2>;
+ };
+
+ sysmmu_mfc_r: sysmmu@13630000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13630000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 6>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+ samsung,power-domain = <&pd_mfc>;
+ #iommu-cells = <2>;
+ };
+
+ sysmmu_tv: sysmmu@12E20000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x12E20000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 4>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
+ samsung,power-domain = <&pd_tv>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc0: sysmmu@11A20000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11A20000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 2>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_FIMC0>, <&clock CLK_FIMC0>;
+ samsung,power-domain = <&pd_cam>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc1: sysmmu@11A30000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11A30000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 3>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_FIMC1>, <&clock CLK_FIMC1>;
+ samsung,power-domain = <&pd_cam>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc2: sysmmu@11A40000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11A40000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 4>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_FIMC2>, <&clock CLK_FIMC2>;
+ samsung,power-domain = <&pd_cam>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc3: sysmmu@11A50000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11A50000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 5>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_FIMC3>, <&clock CLK_FIMC3>;
+ samsung,power-domain = <&pd_cam>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_jpeg: sysmmu@11A60000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11A60000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 6>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+ samsung,power-domain = <&pd_cam>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_rotator: sysmmu@12A30000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x12A30000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 0>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+ samsung,power-domain = <&pd_lcd0>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimd0: sysmmu@11E20000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11E20000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <5 2>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_FIMD0>, <&clock CLK_FIMD0>;
+ samsung,power-domain = <&pd_lcd0>;
+ #iommu-cells = <0>;
+ };
};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 807bb5b..9ae48c2 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -142,6 +142,7 @@
interrupts = <0 89 0>;
clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
clock-names = "sclk_fimg2d", "fimg2d";
+ iommus = <&sysmmu_g2d>;
status = "disabled";
};
@@ -175,4 +176,26 @@
samsung,lcd-wb;
};
};
+
+ sysmmu_g2d: sysmmu@12A20000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x12A20000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 7>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+ samsung,power-domain = <&pd_lcd0>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimd1: sysmmu@12220000 {
+ compatible = "samsung,exynos-sysmmu";
+ interrupt-parent = <&combiner>;
+ reg = <0x12220000 0x1000>;
+ interrupts = <5 3>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
+ samsung,power-domain = <&pd_lcd1>;
+ #iommu-cells = <0>;
+ };
};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 861bb91..cc97e18 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -148,6 +148,7 @@
interrupts = <0 89 0>;
clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
clock-names = "sclk_fimg2d", "fimg2d";
+ iommus = <&sysmmu_g2d>;
status = "disabled";
};
@@ -197,6 +198,7 @@
samsung,power-domain = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE0>;
clock-names = "flite";
+ iommus = <&sysmmu_fimc_lite0>;
status = "disabled";
};
@@ -207,6 +209,7 @@
samsung,power-domain = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE1>;
clock-names = "flite";
+ iommus = <&sysmmu_fimc_lite1>;
status = "disabled";
};
@@ -235,6 +238,9 @@
"mcuispdiv1", "uart", "aclk200",
"div_aclk200", "aclk400mcuisp",
"div_aclk400mcuisp";
+ iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
+ <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
+ iommu-names = "isp", "drc", "fd", "mcuctl";
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -271,4 +277,80 @@
compatible = "samsung,exynos4x12-usb2-phy";
samsung,sysreg-phandle = <&sys_reg>;
};
+
+ sysmmu_g2d: sysmmu@10A40000{
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x10A40000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 7>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc_isp: sysmmu@12260000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x12260000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <16 2>;
+ samsung,power-domain = <&pd_isp>;
+ clock-names = "sysmmu";
+ clocks = <&clock CLK_SMMU_ISP>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc_drc: sysmmu@12270000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x12270000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <16 3>;
+ samsung,power-domain = <&pd_isp>;
+ clock-names = "sysmmu";
+ clocks = <&clock CLK_SMMU_DRC>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc_fd: sysmmu@122A0000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x122A0000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <16 4>;
+ samsung,power-domain = <&pd_isp>;
+ clock-names = "sysmmu";
+ clocks = <&clock CLK_SMMU_FD>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc_mcuctl: sysmmu@122B0000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x122B0000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <16 5>;
+ samsung,power-domain = <&pd_isp>;
+ clock-names = "sysmmu";
+ clocks = <&clock CLK_SMMU_ISPCX>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc_lite0: sysmmu@123B0000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x123B0000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <16 0>;
+ samsung,power-domain = <&pd_isp>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_LITE0>, <&clock CLK_FIMC_LITE0>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_fimc_lite1: sysmmu@123C0000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x123C0000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <16 1>;
+ samsung,power-domain = <&pd_isp>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_LITE1>, <&clock CLK_FIMC_LITE1>;
+ #iommu-cells = <0>;
+ };
};
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 16/29] iommu: exynos: make driver multiarch friendly
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (14 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 15/29] ARM: DTS: Exynos4: add System MMU nodes Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 17/29] iommu: exynos: don't read version register on every tlb operation Marek Szyprowski
` (13 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Initialize all structures and register to iommu subsystem only on Exynos
compatible platforms.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index d037e87..64b3bc8 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -20,6 +20,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/mm.h>
+#include <linux/of.h>
#include <linux/iommu.h>
#include <linux/errno.h>
#include <linux/list.h>
@@ -1187,6 +1188,11 @@ static int __init exynos_iommu_init(void)
{
int ret;
+ if (!of_machine_is_compatible("samsung,exynos3") &&
+ !of_machine_is_compatible("samsung,exynos4") &&
+ !of_machine_is_compatible("samsung,exynos5"))
+ return -ENODEV;
+
lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
if (!lv2table_kmem_cache) {
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 17/29] iommu: exynos: don't read version register on every tlb operation
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (15 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 16/29] iommu: exynos: make driver multiarch friendly Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 18/29] iommu: exynos: remove unused functions Marek Szyprowski
` (12 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch removes reading of REG_MMU_VERSION register on every tlb
operation and caches SYSMMU version in driver's internal data.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 64b3bc8..8927923 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -213,6 +213,7 @@ struct sysmmu_drvdata {
spinlock_t lock;
struct iommu_domain *domain;
phys_addr_t pgtable;
+ int version;
};
static bool set_sysmmu_active(struct sysmmu_drvdata *data)
@@ -239,11 +240,6 @@ static void sysmmu_unblock(void __iomem *sfrbase)
__raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
}
-static unsigned int __raw_sysmmu_version(struct sysmmu_drvdata *data)
-{
- return MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
-}
-
static bool sysmmu_block(void __iomem *sfrbase)
{
int i = 120;
@@ -403,7 +399,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
unsigned int cfg = CFG_LRU | CFG_QOS(15);
unsigned int ver;
- ver = __raw_sysmmu_version(data);
+ ver = MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
if (MMU_MAJ_VER(ver) == 3) {
if (MMU_MIN_VER(ver) >= 2) {
cfg |= CFG_FLPDCACHE;
@@ -417,6 +413,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
}
__raw_writel(cfg, data->sfrbase + REG_MMU_CFG);
+ data->version = ver;
}
static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
@@ -526,7 +523,7 @@ static bool exynos_sysmmu_disable(struct device *dev)
static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
sysmmu_iova_t iova)
{
- if (__raw_sysmmu_version(data) == MAKE_MMU_VER(3, 3))
+ if (data->version == MAKE_MMU_VER(3, 3))
__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
}
@@ -575,7 +572,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
* 1MB page can be cached in one of all sets.
* 64KB page can be one of 16 consecutive sets.
*/
- if (MMU_MAJ_VER(__raw_sysmmu_version(data)) == 2)
+ if (MMU_MAJ_VER(data->version) == 2)
num_inv = min_t(unsigned int, size / PAGE_SIZE, 64);
if (sysmmu_block(data->sfrbase)) {
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 18/29] iommu: exynos: remove unused functions
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (16 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 17/29] iommu: exynos: don't read version register on every tlb operation Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 19/29] iommu: exynos: remove useless spinlock Marek Szyprowski
` (11 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch removes two unneeded functions, which are not a part of
generic IOMMU API and were never used by any other driver.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 31 -------------------------------
1 file changed, 31 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 8927923..ec3c882 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -491,13 +491,6 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
return ret;
}
-int exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable)
-{
- BUG_ON(!memblock_is_memory(pgtable));
-
- return __exynos_sysmmu_enable(dev, pgtable, NULL);
-}
-
static bool exynos_sysmmu_disable(struct device *dev)
{
unsigned long flags;
@@ -589,30 +582,6 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
spin_unlock_irqrestore(&data->lock, flags);
}
-void exynos_sysmmu_tlb_invalidate(struct device *dev)
-{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
- unsigned long flags;
- struct sysmmu_drvdata *data;
-
- data = dev_get_drvdata(owner->sysmmu);
-
- spin_lock_irqsave(&data->lock, flags);
- if (is_sysmmu_active(data)) {
- if (!IS_ERR(data->clk_master))
- clk_enable(data->clk_master);
- if (sysmmu_block(data->sfrbase)) {
- __sysmmu_tlb_invalidate(data->sfrbase);
- sysmmu_unblock(data->sfrbase);
- }
- if (!IS_ERR(data->clk_master))
- clk_disable(data->clk_master);
- } else {
- dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
- }
- spin_unlock_irqrestore(&data->lock, flags);
-}
-
static int __init exynos_sysmmu_probe(struct platform_device *pdev)
{
int irq, ret;
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 19/29] iommu: exynos: remove useless spinlock
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (17 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 18/29] iommu: exynos: remove unused functions Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 20/29] iommu: exynos: refactor function parameters to simplify code Marek Szyprowski
` (10 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch removes useless spinlocks and other unused members from
struct exynos_iommu_owner. There is no point is protecting this
structure by spinlock because content of this structure doesn't change
and other structures have their own spinlocks.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index ec3c882..ed8c518 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -190,9 +190,6 @@ struct exynos_iommu_owner {
struct list_head client; /* entry of exynos_iommu_domain.clients */
struct device *dev;
struct device *sysmmu;
- struct iommu_domain *domain;
- void *vmm_data; /* IO virtual memory manager's data */
- spinlock_t lock; /* Lock to preserve consistency of System MMU */
};
struct exynos_iommu_domain {
@@ -478,16 +475,12 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
BUG_ON(!has_sysmmu(dev));
- spin_lock_irqsave(&owner->lock, flags);
-
data = dev_get_drvdata(owner->sysmmu);
ret = __sysmmu_enable(data, pgtable, domain);
if (ret >= 0)
data->master = dev;
- spin_unlock_irqrestore(&owner->lock, flags);
-
return ret;
}
@@ -500,16 +493,12 @@ static bool exynos_sysmmu_disable(struct device *dev)
BUG_ON(!has_sysmmu(dev));
- spin_lock_irqsave(&owner->lock, flags);
-
data = dev_get_drvdata(owner->sysmmu);
disabled = __sysmmu_disable(data);
if (disabled)
data->master = NULL;
- spin_unlock_irqrestore(&owner->lock, flags);
-
return disabled;
}
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 20/29] iommu: exynos: refactor function parameters to simplify code
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (18 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 19/29] iommu: exynos: remove useless spinlock Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 21/29] iommu: exynos: remove unused functions, part 2 Marek Szyprowski
` (9 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch simplifies the code by:
- refactoring function parameters from struct device pointer to direct pointer
to struct sysmmu drvdata
- moving list_head enteries from struct exynos_iommu_owner directly to struct
sysmmu_drvdata
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
1 file changed, 46 insertions(+), 47 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index ed8c518..018a615 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -187,8 +187,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
/* attached to dev.archdata.iommu of the master device */
struct exynos_iommu_owner {
- struct list_head client; /* entry of exynos_iommu_domain.clients */
- struct device *dev;
struct device *sysmmu;
};
@@ -209,6 +207,7 @@ struct sysmmu_drvdata {
int activations;
spinlock_t lock;
struct iommu_domain *domain;
+ struct list_head domain_node;
phys_addr_t pgtable;
int version;
};
@@ -509,12 +508,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
}
-static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
+static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
sysmmu_iova_t iova)
{
unsigned long flags;
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
- struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
if (!IS_ERR(data->clk_master))
clk_enable(data->clk_master);
@@ -528,14 +525,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
clk_disable(data->clk_master);
}
-static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
- size_t size)
+static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
+ sysmmu_iova_t iova, size_t size)
{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
unsigned long flags;
- struct sysmmu_drvdata *data;
-
- data = dev_get_drvdata(owner->sysmmu);
spin_lock_irqsave(&data->lock, flags);
if (is_sysmmu_active(data)) {
@@ -565,8 +558,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
if (!IS_ERR(data->clk_master))
clk_disable(data->clk_master);
} else {
- dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
- iova);
+ dev_dbg(data->master,
+ "disabled. Skipping TLB invalidation @ %#x\n", iova);
}
spin_unlock_irqrestore(&data->lock, flags);
}
@@ -705,7 +698,7 @@ err_pgtable:
static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
{
struct exynos_iommu_domain *priv = domain->priv;
- struct exynos_iommu_owner *owner;
+ struct sysmmu_drvdata *data;
unsigned long flags;
int i;
@@ -713,14 +706,12 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
spin_lock_irqsave(&priv->lock, flags);
- list_for_each_entry(owner, &priv->clients, client) {
- while (!exynos_sysmmu_disable(owner->dev))
- ; /* until System MMU is actually disabled */
+ list_for_each_entry(data, &priv->clients, domain_node) {
+ if (__sysmmu_disable(data))
+ data->master = NULL;
+ list_del_init(&data->domain_node);
}
- while (!list_empty(&priv->clients))
- list_del_init(priv->clients.next);
-
spin_unlock_irqrestore(&priv->lock, flags);
for (i = 0; i < NUM_LV1ENTRIES; i++)
@@ -739,20 +730,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
{
struct exynos_iommu_owner *owner = dev->archdata.iommu;
struct exynos_iommu_domain *priv = domain->priv;
+ struct sysmmu_drvdata *data;
phys_addr_t pagetable = virt_to_phys(priv->pgtable);
unsigned long flags;
- int ret;
+ int ret = -ENODEV;
- spin_lock_irqsave(&priv->lock, flags);
+ if (!has_sysmmu(dev))
+ return -ENODEV;
- ret = __exynos_sysmmu_enable(dev, pagetable, domain);
- if (ret == 0) {
- list_add_tail(&owner->client, &priv->clients);
- owner->domain = domain;
+ data = dev_get_drvdata(owner->sysmmu);
+ if (data) {
+ ret = __sysmmu_enable(data, pagetable, domain);
+ if (ret >= 0) {
+ data->master = dev;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ list_add_tail(&data->domain_node, &priv->clients);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
}
- spin_unlock_irqrestore(&priv->lock, flags);
-
if (ret < 0) {
dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
__func__, &pagetable);
@@ -768,26 +765,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
static void exynos_iommu_detach_device(struct iommu_domain *domain,
struct device *dev)
{
- struct exynos_iommu_owner *owner;
struct exynos_iommu_domain *priv = domain->priv;
phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+ struct sysmmu_drvdata *data;
unsigned long flags;
+ int found = 0;
- spin_lock_irqsave(&priv->lock, flags);
+ if (!has_sysmmu(dev))
+ return;
- list_for_each_entry(owner, &priv->clients, client) {
- if (owner == dev->archdata.iommu) {
- if (exynos_sysmmu_disable(dev)) {
- list_del_init(&owner->client);
- owner->domain = NULL;
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry(data, &priv->clients, domain_node) {
+ if (data->master == dev) {
+ if (__sysmmu_disable(data)) {
+ data->master = NULL;
+ list_del_init(&data->domain_node);
}
+ found = true;
break;
}
}
-
spin_unlock_irqrestore(&priv->lock, flags);
- if (owner == dev->archdata.iommu)
+ if (found)
dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
__func__, &pagetable);
else
@@ -834,12 +834,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
* not currently mapped.
*/
if (need_flush_flpd_cache) {
- struct exynos_iommu_owner *owner;
+ struct sysmmu_drvdata *data;
spin_lock(&priv->lock);
- list_for_each_entry(owner, &priv->clients, client)
- sysmmu_tlb_invalidate_flpdcache(
- owner->dev, iova);
+ list_for_each_entry(data, &priv->clients, domain_node)
+ sysmmu_tlb_invalidate_flpdcache(data, iova);
spin_unlock(&priv->lock);
}
}
@@ -874,13 +873,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
spin_lock(&priv->lock);
if (lv1ent_page_zero(sent)) {
- struct exynos_iommu_owner *owner;
+ struct sysmmu_drvdata *data;
/*
* Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
* entry by speculative prefetch of SLPD which has no mapping.
*/
- list_for_each_entry(owner, &priv->clients, client)
- sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
+ list_for_each_entry(data, &priv->clients, domain_node)
+ sysmmu_tlb_invalidate_flpdcache(data, iova);
}
spin_unlock(&priv->lock);
@@ -985,13 +984,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
sysmmu_iova_t iova, size_t size)
{
- struct exynos_iommu_owner *owner;
+ struct sysmmu_drvdata *data;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- list_for_each_entry(owner, &priv->clients, client)
- sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
+ list_for_each_entry(data, &priv->clients, domain_node)
+ sysmmu_tlb_invalidate_entry(data, iova, size);
spin_unlock_irqrestore(&priv->lock, flags);
}
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 21/29] iommu: exynos: remove unused functions, part 2
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (19 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 20/29] iommu: exynos: refactor function parameters to simplify code Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 22/29] iommu: exynos: add support for binding more than one sysmmu to master device Marek Szyprowski
` (8 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
After refactoring functions to use pointer to struct sysmmu_drvdata
directly, some functions became useless and thus never used, so remove
them completely.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 43 -------------------------------------------
1 file changed, 43 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 018a615..674d1fb 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -458,49 +458,6 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
return ret;
}
-/* __exynos_sysmmu_enable: Enables System MMU
- *
- * returns -error if an error occurred and System MMU is not enabled,
- * 0 if the System MMU has been just enabled and 1 if System MMU was already
- * enabled before.
- */
-static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
- struct iommu_domain *domain)
-{
- int ret = 0;
- unsigned long flags;
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
- struct sysmmu_drvdata *data;
-
- BUG_ON(!has_sysmmu(dev));
-
- data = dev_get_drvdata(owner->sysmmu);
-
- ret = __sysmmu_enable(data, pgtable, domain);
- if (ret >= 0)
- data->master = dev;
-
- return ret;
-}
-
-static bool exynos_sysmmu_disable(struct device *dev)
-{
- unsigned long flags;
- bool disabled = true;
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
- struct sysmmu_drvdata *data;
-
- BUG_ON(!has_sysmmu(dev));
-
- data = dev_get_drvdata(owner->sysmmu);
-
- disabled = __sysmmu_disable(data);
- if (disabled)
- data->master = NULL;
-
- return disabled;
-}
-
static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
sysmmu_iova_t iova)
{
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 22/29] iommu: exynos: add support for binding more than one sysmmu to master device
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (20 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 21/29] iommu: exynos: remove unused functions, part 2 Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 23/29] iommu: exynos: init iommu controllers from device tree Marek Szyprowski
` (7 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds support for assigning more than one SYSMMU controller to
the master device. This has been achieved simply by chaning the struct
device pointer in struct exynos_iommu_owner into the list of struct
sysmmu_drvdata of all controllers assigned to the given master device.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 674d1fb..46e0edc 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -187,7 +187,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
/* attached to dev.archdata.iommu of the master device */
struct exynos_iommu_owner {
- struct device *sysmmu;
+ struct list_head clients;
};
struct exynos_iommu_domain {
@@ -208,6 +208,7 @@ struct sysmmu_drvdata {
spinlock_t lock;
struct iommu_domain *domain;
struct list_head domain_node;
+ struct list_head owner_node;
phys_addr_t pgtable;
int version;
};
@@ -695,8 +696,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
if (!has_sysmmu(dev))
return -ENODEV;
- data = dev_get_drvdata(owner->sysmmu);
- if (data) {
+ list_for_each_entry(data, &owner->clients, owner_node) {
ret = __sysmmu_enable(data, pagetable, domain);
if (ret >= 0) {
data->master = dev;
@@ -724,7 +724,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
{
struct exynos_iommu_domain *priv = domain->priv;
phys_addr_t pagetable = virt_to_phys(priv->pgtable);
- struct sysmmu_drvdata *data;
+ struct sysmmu_drvdata *data, *next;
unsigned long flags;
int found = 0;
@@ -732,14 +732,13 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
return;
spin_lock_irqsave(&priv->lock, flags);
- list_for_each_entry(data, &priv->clients, domain_node) {
+ list_for_each_entry_safe(data, next, &priv->clients, domain_node) {
if (data->master == dev) {
if (__sysmmu_disable(data)) {
data->master = NULL;
list_del_init(&data->domain_node);
}
found = true;
- break;
}
}
spin_unlock_irqrestore(&priv->lock, flags);
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 23/29] iommu: exynos: init iommu controllers from device tree
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (21 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 22/29] iommu: exynos: add support for binding more than one sysmmu to master device Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 24/29] iommu: exynos: create default iommu-based dma-mapping for master devices Marek Szyprowski
` (6 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds code to initialize and assign SYSMMU controllers to
their master devices defined in device tree.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 152 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 145 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 46e0edc..845f547 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -21,6 +21,7 @@
#include <linux/err.h>
#include <linux/mm.h>
#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/iommu.h>
#include <linux/errno.h>
#include <linux/list.h>
@@ -211,6 +212,9 @@ struct sysmmu_drvdata {
struct list_head owner_node;
phys_addr_t pgtable;
int version;
+ const char *name;
+ dma_addr_t base;
+ size_t size;
};
static bool set_sysmmu_active(struct sysmmu_drvdata *data)
@@ -574,6 +578,11 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
}
data->sysmmu = dev;
+
+ /* default io address space parameters */
+ data->base = SZ_1G;
+ data->size = SZ_2G;
+
spin_lock_init(&data->lock);
platform_set_drvdata(pdev, data);
@@ -1055,30 +1064,159 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
return phys;
}
+static void __free_owner_struct(struct exynos_iommu_owner *owner,
+ struct device *dev)
+{
+ while (!list_empty(&owner->clients))
+ list_del_init(owner->clients.next);
+
+ kfree(owner);
+ dev->archdata.iommu = NULL;
+}
+
+static int __init_master_sysmmu(struct device *dev)
+{
+ struct of_phandle_args sysmmu_spec;
+ struct exynos_iommu_owner *owner;
+ int i = 0;
+ int ret;
+
+ owner = kzalloc(sizeof(*owner), GFP_KERNEL);
+ if (!owner)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&owner->clients);
+
+ while (!of_parse_phandle_with_args(dev->of_node, "iommus",
+ "#iommu-cells", i,
+ &sysmmu_spec)) {
+ struct platform_device *sysmmu;
+ struct sysmmu_drvdata *data;
+
+ sysmmu = of_find_device_by_node(sysmmu_spec.np);
+ if (!sysmmu) {
+ dev_err(dev, "sysmmu node not found\n");
+ ret = -ENODEV;
+ goto err;
+ }
+ data = platform_get_drvdata(sysmmu);
+ if (!data) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ of_property_read_string_index(dev->of_node, "iommu-names", i,
+ &data->name);
+
+ if (sysmmu_spec.args_count == 2) {
+ data->base = sysmmu_spec.args[0];
+ data->size = sysmmu_spec.args[1];
+ } else if (sysmmu_spec.args_count != 0) {
+ dev_err(dev, "incorrect iommu property specified\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ list_add_tail(&data->owner_node, &owner->clients);
+
+ i++;
+ }
+
+ if (i == 0) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ dev->archdata.iommu = owner;
+ dev_dbg(dev, "registered %d sysmmu controllers\n", i);
+
+ return 0;
+err:
+ __free_owner_struct(owner, dev);
+ return ret;
+}
+
+static int __init_subdevice_sysmmu(struct device *dev)
+{
+ struct device *parent = dev->parent;
+ struct exynos_iommu_owner *owner;
+ struct sysmmu_drvdata *data;
+ char *name;
+
+ name = strrchr(dev_name(dev), ':');
+ if (!name)
+ return -ENODEV;
+ name++;
+
+ owner = parent->archdata.iommu;
+ if (!owner)
+ return -ENODEV;
+
+ list_for_each_entry(data, &owner->clients, owner_node)
+ if (strcmp(name, data->name) == 0)
+ break;
+ if (!data)
+ return -ENODEV;
+
+ owner = kzalloc(sizeof(*owner), GFP_KERNEL);
+ if (!owner)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&owner->clients);
+
+ /* move sysmmu from parent to child device */
+ list_del(&data->owner_node);
+ list_add_tail(&data->owner_node, &owner->clients);
+
+ dev->archdata.iommu = owner;
+ dev_dbg(dev->parent,
+ "registered sysmmu controller for %s subdevice\n", data->name);
+
+ return 0;
+}
+
static int exynos_iommu_add_device(struct device *dev)
{
struct iommu_group *group;
int ret;
- group = iommu_group_get(dev);
+ BUG_ON(dev->archdata.iommu != NULL);
- if (!group) {
- group = iommu_group_alloc();
- if (IS_ERR(group)) {
- dev_err(dev, "Failed to allocate IOMMU group\n");
- return PTR_ERR(group);
- }
+ if (of_get_property(dev->of_node, "iommus", NULL))
+ ret = __init_master_sysmmu(dev);
+ else if (dev->parent &&
+ of_get_property(dev->parent->of_node, "iommus", NULL))
+ ret = __init_subdevice_sysmmu(dev);
+ else
+ return -ENODEV;
+
+ if (ret)
+ return ret;
+
+ group = iommu_group_alloc();
+ if (IS_ERR(group)) {
+ dev_err(dev, "Failed to allocate IOMMU group\n");
+ ret = PTR_ERR(group);
+ goto err;
}
ret = iommu_group_add_device(group, dev);
+ if (ret != 0)
+ goto err;
+
iommu_group_put(group);
+ return 0;
+err:
+ __free_owner_struct(dev->archdata.iommu, dev);
return ret;
}
static void exynos_iommu_remove_device(struct device *dev)
{
+ struct exynos_iommu_owner *owner = dev->archdata.iommu;
+
iommu_group_remove_device(dev);
+ if (owner)
+ __free_owner_struct(owner, dev);
}
static const struct iommu_ops exynos_iommu_ops = {
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 24/29] iommu: exynos: create default iommu-based dma-mapping for master devices
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (22 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 23/29] iommu: exynos: init iommu controllers from device tree Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 25/29] iommu: exynos: add support for runtime_pm Marek Szyprowski
` (5 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch adds code to create default per-device iommu-based
dma-mapping instance for all master devices, whose driver didn't set
DRIVER_HAS_OWN_IOMMU_MANAGER flag.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 49 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 845f547..336b2f8 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -12,6 +12,7 @@
#define DEBUG
#endif
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
@@ -29,6 +30,7 @@
#include <linux/export.h>
#include <asm/cacheflush.h>
+#include <asm/dma-iommu.h>
#include <asm/pgtable.h>
typedef u32 sysmmu_iova_t;
@@ -1064,6 +1066,43 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
return phys;
}
+static int sysmmu_master_device_event(struct notifier_block *nb,
+ unsigned long val, void *p)
+{
+ struct device *dev = p;
+ struct exynos_iommu_owner *owner = dev->archdata.iommu;
+ struct sysmmu_drvdata *data;
+
+ if (!owner)
+ return 0;
+
+ data = list_first_entry(&owner->clients, struct sysmmu_drvdata,
+ owner_node);
+ if (!data)
+ return 0;
+
+ switch (val) {
+
+ case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
+ if (!(dev->driver->flags & DRIVER_HAS_OWN_IOMMU_MANAGER))
+ arm_iommu_create_default_mapping(dev, data->base,
+ data->size);
+ break;
+
+ case IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER:
+ case IOMMU_GROUP_NOTIFY_DRVBIND_FAILED:
+ if (!(dev->driver->flags & DRIVER_HAS_OWN_IOMMU_MANAGER))
+ arm_iommu_release_default_mapping(dev);
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block sysmmu_master_device_notifier = {
+ .notifier_call = sysmmu_master_device_event,
+};
+
static void __free_owner_struct(struct exynos_iommu_owner *owner,
struct device *dev)
{
@@ -1202,6 +1241,7 @@ static int exynos_iommu_add_device(struct device *dev)
if (ret != 0)
goto err;
+ iommu_group_register_notifier(group, &sysmmu_master_device_notifier);
iommu_group_put(group);
return 0;
@@ -1213,8 +1253,15 @@ err:
static void exynos_iommu_remove_device(struct device *dev)
{
struct exynos_iommu_owner *owner = dev->archdata.iommu;
+ struct iommu_group *group = iommu_group_get(dev);
+
+ if (group) {
+ iommu_group_unregister_notifier(group,
+ &sysmmu_master_device_notifier);
+ iommu_group_remove_device(dev);
+ iommu_group_put(group);
+ }
- iommu_group_remove_device(dev);
if (owner)
__free_owner_struct(owner, dev);
}
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 25/29] iommu: exynos: add support for runtime_pm
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (23 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 24/29] iommu: exynos: create default iommu-based dma-mapping for master devices Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 26/29] iommu: exynos: rename variables to reflect their purpose Marek Szyprowski
` (4 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch enables support for runtime pm for SYSMMU controllers. State
of each controller is saved before master's device power domain is
turned off and restored after it has been turned on.
exynos_iommu_attach_device() function might be called anytime, even when
power domain for master's device has been turned off, so to let SYSMMU
controllers to access its registers, a call to pm_runtime_get_sync() has
to be done, which turns on the power domain, which SYSMMU belongs to.
Later, once SYSMMU has been enabled, a call to pm_runtime_put() lets
runtime pm to turn off the power domain if there are no other devices
enabled. This way, the SYSMMU drivers get a genpd pm event and save its
state with sysmmu_save_state() function.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 336b2f8..5cd91b11 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -28,6 +28,7 @@
#include <linux/list.h>
#include <linux/memblock.h>
#include <linux/export.h>
+#include <linux/pm_domain.h>
#include <asm/cacheflush.h>
#include <asm/dma-iommu.h>
@@ -208,6 +209,7 @@ struct sysmmu_drvdata {
struct clk *clk;
struct clk *clk_master;
int activations;
+ int suspended;
spinlock_t lock;
struct iommu_domain *domain;
struct list_head domain_node;
@@ -217,6 +219,7 @@ struct sysmmu_drvdata {
const char *name;
dma_addr_t base;
size_t size;
+ struct notifier_block pm_notifier;
};
static bool set_sysmmu_active(struct sysmmu_drvdata *data)
@@ -235,7 +238,7 @@ static bool set_sysmmu_inactive(struct sysmmu_drvdata *data)
static bool is_sysmmu_active(struct sysmmu_drvdata *data)
{
- return data->activations > 0;
+ return (!data->suspended && data->activations > 0);
}
static void sysmmu_unblock(void __iomem *sfrbase)
@@ -528,6 +531,51 @@ static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
spin_unlock_irqrestore(&data->lock, flags);
}
+static void sysmmu_restore_state(struct sysmmu_drvdata *data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&data->lock, flags);
+ if (data->activations > 0) {
+ data->suspended = false;
+ __sysmmu_enable_nocount(data);
+ dev_dbg(data->sysmmu, "restored state\n");
+ }
+ spin_unlock_irqrestore(&data->lock, flags);
+}
+
+static void sysmmu_save_state(struct sysmmu_drvdata *data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&data->lock, flags);
+ if (data->activations > 0) {
+ __sysmmu_disable_nocount(data);
+ data->suspended = true;
+ dev_dbg(data->sysmmu, "saved state\n");
+ }
+ spin_unlock_irqrestore(&data->lock, flags);
+}
+
+static int sysmmu_runtime_genpd_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct sysmmu_drvdata *data;
+
+ data = container_of(this, struct sysmmu_drvdata, pm_notifier);
+
+ switch (event) {
+ case PM_GENPD_POST_POWER_ON:
+ sysmmu_restore_state(data);
+ break;
+ case PM_GENPD_POWER_OFF_PREPARE:
+ sysmmu_save_state(data);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
static int __init exynos_sysmmu_probe(struct platform_device *pdev)
{
int irq, ret;
@@ -580,6 +628,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
}
data->sysmmu = dev;
+ data->pm_notifier.notifier_call = sysmmu_runtime_genpd_event;
/* default io address space parameters */
data->base = SZ_1G;
@@ -708,6 +757,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
return -ENODEV;
list_for_each_entry(data, &owner->clients, owner_node) {
+ pm_runtime_get_sync(data->sysmmu);
ret = __sysmmu_enable(data, pagetable, domain);
if (ret >= 0) {
data->master = dev;
@@ -716,6 +766,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
list_add_tail(&data->domain_node, &priv->clients);
spin_unlock_irqrestore(&priv->lock, flags);
}
+ pm_runtime_put(data->sysmmu);
}
if (ret < 0) {
@@ -1156,6 +1207,7 @@ static int __init_master_sysmmu(struct device *dev)
}
list_add_tail(&data->owner_node, &owner->clients);
+ pm_genpd_register_notifier(dev, &data->pm_notifier);
i++;
}
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 26/29] iommu: exynos: rename variables to reflect their purpose
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (24 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 25/29] iommu: exynos: add support for runtime_pm Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 27/29] iommu: exynos: document internal structures Marek Szyprowski
` (3 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch renames some variables to make the code easier to understand.
'domain' is replaced by 'iommu_domain' (more generic entity) and really
meaning less 'priv' by 'domain' to reflect its purpose.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 191 ++++++++++++++++++++++---------------------
1 file changed, 97 insertions(+), 94 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5cd91b11..7600861 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -440,8 +440,8 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
clk_disable(data->clk_master);
}
-static int __sysmmu_enable(struct sysmmu_drvdata *data,
- phys_addr_t pgtable, struct iommu_domain *domain)
+static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
+ struct iommu_domain *iommu_domain)
{
int ret = 0;
unsigned long flags;
@@ -449,7 +449,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
spin_lock_irqsave(&data->lock, flags);
if (set_sysmmu_active(data)) {
data->pgtable = pgtable;
- data->domain = domain;
+ data->domain = iommu_domain;
__sysmmu_enable_nocount(data);
@@ -664,92 +664,93 @@ static inline void pgtable_flush(void *vastart, void *vaend)
virt_to_phys(vaend));
}
-static int exynos_iommu_domain_init(struct iommu_domain *domain)
+static int exynos_iommu_domain_init(struct iommu_domain *iommu_domain)
{
- struct exynos_iommu_domain *priv;
+ struct exynos_iommu_domain *domain;
int i;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
+ domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+ if (!domain)
return -ENOMEM;
- priv->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
- if (!priv->pgtable)
+ domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
+ if (!domain->pgtable)
goto err_pgtable;
- priv->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
- if (!priv->lv2entcnt)
+ domain->lv2entcnt = (short *)
+ __get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
+ if (!domain->lv2entcnt)
goto err_counter;
/* w/a of System MMU v3.3 to prevent caching 1MiB mapping */
for (i = 0; i < NUM_LV1ENTRIES; i += 8) {
- priv->pgtable[i + 0] = ZERO_LV2LINK;
- priv->pgtable[i + 1] = ZERO_LV2LINK;
- priv->pgtable[i + 2] = ZERO_LV2LINK;
- priv->pgtable[i + 3] = ZERO_LV2LINK;
- priv->pgtable[i + 4] = ZERO_LV2LINK;
- priv->pgtable[i + 5] = ZERO_LV2LINK;
- priv->pgtable[i + 6] = ZERO_LV2LINK;
- priv->pgtable[i + 7] = ZERO_LV2LINK;
+ domain->pgtable[i + 0] = ZERO_LV2LINK;
+ domain->pgtable[i + 1] = ZERO_LV2LINK;
+ domain->pgtable[i + 2] = ZERO_LV2LINK;
+ domain->pgtable[i + 3] = ZERO_LV2LINK;
+ domain->pgtable[i + 4] = ZERO_LV2LINK;
+ domain->pgtable[i + 5] = ZERO_LV2LINK;
+ domain->pgtable[i + 6] = ZERO_LV2LINK;
+ domain->pgtable[i + 7] = ZERO_LV2LINK;
}
- pgtable_flush(priv->pgtable, priv->pgtable + NUM_LV1ENTRIES);
+ pgtable_flush(domain->pgtable, domain->pgtable + NUM_LV1ENTRIES);
- spin_lock_init(&priv->lock);
- spin_lock_init(&priv->pgtablelock);
- INIT_LIST_HEAD(&priv->clients);
+ spin_lock_init(&domain->lock);
+ spin_lock_init(&domain->pgtablelock);
+ INIT_LIST_HEAD(&domain->clients);
- domain->geometry.aperture_start = 0;
- domain->geometry.aperture_end = ~0UL;
- domain->geometry.force_aperture = true;
+ iommu_domain->geometry.aperture_start = 0;
+ iommu_domain->geometry.aperture_end = ~0UL;
+ iommu_domain->geometry.force_aperture = true;
- domain->priv = priv;
+ iommu_domain->priv = domain;
return 0;
err_counter:
- free_pages((unsigned long)priv->pgtable, 2);
+ free_pages((unsigned long)domain->pgtable, 2);
err_pgtable:
- kfree(priv);
+ kfree(domain);
return -ENOMEM;
}
-static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+static void exynos_iommu_domain_destroy(struct iommu_domain *iommu_domain)
{
- struct exynos_iommu_domain *priv = domain->priv;
+ struct exynos_iommu_domain *domain = iommu_domain->priv;
struct sysmmu_drvdata *data;
unsigned long flags;
int i;
- WARN_ON(!list_empty(&priv->clients));
+ WARN_ON(!list_empty(&domain->clients));
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock_irqsave(&domain->lock, flags);
- list_for_each_entry(data, &priv->clients, domain_node) {
+ list_for_each_entry(data, &domain->clients, domain_node) {
if (__sysmmu_disable(data))
data->master = NULL;
list_del_init(&data->domain_node);
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&domain->lock, flags);
for (i = 0; i < NUM_LV1ENTRIES; i++)
- if (lv1ent_page(priv->pgtable + i))
+ if (lv1ent_page(domain->pgtable + i))
kmem_cache_free(lv2table_kmem_cache,
- phys_to_virt(lv2table_base(priv->pgtable + i)));
+ phys_to_virt(lv2table_base(domain->pgtable + i)));
- free_pages((unsigned long)priv->pgtable, 2);
- free_pages((unsigned long)priv->lv2entcnt, 1);
- kfree(domain->priv);
- domain->priv = NULL;
+ free_pages((unsigned long)domain->pgtable, 2);
+ free_pages((unsigned long)domain->lv2entcnt, 1);
+ kfree(iommu_domain->priv);
+ iommu_domain->priv = NULL;
}
-static int exynos_iommu_attach_device(struct iommu_domain *domain,
+static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
struct device *dev)
{
struct exynos_iommu_owner *owner = dev->archdata.iommu;
- struct exynos_iommu_domain *priv = domain->priv;
+ struct exynos_iommu_domain *domain = iommu_domain->priv;
struct sysmmu_drvdata *data;
- phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+ phys_addr_t pagetable = virt_to_phys(domain->pgtable);
unsigned long flags;
int ret = -ENODEV;
@@ -758,13 +759,13 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
list_for_each_entry(data, &owner->clients, owner_node) {
pm_runtime_get_sync(data->sysmmu);
- ret = __sysmmu_enable(data, pagetable, domain);
+ ret = __sysmmu_enable(data, pagetable, iommu_domain);
if (ret >= 0) {
data->master = dev;
- spin_lock_irqsave(&priv->lock, flags);
- list_add_tail(&data->domain_node, &priv->clients);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_lock_irqsave(&domain->lock, flags);
+ list_add_tail(&data->domain_node, &domain->clients);
+ spin_unlock_irqrestore(&domain->lock, flags);
}
pm_runtime_put(data->sysmmu);
}
@@ -781,11 +782,11 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
return ret;
}
-static void exynos_iommu_detach_device(struct iommu_domain *domain,
+static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
struct device *dev)
{
- struct exynos_iommu_domain *priv = domain->priv;
- phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+ struct exynos_iommu_domain *domain = iommu_domain->priv;
+ phys_addr_t pagetable = virt_to_phys(domain->pgtable);
struct sysmmu_drvdata *data, *next;
unsigned long flags;
int found = 0;
@@ -793,8 +794,8 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
if (!has_sysmmu(dev))
return;
- spin_lock_irqsave(&priv->lock, flags);
- list_for_each_entry_safe(data, next, &priv->clients, domain_node) {
+ spin_lock_irqsave(&domain->lock, flags);
+ list_for_each_entry_safe(data, next, &domain->clients, domain_node) {
if (data->master == dev) {
if (__sysmmu_disable(data)) {
data->master = NULL;
@@ -803,7 +804,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
found = true;
}
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&domain->lock, flags);
if (found)
dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
@@ -812,7 +813,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
dev_err(dev, "%s: No IOMMU is attached\n", __func__);
}
-static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
+static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *domain,
sysmmu_pte_t *sent, sysmmu_iova_t iova, short *pgcounter)
{
if (lv1ent_section(sent)) {
@@ -854,17 +855,17 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
if (need_flush_flpd_cache) {
struct sysmmu_drvdata *data;
- spin_lock(&priv->lock);
- list_for_each_entry(data, &priv->clients, domain_node)
+ spin_lock(&domain->lock);
+ list_for_each_entry(data, &domain->clients, domain_node)
sysmmu_tlb_invalidate_flpdcache(data, iova);
- spin_unlock(&priv->lock);
+ spin_unlock(&domain->lock);
}
}
return page_entry(sent, iova);
}
-static int lv1set_section(struct exynos_iommu_domain *priv,
+static int lv1set_section(struct exynos_iommu_domain *domain,
sysmmu_pte_t *sent, sysmmu_iova_t iova,
phys_addr_t paddr, short *pgcnt)
{
@@ -889,17 +890,17 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
pgtable_flush(sent, sent + 1);
- spin_lock(&priv->lock);
+ spin_lock(&domain->lock);
if (lv1ent_page_zero(sent)) {
struct sysmmu_drvdata *data;
/*
* Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
* entry by speculative prefetch of SLPD which has no mapping.
*/
- list_for_each_entry(data, &priv->clients, domain_node)
+ list_for_each_entry(data, &domain->clients, domain_node)
sysmmu_tlb_invalidate_flpdcache(data, iova);
}
- spin_unlock(&priv->lock);
+ spin_unlock(&domain->lock);
return 0;
}
@@ -959,74 +960,76 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size,
* than or equal size to 128KiB.
* - Start address of an I/O virtual region must be aligned by 128KiB.
*/
-static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
- phys_addr_t paddr, size_t size, int prot)
+static int exynos_iommu_map(struct iommu_domain *iommu_domain,
+ unsigned long l_iova, phys_addr_t paddr, size_t size,
+ int prot)
{
- struct exynos_iommu_domain *priv = domain->priv;
+ struct exynos_iommu_domain *domain = iommu_domain->priv;
sysmmu_pte_t *entry;
sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
unsigned long flags;
int ret = -ENOMEM;
- BUG_ON(priv->pgtable == NULL);
+ BUG_ON(domain->pgtable == NULL);
- spin_lock_irqsave(&priv->pgtablelock, flags);
+ spin_lock_irqsave(&domain->pgtablelock, flags);
- entry = section_entry(priv->pgtable, iova);
+ entry = section_entry(domain->pgtable, iova);
if (size == SECT_SIZE) {
- ret = lv1set_section(priv, entry, iova, paddr,
- &priv->lv2entcnt[lv1ent_offset(iova)]);
+ ret = lv1set_section(domain, entry, iova, paddr,
+ &domain->lv2entcnt[lv1ent_offset(iova)]);
} else {
sysmmu_pte_t *pent;
- pent = alloc_lv2entry(priv, entry, iova,
- &priv->lv2entcnt[lv1ent_offset(iova)]);
+ pent = alloc_lv2entry(domain, entry, iova,
+ &domain->lv2entcnt[lv1ent_offset(iova)]);
if (IS_ERR(pent))
ret = PTR_ERR(pent);
else
ret = lv2set_page(pent, paddr, size,
- &priv->lv2entcnt[lv1ent_offset(iova)]);
+ &domain->lv2entcnt[lv1ent_offset(iova)]);
}
if (ret)
pr_err("%s: Failed(%d) to map %#zx bytes @ %#x\n",
__func__, ret, size, iova);
- spin_unlock_irqrestore(&priv->pgtablelock, flags);
+ spin_unlock_irqrestore(&domain->pgtablelock, flags);
return ret;
}
-static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
- sysmmu_iova_t iova, size_t size)
+static
+void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *domain,
+ sysmmu_iova_t iova, size_t size)
{
struct sysmmu_drvdata *data;
unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock_irqsave(&domain->lock, flags);
- list_for_each_entry(data, &priv->clients, domain_node)
+ list_for_each_entry(data, &domain->clients, domain_node)
sysmmu_tlb_invalidate_entry(data, iova, size);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&domain->lock, flags);
}
-static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+static size_t exynos_iommu_unmap(struct iommu_domain *iommu_domain,
unsigned long l_iova, size_t size)
{
- struct exynos_iommu_domain *priv = domain->priv;
+ struct exynos_iommu_domain *domain = iommu_domain->priv;
sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
sysmmu_pte_t *ent;
size_t err_pgsize;
unsigned long flags;
- BUG_ON(priv->pgtable == NULL);
+ BUG_ON(domain->pgtable == NULL);
- spin_lock_irqsave(&priv->pgtablelock, flags);
+ spin_lock_irqsave(&domain->pgtablelock, flags);
- ent = section_entry(priv->pgtable, iova);
+ ent = section_entry(domain->pgtable, iova);
if (lv1ent_section(ent)) {
if (WARN_ON(size < SECT_SIZE)) {
@@ -1059,7 +1062,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
*ent = 0;
size = SPAGE_SIZE;
pgtable_flush(ent, ent + 1);
- priv->lv2entcnt[lv1ent_offset(iova)] += 1;
+ domain->lv2entcnt[lv1ent_offset(iova)] += 1;
goto done;
}
@@ -1073,15 +1076,15 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
size = LPAGE_SIZE;
- priv->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
+ domain->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
done:
- spin_unlock_irqrestore(&priv->pgtablelock, flags);
+ spin_unlock_irqrestore(&domain->pgtablelock, flags);
- exynos_iommu_tlb_invalidate_entry(priv, iova, size);
+ exynos_iommu_tlb_invalidate_entry(domain, iova, size);
return size;
err:
- spin_unlock_irqrestore(&priv->pgtablelock, flags);
+ spin_unlock_irqrestore(&domain->pgtablelock, flags);
pr_err("%s: Failed: size(%#zx) @ %#x is smaller than page size %#zx\n",
__func__, size, iova, err_pgsize);
@@ -1089,17 +1092,17 @@ err:
return 0;
}
-static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
+static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
dma_addr_t iova)
{
- struct exynos_iommu_domain *priv = domain->priv;
+ struct exynos_iommu_domain *domain = iommu_domain->priv;
sysmmu_pte_t *entry;
unsigned long flags;
phys_addr_t phys = 0;
- spin_lock_irqsave(&priv->pgtablelock, flags);
+ spin_lock_irqsave(&domain->pgtablelock, flags);
- entry = section_entry(priv->pgtable, iova);
+ entry = section_entry(domain->pgtable, iova);
if (lv1ent_section(entry)) {
phys = section_phys(entry) + section_offs(iova);
@@ -1112,7 +1115,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
phys = spage_phys(entry) + spage_offs(iova);
}
- spin_unlock_irqrestore(&priv->pgtablelock, flags);
+ spin_unlock_irqrestore(&domain->pgtablelock, flags);
return phys;
}
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 27/29] iommu: exynos: document internal structures
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (25 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 26/29] iommu: exynos: rename variables to reflect their purpose Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 28/29] iommu: exynos: remove excessive includes and sort others alphabetically Marek Szyprowski
` (2 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Add a few words of comment to all internal structures used by the driver.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 59 ++++++++++++++++++++++++++++----------------
1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 7600861..78ce618 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -189,37 +189,54 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
"UNKNOWN FAULT"
};
-/* attached to dev.archdata.iommu of the master device */
+/*
+ * This structure is attached to dev.archdata.iommu of the master device
+ * on device add, contains a list of SYSMMU controllers defined by device tree,
+ * which are bound to given master device. It is usually referenced by 'owner'
+ * pointer.
+ */
struct exynos_iommu_owner {
- struct list_head clients;
+ struct list_head clients; /* list of sysmmu_drvdata.owner_node */
};
+/*
+ * This structure is stored in ->priv field of generic struct iommu_domain,
+ * contains list of SYSMMU controllers from all master devices, which has been
+ * attached to this domain and page tables of IO address space defined by this
+ * domain. It is usually referenced by 'domain' pointer.
+ */
struct exynos_iommu_domain {
- struct list_head clients; /* list of sysmmu_drvdata.node */
+ struct list_head clients; /* list of sysmmu_drvdata.domain_node */
sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
short *lv2entcnt; /* free lv2 entry counter for each section */
- spinlock_t lock; /* lock for this structure */
+ spinlock_t lock; /* lock for modyfying list of clients */
spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
};
+/*
+ * This structure hold all data of a single SYSMMU controller, this includes
+ * hw resources like registers and clocks, pointers and list nodes to connect
+ * it to all other structures, internal state and parameters read from device
+ * tree. It is usually referenced by 'data' pointer.
+ */
struct sysmmu_drvdata {
- struct device *sysmmu; /* System MMU's device descriptor */
- struct device *master; /* Owner of system MMU */
- void __iomem *sfrbase;
- struct clk *clk;
- struct clk *clk_master;
- int activations;
- int suspended;
- spinlock_t lock;
- struct iommu_domain *domain;
- struct list_head domain_node;
- struct list_head owner_node;
- phys_addr_t pgtable;
- int version;
- const char *name;
- dma_addr_t base;
- size_t size;
- struct notifier_block pm_notifier;
+ struct device *sysmmu; /* SYSMMU controller device */
+ struct device *master; /* master device (owner of given SYSMMU) */
+ void __iomem *sfrbase; /* our registers */
+ struct clk *clk; /* SYSMMU's clock */
+ struct clk *clk_master; /* master's device clock */
+ int activations; /* number of calls to sysmmu_enable */
+ int suspended; /* status of the controller (managed by runtime pm) */
+ spinlock_t lock; /* lock for modyfying enable/disable state */
+ struct iommu_domain *domain; /* domain we belong to */
+ struct list_head domain_node; /* node for domain clients list */
+ struct list_head owner_node; /* node for owner clients list */
+ phys_addr_t pgtable; /* assigned page table structure */
+ int version; /* our version */
+ const char *name; /* our name from device tree */
+ dma_addr_t base; /* base addres of IO address space define in DT */
+ size_t size; /* size of IO address space define in DT */
+ struct notifier_block pm_notifier; /* notifier for pm domain on/off */
};
static bool set_sysmmu_active(struct sysmmu_drvdata *data)
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 28/29] iommu: exynos: remove excessive includes and sort others alphabetically
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (26 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 27/29] iommu: exynos: document internal structures Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-05 10:47 ` [PATCH 29/29] temporary: media: s5p-mfc: add support for IOMMU Marek Szyprowski
2014-08-18 23:32 ` [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Joerg Roedel
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Removed following unused includes: <linux/mm.h>, <linux/errno.h>,
<linux/memblock.h> and <linux/export.h>.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/iommu/exynos-iommu.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 78ce618..1bbb100 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -12,23 +12,19 @@
#define DEBUG
#endif
+#include <linux/clk.h>
#include <linux/dma-mapping.h>
+#include <linux/err.h>
#include <linux/io.h>
+#include <linux/iommu.h>
#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/mm.h>
+#include <linux/list.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/iommu.h>
-#include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/memblock.h>
-#include <linux/export.h>
+#include <linux/platform_device.h>
#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/dma-iommu.h>
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH 29/29] temporary: media: s5p-mfc: add support for IOMMU
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (27 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 28/29] iommu: exynos: remove excessive includes and sort others alphabetically Marek Szyprowski
@ 2014-08-05 10:47 ` Marek Szyprowski
2014-08-18 23:32 ` [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Joerg Roedel
29 siblings, 0 replies; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-05 10:47 UTC (permalink / raw)
To: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel
Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
This patch is an example how to use more than one IOMMU controller in a
device driver for hardware blocks, which have more then one dma master
(memory interface with iommu controller).
This patch is temporary, do not merge it yet.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/media/platform/s5p-mfc/s5p_mfc.c | 46 ++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 77b99ae..c2e95ab 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,7 +22,11 @@
#include <media/v4l2-event.h>
#include <linux/workqueue.h>
#include <linux/of.h>
+#include <linux/of_platform.h>
#include <media/videobuf2-core.h>
+
+#include <asm/dma-iommu.h>
+
#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
@@ -996,6 +1000,39 @@ static const struct v4l2_file_operations s5p_mfc_fops = {
.mmap = s5p_mfc_mmap,
};
+static struct device *s5p_mfc_alloc_memdev(struct device *dev, const char *name)
+{
+ struct device *child;
+ int ret;
+
+ child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
+ if (!child)
+ return NULL;
+
+ device_initialize(child);
+ dev_set_name(child, "%s:%s", dev_name(dev), name);
+ child->parent = dev;
+ child->bus = dev->bus;
+ child->coherent_dma_mask = dev->coherent_dma_mask;
+ child->dma_mask = dev->dma_mask;
+
+ if (device_add(child) == 0) {
+ ret = arm_iommu_create_default_mapping(child, 0x20000000,
+ SZ_256M);
+ if (ret == 0)
+ return child;
+ }
+
+ put_device(child);
+ return NULL;
+}
+
+void s5p_mfc_free_memdev(struct device *dev)
+{
+ arm_iommu_release_default_mapping(dev);
+ put_device(dev);
+}
+
static void *mfc_get_drv_data(struct platform_device *pdev);
/* MFC probe function */
@@ -1049,8 +1086,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
goto err_res;
}
- dev->mem_dev_l = &dev->plat_dev->dev;
- dev->mem_dev_r = &dev->plat_dev->dev;
+ dev->mem_dev_l = s5p_mfc_alloc_memdev(&dev->plat_dev->dev, "left");
+ dev->mem_dev_r = s5p_mfc_alloc_memdev(&dev->plat_dev->dev, "right");
dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
if (IS_ERR(dev->alloc_ctx[0])) {
@@ -1181,6 +1218,10 @@ static int s5p_mfc_remove(struct platform_device *pdev)
s5p_mfc_release_firmware(dev);
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
+ if (dev->mem_dev_l)
+ s5p_mfc_free_memdev(dev->mem_dev_l);
+ if (dev->mem_dev_r)
+ s5p_mfc_free_memdev(dev->mem_dev_r);
s5p_mfc_final_pm(dev);
return 0;
@@ -1436,6 +1477,7 @@ static struct platform_driver s5p_mfc_driver = {
.owner = THIS_MODULE,
.pm = &s5p_mfc_pm_ops,
.of_match_table = exynos_mfc_match,
+ .flags = DRIVER_HAS_OWN_IOMMU_MANAGER,
},
};
--
1.9.2
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
2014-08-05 10:47 [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
` (28 preceding siblings ...)
2014-08-05 10:47 ` [PATCH 29/29] temporary: media: s5p-mfc: add support for IOMMU Marek Szyprowski
@ 2014-08-18 23:32 ` Joerg Roedel
2014-08-19 6:07 ` Marek Szyprowski
29 siblings, 1 reply; 50+ messages in thread
From: Joerg Roedel @ 2014-08-18 23:32 UTC (permalink / raw)
To: Marek Szyprowski
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
On Tue, Aug 05, 2014 at 12:47:28PM +0200, Marek Szyprowski wrote:
> .../devicetree/bindings/iommu/samsung,sysmmu.txt | 93 ++-
> Documentation/power/notifiers.txt | 14 +
> arch/arm/boot/dts/exynos4.dtsi | 118 ++++
> arch/arm/boot/dts/exynos4210.dtsi | 23 +
> arch/arm/boot/dts/exynos4x12.dtsi | 82 +++
> arch/arm/include/asm/dma-iommu.h | 36 ++
> arch/arm/mach-exynos/pm_domains.c | 12 +-
> arch/arm/mach-integrator/impd1.c | 2 +-
> arch/arm/mm/dma-mapping.c | 47 ++
> drivers/base/bus.c | 4 +-
> drivers/base/dd.c | 10 +-
> drivers/base/platform.c | 2 +-
> drivers/base/power/domain.c | 70 ++-
> drivers/clk/samsung/clk-exynos4.c | 1 +
> drivers/gpu/drm/exynos/exynos_drm_fimc.c | 1 +
> drivers/gpu/drm/exynos/exynos_drm_fimd.c | 26 +-
> drivers/gpu/drm/exynos/exynos_drm_g2d.c | 1 +
> drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 +
> drivers/gpu/drm/exynos/exynos_drm_rotator.c | 1 +
> drivers/gpu/drm/exynos/exynos_mixer.c | 1 +
> drivers/iommu/exynos-iommu.c | 663 +++++++++++++--------
> drivers/iommu/iommu.c | 3 +
> drivers/media/platform/s5p-mfc/s5p_mfc.c | 107 ++--
> drivers/pci/host/pci-mvebu.c | 2 +-
> drivers/pci/host/pci-rcar-gen2.c | 2 +-
> drivers/pci/host/pci-tegra.c | 2 +-
> drivers/pci/host/pcie-rcar.c | 2 +-
> drivers/soc/tegra/pmc.c | 2 +-
> include/dt-bindings/clock/exynos4.h | 10 +-
> include/linux/device.h | 12 +-
> include/linux/iommu.h | 1 +
> include/linux/pm.h | 2 +
> include/linux/pm_domain.h | 19 +
> 33 files changed, 1016 insertions(+), 356 deletions(-)
This touches a lot of non-iommu stuff. What is your strategy on getting
this in, do you plan to get the non-iommu changes merged first or do you
want to collect the respective Acks and merge this all through one tree?
Joerg
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
2014-08-18 23:32 ` [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Joerg Roedel
@ 2014-08-19 6:07 ` Marek Szyprowski
2014-08-19 11:39 ` Andreas Färber
0 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-19 6:07 UTC (permalink / raw)
To: Joerg Roedel
Cc: iommu, linux-samsung-soc, linux-arm-kernel, linux-kernel,
linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo,
Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
Greg Kroah-Hartman, Rafael J. Wysocki, Inki Dae, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park
Hello,
On 2014-08-19 01:32, Joerg Roedel wrote:
> On Tue, Aug 05, 2014 at 12:47:28PM +0200, Marek Szyprowski wrote:
>> .../devicetree/bindings/iommu/samsung,sysmmu.txt | 93 ++-
>> Documentation/power/notifiers.txt | 14 +
>> arch/arm/boot/dts/exynos4.dtsi | 118 ++++
>> arch/arm/boot/dts/exynos4210.dtsi | 23 +
>> arch/arm/boot/dts/exynos4x12.dtsi | 82 +++
>> arch/arm/include/asm/dma-iommu.h | 36 ++
>> arch/arm/mach-exynos/pm_domains.c | 12 +-
>> arch/arm/mach-integrator/impd1.c | 2 +-
>> arch/arm/mm/dma-mapping.c | 47 ++
>> drivers/base/bus.c | 4 +-
>> drivers/base/dd.c | 10 +-
>> drivers/base/platform.c | 2 +-
>> drivers/base/power/domain.c | 70 ++-
>> drivers/clk/samsung/clk-exynos4.c | 1 +
>> drivers/gpu/drm/exynos/exynos_drm_fimc.c | 1 +
>> drivers/gpu/drm/exynos/exynos_drm_fimd.c | 26 +-
>> drivers/gpu/drm/exynos/exynos_drm_g2d.c | 1 +
>> drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 +
>> drivers/gpu/drm/exynos/exynos_drm_rotator.c | 1 +
>> drivers/gpu/drm/exynos/exynos_mixer.c | 1 +
>> drivers/iommu/exynos-iommu.c | 663 +++++++++++++--------
>> drivers/iommu/iommu.c | 3 +
>> drivers/media/platform/s5p-mfc/s5p_mfc.c | 107 ++--
>> drivers/pci/host/pci-mvebu.c | 2 +-
>> drivers/pci/host/pci-rcar-gen2.c | 2 +-
>> drivers/pci/host/pci-tegra.c | 2 +-
>> drivers/pci/host/pcie-rcar.c | 2 +-
>> drivers/soc/tegra/pmc.c | 2 +-
>> include/dt-bindings/clock/exynos4.h | 10 +-
>> include/linux/device.h | 12 +-
>> include/linux/iommu.h | 1 +
>> include/linux/pm.h | 2 +
>> include/linux/pm_domain.h | 19 +
>> 33 files changed, 1016 insertions(+), 356 deletions(-)
> This touches a lot of non-iommu stuff. What is your strategy on getting
> this in, do you plan to get the non-iommu changes merged first or do you
> want to collect the respective Acks and merge this all through one tree?
Those patches are posted as one patchset mainly to demonstrate how to get
everything to work together. I also posted this as a single patch series
to get some feedback from other iommu developers, especially all those
involved in the generic iommu dt bindings.
For merging, I will split them into smaller series and try to get
respective acks.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
2014-08-19 6:07 ` Marek Szyprowski
@ 2014-08-19 11:39 ` Andreas Färber
2014-08-19 12:01 ` Marek Szyprowski
0 siblings, 1 reply; 50+ messages in thread
From: Andreas Färber @ 2014-08-19 11:39 UTC (permalink / raw)
To: Marek Szyprowski, Inki Dae
Cc: Joerg Roedel, iommu, linux-samsung-soc, linux-arm-kernel,
linux-kernel, linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha,
Cho KyongHo, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park, Ajay Kumar
Hi Marek and Inki,
Am 19.08.2014 08:07, schrieb Marek Szyprowski:
> On 2014-08-19 01:32, Joerg Roedel wrote:
>> On Tue, Aug 05, 2014 at 12:47:28PM +0200, Marek Szyprowski wrote:
[...]
>>> 33 files changed, 1016 insertions(+), 356 deletions(-)
>> This touches a lot of non-iommu stuff. What is your strategy on getting
>> this in, do you plan to get the non-iommu changes merged first or do you
>> want to collect the respective Acks and merge this all through one tree?
>
> Those patches are posted as one patchset mainly to demonstrate how to get
> everything to work together. I also posted this as a single patch series
> to get some feedback from other iommu developers, especially all those
> involved in the generic iommu dt bindings.
>
> For merging, I will split them into smaller series and try to get
> respective acks.
I'm working on 5250 based Spring Chromebook and noticed that v3.17-rc1
got some more iommu support. With the new CONFIG_DRM_EXYNOS_IOMMU=y my
machine stops booting. So I'm wondering, is any of this a fix for 3.17,
or is all of this "unrelated" -next material? Also, are you or someone
working on the respective DT changes for Exynos5?
Regards,
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
2014-08-19 11:39 ` Andreas Färber
@ 2014-08-19 12:01 ` Marek Szyprowski
2014-08-19 12:30 ` Andreas Färber
0 siblings, 1 reply; 50+ messages in thread
From: Marek Szyprowski @ 2014-08-19 12:01 UTC (permalink / raw)
To: Andreas Färber, Inki Dae
Cc: Joerg Roedel, iommu, linux-samsung-soc, linux-arm-kernel,
linux-kernel, linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha,
Cho KyongHo, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park, Ajay Kumar
Hello,
On 2014-08-19 13:39, Andreas Färber wrote:
> Hi Marek and Inki,
>
> Am 19.08.2014 08:07, schrieb Marek Szyprowski:
>> On 2014-08-19 01:32, Joerg Roedel wrote:
>>> On Tue, Aug 05, 2014 at 12:47:28PM +0200, Marek Szyprowski wrote:
> [...]
>>>> 33 files changed, 1016 insertions(+), 356 deletions(-)
>>> This touches a lot of non-iommu stuff. What is your strategy on getting
>>> this in, do you plan to get the non-iommu changes merged first or do you
>>> want to collect the respective Acks and merge this all through one tree?
>> Those patches are posted as one patchset mainly to demonstrate how to get
>> everything to work together. I also posted this as a single patch series
>> to get some feedback from other iommu developers, especially all those
>> involved in the generic iommu dt bindings.
>>
>> For merging, I will split them into smaller series and try to get
>> respective acks.
> I'm working on 5250 based Spring Chromebook and noticed that v3.17-rc1
> got some more iommu support. With the new CONFIG_DRM_EXYNOS_IOMMU=y my
> machine stops booting. So I'm wondering, is any of this a fix for 3.17,
> or is all of this "unrelated" -next material?
This is probably a side effect of patch
3170447c1f264d51b8d1f3898bf2588588a64fdc
("iommu/exynos: Select ARM_DMA_USE_IOMMU"). It added selection of
ARM_DMA_USE_IOMMU
symbol, on which IOMMU support in Exynos DRM subsystem depends. However
selecting
this symbol is all that this patch does, without providing any code code
which
implements real support for ARM DMA IOMMU integration, which is needed
by Exynos
DRM driver. Please disable CONFIG_DRM_EXYNOS_IOMMU in kernel .config and
your
system should be bootable again.
> Also, are you or someone
> working on the respective DT changes for Exynos5?
I can prepare DT changes for Exynos5 as well, but first I wanted to
clarify if
everyone involved in generic IOMMU bindings and Exynos IOMMU driver
agrees on my
proposal.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH 00/29] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
2014-08-19 12:01 ` Marek Szyprowski
@ 2014-08-19 12:30 ` Andreas Färber
0 siblings, 0 replies; 50+ messages in thread
From: Andreas Färber @ 2014-08-19 12:30 UTC (permalink / raw)
To: Marek Szyprowski, Inki Dae
Cc: Joerg Roedel, iommu, linux-samsung-soc, linux-arm-kernel,
linux-kernel, linaro-mm-sig, Arnd Bergmann, Shaik Ameer Basha,
Cho KyongHo, Thierry Reding, Olof Johansson, Laurent Pinchart,
Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Kukjin Kim,
Sylwester Nawrocki, Tomasz Figa, Kyungmin Park, Ajay Kumar
Hi,
Am 19.08.2014 14:01, schrieb Marek Szyprowski:
> On 2014-08-19 13:39, Andreas Färber wrote:
>> I'm working on 5250 based Spring Chromebook and noticed that v3.17-rc1
>> got some more iommu support. With the new CONFIG_DRM_EXYNOS_IOMMU=y my
>> machine stops booting. So I'm wondering, is any of this a fix for 3.17,
>> or is all of this "unrelated" -next material?
>
> This is probably a side effect of patch
> 3170447c1f264d51b8d1f3898bf2588588a64fdc
> ("iommu/exynos: Select ARM_DMA_USE_IOMMU"). It added selection of
> ARM_DMA_USE_IOMMU
> symbol, on which IOMMU support in Exynos DRM subsystem depends. However
> selecting
> this symbol is all that this patch does, without providing any code code
> which
> implements real support for ARM DMA IOMMU integration, which is needed
> by Exynos
> DRM driver. Please disable CONFIG_DRM_EXYNOS_IOMMU in kernel .config and
> your
> system should be bootable again.
Yes, that's what my report implied. :)
I'm bringing this up for -rc2 though: It sounds as if that option should
remain unavailable until the required code is in? Thanks.
>> Also, are you or someone
>> working on the respective DT changes for Exynos5?
>
> I can prepare DT changes for Exynos5 as well, but first I wanted to
> clarify if
> everyone involved in generic IOMMU bindings and Exynos IOMMU driver
> agrees on my
> proposal.
Sure. I'm updating my old spring-bridge.v6 branch [1] to 3.17-rc1 [2],
which involves three drm bridge patches rebased onto the new drm panel
prepare/unprepare infrastructure plus two LVDS DT patches in addition to
the IOMMU patches. That old branch included DT changes for 5250 in "ARM:
dts: add System MMU nodes of Exynos SoCs", but that'll probably need
updating for the new bindings.
Regards,
Andreas
[1] https://github.com/afaerber/linux/commits/spring-bridge.v6
[2] https://github.com/afaerber/linux/commits/spring-next
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
^ permalink raw reply [flat|nested] 50+ messages in thread