[PATCH 1/3] phy: exynos-mipi-video: Drop support for direct access to PMU
From: Sylwester Nawrocki <s.nawro...@samsung.com> There is no need to support access to the PMU through memory ioresource as now access through PMU regmap should only be used. Signed-off-by: Sylwester Nawrocki <s.nawro...@samsung.com> Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/phy/phy-exynos-mipi-video.c | 57 + 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 2a54cab..d4f5d8e 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -22,9 +22,6 @@ #include #include -/* MIPI_PHYn_CONTROL reg. offset (for base address from ioremap): n = 0..1 */ -#define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) - enum exynos_mipi_phy_id { EXYNOS_MIPI_PHY_ID_CSIS0, EXYNOS_MIPI_PHY_ID_DSIM0, @@ -50,7 +47,6 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state, enum exynos_mipi_phy_id id, unsigned int on) { const unsigned int offset = EXYNOS4_MIPI_PHY_CONTROL(id / 2); - void __iomem *addr; u32 val, reset; if (is_mipi_dsim_phy_id(id)) @@ -60,35 +56,17 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state, spin_lock(>slock); - if (!IS_ERR(state->regmap)) { - regmap_read(state->regmap, offset, ); - if (on) - val |= reset; - else - val &= ~reset; - regmap_write(state->regmap, offset, val); - if (on) - val |= EXYNOS4_MIPI_PHY_ENABLE; - else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) - val &= ~EXYNOS4_MIPI_PHY_ENABLE; - regmap_write(state->regmap, offset, val); - } else { - addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); - - val = readl(addr); - if (on) - val |= reset; - else - val &= ~reset; - writel(val, addr); - /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set */ - if (on) - val |= EXYNOS4_MIPI_PHY_ENABLE; - else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) - val &= ~EXYNOS4_MIPI_PHY_ENABLE; - - writel(val, addr); - } + regmap_read(state->regmap, offset, ); + if (on) + val |= reset; + else + val &= ~reset; + regmap_write(state->regmap, offset, val); + if (on) + val |= EXYNOS4_MIPI_PHY_ENABLE; + else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) + val &= ~EXYNOS4_MIPI_PHY_ENABLE; + regmap_write(state->regmap, offset, val); spin_unlock(>slock); return 0; @@ -142,17 +120,8 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) return -ENOMEM; state->regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); - if (IS_ERR(state->regmap)) { - struct resource *res; - - dev_info(dev, "regmap lookup failed: %ld\n", -PTR_ERR(state->regmap)); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - state->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(state->regs)) - return PTR_ERR(state->regs); - } + if (IS_ERR(state->regmap)) + return PTR_ERR(state->regmap); dev_set_drvdata(dev, state); spin_lock_init(>slock); -- 1.9.2
[PATCH 0/3] phy: exynos-mipi-video: add support for Exynos 54xx SoCs
Hello, This patch series adds upport for MIPI Video DPHY found in Exynos 5420/5422/5800 and 5433 SoCs. Best regards Marek Szyprowski Samsung R Institute Poland Patch summary: Marek Szyprowski (2): phy: exynos-mipi-video: rewrite handling of phy registers phy: exynos-mipi-video: add support for Exynos 5420 and 5433 SoCs Sylwester Nawrocki (1): phy: exynos-mipi-video: Drop support for direct access to PMU .../devicetree/bindings/phy/samsung-phy.txt| 18 +- drivers/phy/phy-exynos-mipi-video.c| 322 - include/linux/mfd/syscon/exynos5-pmu.h | 3 + 3 files changed, 276 insertions(+), 67 deletions(-) -- 1.9.2
[PATCH 3/3] phy: exynos-mipi-video: Add support for Exynos 5420 and 5433 SoCs
This patch adds support for MIPI DPHYs found in Exynos5420-compatible (5420, 5422 and 5800) and Exynos5433 SoCs. Those SoCs differs from earlier by different offset of MIPI DPHY registers in PMU controllers (Exynos 5420-compatible case) or by moving MIPI DPHY reset registers to separate system register controllers (Exynos 5433 case). In both case also additional 5th PHY (MIPI CSIS 2) has been added. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- .../devicetree/bindings/phy/samsung-phy.txt| 18 ++- drivers/phy/phy-exynos-mipi-video.c| 129 - include/linux/mfd/syscon/exynos5-pmu.h | 3 + 3 files changed, 147 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 0289d3b..9872ba8 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -2,9 +2,20 @@ Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY - Required properties: -- compatible : should be "samsung,s5pv210-mipi-video-phy"; +- compatible : should be one of the listed compatibles: + - "samsung,s5pv210-mipi-video-phy" + - "samsung,exynos5420-mipi-video-phy" + - "samsung,exynos5433-mipi-video-phy" - #phy-cells : from the generic phy bindings, must be 1; -- syscon - phandle to the PMU system controller; + +In case of s5pv210 and exynos5420 compatible PHYs: +- syscon - phandle to the PMU system controller + +In case of exynos5433 compatible PHY: + - samsung,pmu-syscon - phandle to the PMU system controller + - samsung,disp-sysreg - phandle to the DISP system registers controller + - samsung,cam0-sysreg - phandle to the CAM0 system registers controller + - samsung,cam1-sysreg - phandle to the CAM1 system registers controller For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in the PHY specifier identifies the PHY and its meaning is as follows: @@ -12,6 +23,9 @@ the PHY specifier identifies the PHY and its meaning is as follows: 1 - MIPI DSIM 0, 2 - MIPI CSIS 1, 3 - MIPI DSIM 1. +"samsung,exynos5420-mipi-video-phy" and "samsung,exynos5433-mipi-video-phy" +supports additional fifth PHY: + 4 - MIPI CSIS 2. Samsung EXYNOS SoC series Display Port PHY - diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 7ba0936..3e6656c 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -1,7 +1,7 @@ /* * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Copyright (C) 2013,2016 Samsung Electronics Co., Ltd. * Author: Sylwester Nawrocki <s.nawro...@samsung.com> * * This program is free software; you can redistribute it and/or modify @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -28,11 +29,15 @@ enum exynos_mipi_phy_id { EXYNOS_MIPI_PHY_ID_DSIM0, EXYNOS_MIPI_PHY_ID_CSIS1, EXYNOS_MIPI_PHY_ID_DSIM1, + EXYNOS_MIPI_PHY_ID_CSIS2, EXYNOS_MIPI_PHYS_NUM }; enum exynos_mipi_phy_regmap_id { EXYNOS_MIPI_REGMAP_PMU, + EXYNOS_MIPI_REGMAP_DISP, + EXYNOS_MIPI_REGMAP_CAM0, + EXYNOS_MIPI_REGMAP_CAM1, EXYNOS_MIPI_REGMAPS_NUM }; @@ -97,6 +102,122 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = { }, }; +static const struct mipi_phy_device_desc exynos5420_mipi_phy = { + .num_regmaps = 1, + .regmap_names = {"syscon"}, + .num_phys = 5, + .phys = { + { + /* EXYNOS_MIPI_PHY_ID_CSIS0 */ + .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0, + .enable_val = EXYNOS5_PHY_ENABLE, + .enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL, + .enable_map = EXYNOS_MIPI_REGMAP_PMU, + .resetn_val = EXYNOS5_MIPI_PHY_S_RESETN, + .resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL, + .resetn_map = EXYNOS_MIPI_REGMAP_PMU, + }, { + /* EXYNOS_MIPI_PHY_ID_DSIM0 */ + .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0, + .enable_val = EXYNOS5_PHY_ENABLE, + .enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL, + .enable_map = EXYNOS_MIPI_REGMAP_PMU, + .resetn_val = EXYNOS5_MIPI_PHY_M_RESETN, + .resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL, + .resetn_map = EXYNOS_MIPI_REGMAP_PMU, + }, { + /* EXYNOS_MIPI_PHY_ID_CSIS1 */ +
[PATCH 2/3] phy: exynos-mipi-video: Rewrite handling of phy registers
Controlling Exynos MIPI DPHY is done by handling 2 registers: one for phy reset and one for enabling it. This patch moves definitions of those 2 registers to speparate exynos_mipi_phy_desc structure, which can be defined separately for each PHY for each supported hardware variant. This code rewrite is needed to add support for newer Exynos SoCs, which have MIPI PHY related registers at different offsets or even different register regions. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/phy/phy-exynos-mipi-video.c | 166 1 file changed, 131 insertions(+), 35 deletions(-) diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index d4f5d8e..7ba0936 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -16,13 +16,14 @@ #include #include #include +#include #include -#include #include #include #include enum exynos_mipi_phy_id { + EXYNOS_MIPI_PHY_ID_NONE = -1, EXYNOS_MIPI_PHY_ID_CSIS0, EXYNOS_MIPI_PHY_ID_DSIM0, EXYNOS_MIPI_PHY_ID_CSIS1, @@ -30,57 +31,138 @@ enum exynos_mipi_phy_id { EXYNOS_MIPI_PHYS_NUM }; -#define is_mipi_dsim_phy_id(id) \ - ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1) +enum exynos_mipi_phy_regmap_id { + EXYNOS_MIPI_REGMAP_PMU, + EXYNOS_MIPI_REGMAPS_NUM +}; + +struct mipi_phy_device_desc +{ + int num_phys; + int num_regmaps; + const char *regmap_names[EXYNOS_MIPI_REGMAPS_NUM]; + struct exynos_mipi_phy_desc { + enum exynos_mipi_phy_id coupled_phy_id; + u32 enable_val; + unsigned int enable_reg; + enum exynos_mipi_phy_regmap_id enable_map; + u32 resetn_val; + unsigned int resetn_reg; + enum exynos_mipi_phy_regmap_id resetn_map; + } phys[EXYNOS_MIPI_PHYS_NUM]; +}; + +static const struct mipi_phy_device_desc s5pv210_mipi_phy = { + .num_regmaps = 1, + .regmap_names = {"syscon"}, + .num_phys = 4, + .phys = { + { + /* EXYNOS_MIPI_PHY_ID_CSIS0 */ + .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0, + .enable_val = EXYNOS4_MIPI_PHY_ENABLE, + .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0), + .enable_map = EXYNOS_MIPI_REGMAP_PMU, + .resetn_val = EXYNOS4_MIPI_PHY_SRESETN, + .resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(0), + .resetn_map = EXYNOS_MIPI_REGMAP_PMU, + }, { + /* EXYNOS_MIPI_PHY_ID_DSIM0 */ + .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0, + .enable_val = EXYNOS4_MIPI_PHY_ENABLE, + .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0), + .enable_map = EXYNOS_MIPI_REGMAP_PMU, + .resetn_val = EXYNOS4_MIPI_PHY_MRESETN, + .resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(0), + .resetn_map = EXYNOS_MIPI_REGMAP_PMU, + }, { + /* EXYNOS_MIPI_PHY_ID_CSIS1 */ + .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1, + .enable_val = EXYNOS4_MIPI_PHY_ENABLE, + .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1), + .enable_map = EXYNOS_MIPI_REGMAP_PMU, + .resetn_val = EXYNOS4_MIPI_PHY_SRESETN, + .resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(1), + .resetn_map = EXYNOS_MIPI_REGMAP_PMU, + }, { + /* EXYNOS_MIPI_PHY_ID_DSIM1 */ + .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1, + .enable_val = EXYNOS4_MIPI_PHY_ENABLE, + .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1), + .enable_map = EXYNOS_MIPI_REGMAP_PMU, + .resetn_val = EXYNOS4_MIPI_PHY_MRESETN, + .resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(1), + .resetn_map = EXYNOS_MIPI_REGMAP_PMU, + }, + }, +}; + struct exynos_mipi_video_phy { + struct regmap *regmaps[EXYNOS_MIPI_REGMAPS_NUM]; + int num_phys; struct video_phy_desc { struct phy *phy; unsigned int index; + const struct exynos_mipi_phy_desc *data; } phys[EXYNOS_MIPI_PHYS_NUM]; spinlock_t slock; - void __iomem *regs; - struct regmap *regmap; }; -static int __set_phy_state(struct exynos_mipi_video_phy *state, - enum exynos_mipi_phy_id id, unsigned int on) +static inline int __is_running(const struct exynos_mipi_phy_desc *data, + struct exynos_mipi_video_phy *state) { - const uns
Re: [PATCH] serial: samsung: Reorder the sequence of clock control when call s3c24xx_serial_set_termios()
Dear Chanwoo, On 2016-03-25 01:10, Chanwoo Choi wrote: Hi Robert, I send following patch to fix the broken serial log of Exynos SoC. As I knew, you also knew this issue. If possible, could you review or test this patch? Robert no longer works for Samsung, so I'm afraid that he won't be able to test this patch. Best Regards, Chanwoo Choi On 2016년 03월 14일 09:41, Chanwoo Choi wrote: This patch fixes the broken serial log when changing the clock source of uart device. Before disabling the original clock source, this patch enables the new clock source to protect the clock off state for a split second. Signed-off-by: Chanwoo Choi <cw00.c...@samsung.com> --- drivers/tty/serial/samsung.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index d72cd736bdc6..80d59dbfebba 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1265,13 +1265,13 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, if (ourport->baudclk != clk) { s3c24xx_serial_setsource(port, clk_sel); + clk_prepare_enable(clk); + IMHO clk_prepare_enable() should be moved before s3c24xx_serial_setsource() to be really sure that there will be no period of hw operating with disabled baud clock. Could you check if it works for you? if (!IS_ERR(ourport->baudclk)) { clk_disable_unprepare(ourport->baudclk); ourport->baudclk = ERR_PTR(-EINVAL); } - clk_prepare_enable(clk); - ourport->baudclk = clk; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; } Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
driver(struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; int ret = -ENODEV; - if (!driver || !driver->bind || !driver->setup) - return -EINVAL; - mutex_lock(_lock); if (driver->udc_name) { list_for_each_entry(udc, _list, list) { @@ -567,16 +590,47 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) } } - list_add_tail(>pending, _driver_pending_list); +// list_add_tail(>pending, _driver_pending_list); FIXME pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n", driver->function); + mutex_unlock(_lock); - return 0; + return ret; found: ret = udc_bind_to_driver(udc, driver); mutex_unlock(_lock); return ret; } + +#define USB_GADGET_BIND_RETRIES5 +#define USB_GADGET_BIND_TIMEOUT(3 * HZ) +static void usb_gadget_work(struct work_struct *work) +{ + struct usb_gadget_driver *driver = container_of(work, + struct usb_gadget_driver, + work.work); + int res; + + if (driver->retries++ > USB_GADGET_BIND_RETRIES) { + pr_err("couldn't find an available UDC\n"); + return; + } + + res = __usb_gadget_probe_driver(driver); + if (res == -ENODEV) + schedule_delayed_work(>work, USB_GADGET_BIND_TIMEOUT); +} + +int usb_gadget_probe_driver(struct usb_gadget_driver *driver) +{ + if (!driver || !driver->bind || !driver->setup) + return -EINVAL; + + INIT_DELAYED_WORK(>work, usb_gadget_work); + schedule_delayed_work(>work, 0); + + return 0; +} EXPORT_SYMBOL_GPL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) @@ -587,6 +641,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!driver || !driver->unbind) return -EINVAL; + cancel_delayed_work(>work); + mutex_lock(_lock); list_for_each_entry(udc, _list, list) if (udc->driver == driver) { @@ -747,7 +803,7 @@ static int __init usb_udc_init(void) udc_class->dev_uevent = usb_udc_uevent; return 0; } -subsys_initcall(usb_udc_init); +late_initcall_sync(usb_udc_init); static void __exit usb_udc_exit(void) { diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index d82d006..adb1e68 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1014,6 +1014,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) * @resume: Invoked on USB resume. May be called in_interrupt. * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers *and should be called in_interrupt. + * @work: Gadget work used to bind to the USB controller. + * @retries: Gadget retries to bind to the USB controller. * @driver: Driver model state for this driver. * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL, *this driver will be bound to any available UDC. @@ -1075,6 +1077,8 @@ struct usb_gadget_driver { void(*suspend)(struct usb_gadget *); void(*resume)(struct usb_gadget *); void(*reset)(struct usb_gadget *); + struct delayed_work work; + int retries; /* FIXME support safe rmmod */ struct device_driverdriver; Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 1/2] [media] vb2-memops: Fix over allocation of frame vectors
Hello, On 2016-03-03 20:12, Ricardo Ribalda Delgado wrote: On page unaligned frames, create_framevec forces get_vaddr_frames to allocate an extra page at the end of the buffer. Under some circumstances, this leads to -EINVAL on VIDIOC_QBUF. E.g: We have vm_a that vm_area that goes from 0x1000 to 0x3000. And a frame that goes from 0x1800 to 0x2800, i.e. 2 pages. frame_vector_create will be called with the following params: get_vaddr_frames(0x1800 , 2, write, 1, vec); get_vaddr will allocate the first page after checking that the memory 0x1800-0x27ff is valid, but it will not allocate the second page because the range 0x2800-0x37ff is out of the vm_a range. This results in create_framevec returning -EFAULT Error Trace: [ 9083.793015] video0: VIDIOC_QBUF: 00:00:00. index=1, type=vid-cap, flags=0x2002, field=any, sequence=0, memory=userptr, bytesused=0, offset/userptr=0x7ff2b023ca80, length=5765760 [ 9083.793028] timecode=00:00:00 type=0, flags=0x, frames=0, userbits=0x [ 9083.793117] video0: VIDIOC_QBUF: error -22: 00:00:00. index=2, type=vid-cap, flags=0x, field=any, sequence=0, memory=userptr, bytesused=0, offset/userptr=0x7ff2b07bc500, length=5765760 Fixes: 21fb0cb7ec65 ("[media] vb2: Provide helpers for mapping virtual addresses") Reported-by: Albert Antony <alb...@newtec.dk> Signed-off-by: Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> Acked-by: Marek Szyprowski <m.szyprow...@samsung.com> --- Maybe we should cc stable. This error has not pop-out yet because userptr is usually called with memory on the heap and malloc usually overallocate. This error has been a pain to trace :). Regards! drivers/media/v4l2-core/videobuf2-memops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c index dbec5923fcf0..e4e4976c6849 100644 --- a/drivers/media/v4l2-core/videobuf2-memops.c +++ b/drivers/media/v4l2-core/videobuf2-memops.c @@ -49,7 +49,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start, vec = frame_vector_create(nr); if (!vec) return ERR_PTR(-ENOMEM); - ret = get_vaddr_frames(start, nr, write, 1, vec); + ret = get_vaddr_frames(start & PAGE_MASK, nr, write, 1, vec); if (ret < 0) goto out_destroy; /* We accept only complete set of PFNs */ Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [patch] iommu/exynos: checking for IS_ERR() instead of NULL
Hello, On 2016-03-02 11:10, Dan Carpenter wrote: of_platform_device_create() returns NULL on error, it never returns error pointers. Fixes: 8ed55c812fa8 ('iommu/exynos: Init from dt-specific callback instead of initcall') Signed-off-by: Dan Carpenter <dan.carpen...@oracle.com> Acked-by: Marek Szyprowski <m.szyprow...@samsung.com> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index b066504..cb57bda 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1347,8 +1347,8 @@ static int __init exynos_iommu_of_setup(struct device_node *np) exynos_iommu_init(); pdev = of_platform_device_create(np, NULL, platform_bus_type.dev_root); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); + if (!pdev) + return -ENOMEM; /* * use the first registered sysmmu device for performing Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2] serial: samsung: Reorder the sequence of clock control when call s3c24xx_serial_set_termios()
Hello, On 2016-03-28 01:48, Chanwoo Choi wrote: This patch fixes the broken serial log when changing the clock source of uart device. Before disabling the original clock source, this patch enables the new clock source to protect the clock off state for a split second. Signed-off-by: Chanwoo Choi <cw00.c...@samsung.com> Reviewed-by: Marek Szyprowski <m.szyprow...@samsung.com> --- Changes from v1: (https://lkml.org/lkml/2016/3/13/183) - Enable the clock before changing the source by s3c24xx_serial_setsource() - Rebase it on Linux v4.6-rc1 drivers/tty/serial/samsung.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index ac7f8df54406..99bb23161dd6 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1271,6 +1271,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, /* check to see if we need to change clock source */ if (ourport->baudclk != clk) { + clk_prepare_enable(clk); + s3c24xx_serial_setsource(port, clk_sel); if (!IS_ERR(ourport->baudclk)) { @@ -1278,8 +1280,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ourport->baudclk = ERR_PTR(-EINVAL); } - clk_prepare_enable(clk); - ourport->baudclk = clk; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; } Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v7 1/2] drivers: base: add support for registering notifier about deferred probe
Hello, On 2016-04-13 16:12, Greg Kroah-Hartman wrote: On Wed, Apr 13, 2016 at 11:35:59AM +0200, Marek Szyprowski wrote: This patch adds code which allow other subsystems get a notification when deferred probe has been triggered. This way one can retry some actions, which earlier failed with -EPROBE_DEFER error code. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Why would some other subsystem want/care about this? You aren't telling them what device was deferred, and you don't need to as the bus itself already knows this information as it did the deferring! confused, This notifier is just to let others that the deferred probe has happened and it is a good time to retry operation, which earlier failed due to missing resources (i.e. power domains, clocks). Such case is with registering AMBA device (not the driver!). During AMBA device registration, bus code has to read some device's registers to get its device CID/PID. To do this, device's clocks and power domain has to be turned on. Those however might not be available that time. With this notifier, AMBA bus code is able to retry device registration, which earlier failed due to missing clocks or power domain. This CID/PID reading has to be done during device registration time because of the already deployed userspace ABI. CID/PID values are reported to userspace, which might rely on them to load proper driver modules. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v8] drivers: amba: properly handle devices with power domains
Hello, On 2016-04-25 11:19, Ulf Hansson wrote: On 15 April 2016 at 11:13, Marek Szyprowski <m.szyprow...@samsung.com> wrote: To read pid/cid registers, the probed device need to be properly turned on. When it is inside a power domain, the bus code should ensure that the given power domain is enabled before trying to access device's registers. However in some cases power domain (or clocks) might not be yet available. Returning -EPROBE_DEFER is not a solution in such case, because callers don't handle this special error code. Instead such devices are added to the special list and their registration is retried from periodic worker until all resources are available. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- Changelog: v8: - replaced notifier with periodic workqueue on Greg request v7: https://lkml.org/lkml/2016/4/13/201 - replaced late_initcall approach with a notifier registered to device core v6: https://lkml.org/lkml/2016/4/12/414 - got back to v1-style approach on Russell King request to avoid ABI break - use list for storing deferred devices and retry their registration from late_initcall v5: https://lkml.org/lkml/2016/2/10/179 - added 2 more patches to avoid regression with existing drivers (nvdimm and sa), for more information, see https://lkml.org/lkml/2015/12/17/390 - changed thread name to "AMBA: add complete support for power domains" v4: https://lkml.org/lkml/2015/12/2/52 - fixed more issues pointed by Ulf Hansson and Russell King v3: https://lkml.org/lkml/2015/12/1/334 - fixed issues pointed by Ulf Hansson - dropped patch for exynos4210 dts, because it already got queued for merging v2: https://lkml.org/lkml/2015/11/26/229 - added 2 patches from 'On-demand device probing' thread (https://lkml.org/lkml/2015/9/29/189), which move PID/CIR reading from amba_device_add() to amba_match() - moved dev_pm_domain_attach() to amba_match(), which is allowed to return -EPROBE_DEFER v1: http://www.spinics.net/lists/arm-kernel/msg463185.html - initial version --- drivers/amba/bus.c | 100 +++-- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index f0099360039e..a5b5c87e2114 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -336,16 +336,7 @@ static void amba_device_release(struct device *dev) kfree(d); } -/** - * amba_device_add - add a previously allocated AMBA device structure - * @dev: AMBA device allocated by amba_device_alloc - * @parent: resource parent for this devices resources - * - * Claim the resource, and read the device cell ID if not already - * initialized. Register the AMBA device with the Linux device - * manager. - */ -int amba_device_add(struct amba_device *dev, struct resource *parent) +static int amba_device_try_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; @@ -373,6 +364,12 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) goto err_release; } + ret = dev_pm_domain_attach(>dev, true); + if (ret == -EPROBE_DEFER) { + iounmap(tmp); + goto err_release; + } + ret = amba_get_enable_pclk(dev); if (ret == 0) { u32 pid, cid; @@ -398,6 +395,7 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) } iounmap(tmp); + dev_pm_domain_detach(>dev, true); if (ret) goto err_release; @@ -421,6 +419,88 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) err_out: return ret; } + +/* + * Registration of AMBA device require reading its pid and cid registers. + * To do this, the device must be turned on (if it is a part of power domain) + * and have clocks enabled. However in some cases those resources might not be + * yet available. Returning EPROBE_DEFER is not a solution in such case, + * because callers don't handle this special error code. Instead such devices + * are added to the special list and their registration is retried from + * periodic worker, until all resources are available and registration succeeds. + */ +struct deferred_device { + struct amba_device *dev; + struct resource *parent; + struct list_head node; +}; + +static LIST_HEAD(deferred_devices); +static DEFINE_MUTEX(deferred_devices_lock); + +static void amba_deferred_retry_func(struct work_struct *dummy); +static DECLARE_DELAYED_WORK(deferred_retry_work, amba_deferred_retry_func); + +#define DEFERRED_DEVICE_TIMEOUT (msecs_to_jiffies(5 * 1000)) + +static void amba_deferred_retry_func(struct work_struct *dummy) +{ + struct deferred_device *ddev, *tmp; + + mutex_lock(_devices_lock); + + list_for_each_entry_safe(ddev, tmp, _devices, node) { + int ret = amba_device_try
Re: [PATCH] of: iommu: make of_iommu_init() postcore_initcall_sync
Hello, On 2016-04-23 11:33, Kefeng Wang wrote: The of_iommu_init() is called multiple times by arch code, make it postcore_initcall_sync, then we can drop relevant calls fully. Note, the IOMMUs should have a chance to perform some basic initialisation before we start adding masters to them. So postcore_initcall_sync is good choice, it ensures of_iommu_init() called before of_platform_populate. Cc: Arnd Bergmann <a...@arndb.de> Cc: Marek Szyprowski <m.szyprow...@samsung.com> Cc: Rich Felker <dal...@libc.org> Cc: Rob Herring <robh...@kernel.org> Cc: Robin Murphy <robin.mur...@arm.com> Cc: Will Deacon <will.dea...@arm.com> Signed-off-by: Kefeng Wang <wangkefeng.w...@huawei.com> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com> Works fine on Samsung Exynos 4412 based Odroid U3 board. --- arch/arm/kernel/setup.c | 2 -- arch/arm64/kernel/setup.c | 2 -- arch/sh/boards/of-generic.c | 2 -- drivers/iommu/of_iommu.c| 5 - include/linux/of_iommu.h| 2 -- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 2c4bea3..18a29a0 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -902,7 +901,6 @@ static int __init customize_machine(void) * machine from the device tree, if no callback is provided, * otherwise we would always need an init_machine callback. */ - of_iommu_init(); if (machine_desc->init_machine) machine_desc->init_machine(); #ifdef CONFIG_OF diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 9dc6776..e20b64f 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -365,7 +364,6 @@ void __init setup_arch(char **cmdline_p) static int __init arm64_device_init(void) { if (of_have_populated_dt()) { - of_iommu_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } else if (acpi_disabled) { diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c index bf3a166..b4d4313 100644 --- a/arch/sh/boards/of-generic.c +++ b/arch/sh/boards/of-generic.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -185,7 +184,6 @@ static int __init sh_of_device_init(void) { pr_info("SH generic board support: populating platform devices\n"); if (of_have_populated_dt()) { - of_iommu_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } else { diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5fea665..04cc80f 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -174,7 +174,7 @@ err_put_node: return NULL; } -void __init of_iommu_init(void) +static int __init of_iommu_init(void) { struct device_node *np; const struct of_device_id *match, *matches = &__iommu_of_table; @@ -186,4 +186,7 @@ void __init of_iommu_init(void) pr_err("Failed to initialise IOMMU %s\n", of_node_full_name(np)); } + + return 0; } +postcore_initcall_sync(of_iommu_init); diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h index ffbe470..e2c2e71 100644 --- a/include/linux/of_iommu.h +++ b/include/linux/of_iommu.h @@ -11,7 +11,6 @@ extern int of_get_dma_window(struct device_node *dn, const char *prefix, int index, unsigned long *busno, dma_addr_t *addr, size_t *size); -extern void of_iommu_init(void); extern struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np); @@ -24,7 +23,6 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix, return -EINVAL; } -static inline void of_iommu_init(void) { } static inline struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 2/2] crypto: s5p-sss - Fix missed interrupts when working with 8 kB blocks
Hello, On 2016-04-22 14:15, Krzysztof Kozlowski wrote: The tcrypt testing module on Exynos5422-based Odroid XU3/4 board failed on testing 8 kB size blocks: $ sudo modprobe tcrypt sec=1 mode=500 testing speed of async ecb(aes) (ecb-aes-s5p) encryption test 0 (128 bit key, 16 byte blocks): 21971 operations in 1 seconds (351536 bytes) test 1 (128 bit key, 64 byte blocks): 21731 operations in 1 seconds (1390784 bytes) test 2 (128 bit key, 256 byte blocks): 21932 operations in 1 seconds (5614592 bytes) test 3 (128 bit key, 1024 byte blocks): 21685 operations in 1 seconds (22205440 bytes) test 4 (128 bit key, 8192 byte blocks): This was caused by a race issue of missed BRDMA_DONE ("Block cipher Receiving DMA") interrupt. Device starts processing the data in DMA mode immediately after setting length of DMA block: receiving (FCBRDMAL) or transmitting (FCBTDMAL). The driver sets these lengths from interrupt handler through s5p_set_dma_indata() function (or xxx_setdata()). However the interrupt handler was first dealing with receive buffer (dma-unmap old, dma-map new, set receive block length which starts the operation), then with transmit buffer and finally was clearing pending interrupts (FCINTPEND). Because of the time window between setting receive buffer length and clearing pending interrupts, the operation on receive buffer could end already and driver would miss new interrupt. User manual for Exynos5422 confirms in example code that setting DMA block lengths should be the last operation. The tcrypt hang could be also observed in following blocked-task dmesg: INFO: task modprobe:258 blocked for more than 120 seconds. Not tainted 4.6.0-rc4-next-20160419-5-g9eac8b7b7753-dirty #42 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. modprobeD c06b09d8 0 258256 0x [] (__schedule) from [] (schedule+0x40/0xac) [] (schedule) from [] (schedule_timeout+0x124/0x178) [] (schedule_timeout) from [] (wait_for_common+0xb8/0x144) [] (wait_for_common) from [] (test_acipher_speed+0x49c/0x740 [tcrypt]) [] (test_acipher_speed [tcrypt]) from [] (do_test+0x2240/0x30ec [tcrypt]) [] (do_test [tcrypt]) from [] (tcrypt_mod_init+0x48/0xa4 [tcrypt]) [] (tcrypt_mod_init [tcrypt]) from [] (do_one_initcall+0x3c/0x16c) [] (do_one_initcall) from [] (do_init_module+0x5c/0x1ac) [] (do_init_module) from [] (load_module+0x1a30/0x1d08) [] (load_module) from [] (SyS_finit_module+0x8c/0x98) [] (SyS_finit_module) from [] (ret_fast_syscall+0x0/0x3c) Fixes: a49e490c7a8a ("crypto: s5p-sss - add S5PV210 advanced crypto engine support") Cc: <sta...@vger.kernel.org> Signed-off-by: Krzysztof Kozlowski <k.kozlow...@samsung.com> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com> This patch solved similar hang issue on Exynos4210 based Universal_C210 board. Now AES crypto module works fine. --- Issue was easily reproduced on newer (faster?) SoCs, like Odroid XU3/XU4 (Exynos5422). Still it was kind of time-related (adding printks or kernel debug options sometimes "was fixing" the issue). On older like Odroid U3 with Exynos4412 this works fine... I am marking this cc-stable because invalid operation comes from the first version of the driver. --- drivers/crypto/s5p-sss.c | 53 +++- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index b96532078d0c..ac6d62b3be07 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -367,43 +367,55 @@ exit: return err; } -static void s5p_aes_tx(struct s5p_aes_dev *dev) +/* + * Returns true if new transmitting (output) data is ready and its + * address+length have to be written to device (by calling + * s5p_set_dma_outdata()). False otherwise. + */ +static bool s5p_aes_tx(struct s5p_aes_dev *dev) { int err = 0; + bool ret = false; s5p_unset_outdata(dev); if (!sg_is_last(dev->sg_dst)) { err = s5p_set_outdata(dev, sg_next(dev->sg_dst)); - if (err) { + if (err) s5p_aes_complete(dev, err); - return; - } - - s5p_set_dma_outdata(dev, dev->sg_dst); + else + ret = true; } else { s5p_aes_complete(dev, err); dev->busy = true; tasklet_schedule(>tasklet); } + + return ret; } -static void s5p_aes_rx(struct s5p_aes_dev *dev) +/* + * Returns true if new receiving (input) data is ready and its + * address+length have to be written to device (by calling + * s5p_set_dma_indata()). False otherwise. + */ +static bool s5p_aes_rx(struct s5p_aes_dev *dev) { int err; + bool ret = false; s5p_unset_indata(dev); if (!sg_is
Re: [PATCH 0/3] [media] s5p-mfc: Fixes for issues when module is removed
Hello, On 2016-05-03 22:27, Javier Martinez Canillas wrote: Hello, This patch series fixes some issues that I noticed when trying to remove the s5p-mfc driver when built as a module. Some of these issues will be fixed once Marek's patches to convert the custom memory region reservation code is replaced by a generic one that supports named memory region reservation [0]. But the fixes are trivial so we can fix the current code until his rework patch lands. For the whole series: Tested-by: Marek Szyprowski <m.szyprow...@samsung.com> Please queue it as fixes to v4.7-rcX. [0]: https://patchwork.linuxtv.org/patch/32287/ Best regards, Javier Javier Martinez Canillas (3): [media] s5p-mfc: Set device name for reserved memory region devs [media] s5p-mfc: Add release callback for memory region devs [media] s5p-mfc: Fix race between s5p_mfc_probe() and s5p_mfc_open() drivers/media/platform/s5p-mfc/s5p_mfc.c | 50 1 file changed, 32 insertions(+), 18 deletions(-) Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [RESEND PATCH] [media] s5p-mfc: don't close instance after free OUTPUT buffers
Hello, On 2016-05-07 00:11, Javier Martinez Canillas wrote: From: ayaka <ay...@soulik.info> User-space applications can use the VIDIOC_REQBUFS ioctl to determine if a memory mapped, user pointer or DMABUF based I/O is supported by the driver. So a set of VIDIOC_REQBUFS ioctl calls will be made with count 0 and then the real VIDIOC_REQBUFS call with count == n. But for count 0, the driver not only frees the buffer but also closes the MFC instance and s5p_mfc_ctx state is set to MFCINST_FREE. The VIDIOC_REQBUFS handler for the output device checks if the s5p_mfc_ctx state is set to MFCINST_INIT (which happens on an VIDIOC_S_FMT) and fails otherwise. So after a VIDIOC_REQBUFS(n), future VIDIOC_REQBUFS(n) calls will fails unless a VIDIOC_S_FMT ioctl calls happens before the reqbufs. But applications may first set the format and then attempt to determine the I/O methods supported by the driver (for example Gstramer does it) so the state won't be set to MFCINST_INIT again and VIDIOC_REQBUFS will fail. To avoid this issue, only free the buffers on VIDIOC_REQBUFS(0) but don't close the MFC instance to allow future VIDIOC_REQBUFS(n) calls to succeed. Signed-off-by: ayaka <ay...@soulik.info> [javier: Rewrote changelog to explain the problem more detailed] Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com> --- Hello, This is a resend of a patch posted by Ayaka some time ago [0]. Without $SUBJECT, trying to decode a video using Gstramer fails on an Exynos5422 Odroid XU4 board with following error message: $ gst-launch-1.0 filesrc location=test.mov ! qtdemux ! h264parse ! v4l2video0dec ! videoconvert ! autovideosink Setting pipeline to PAUSED ... Pipeline is PREROLLING ... [ 3947.114756] vidioc_reqbufs:576: Only V4L2_MEMORY_MAP is supported [ 3947.114771] vidioc_reqbufs:576: Only V4L2_MEMORY_MAP is supported [ 3947.114903] reqbufs_output:484: Reqbufs called in an invalid state [ 3947.114913] reqbufs_output:510: Failed allocating buffers for OUTPUT queue ERROR: from element /GstPipeline:pipeline0/v4l2video0dec:v4l2video0dec0: Failed to allocate required memory. Additional debug info: gstv4l2videodec.c(575): gst_v4l2_video_dec_handle_frame (): /GstPipeline:pipeline0/v4l2video0dec:v4l2video0dec0: Buffer pool activation failed ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... Freeing pipeline ... [0]: https://patchwork.linuxtv.org/patch/32794/ Best regards, Javier drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index f2d6376ce618..8b9467de2d6a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -474,7 +474,6 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, ret = vb2_reqbufs(>vq_src, reqbufs); if (ret) goto out; - s5p_mfc_close_mfc_inst(dev, ctx); ctx->src_bufs_cnt = 0; ctx->output_state = QUEUE_FREE; } else if (ctx->output_state == QUEUE_FREE) { Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: Watchdog reset trigger for eMMC
Hi Anand On 2016-04-30 08:06, Anand Moon wrote: Hi All, Using microSD card when I try to write into /dev/watchdog device it triggers reboot of the board after timer expires. --- root@odroidxu4l:~# echo 3 > /dev/watchdog [ 1659.021844] watchdog: watchdog0: watchdog did not stop! root@odroidxu4l:~# root@odroidxu4l:~# root@odroidxu4l:~# root@odroidxu4l:~# root@odroidxu4l:~# U-Boot 2016.03-00665-g563d8d9-dirty (Apr 04 2016 - 22:27:07 +0930) for ODROID-XU 3 CPU: Exynos5422 @ 800 MHz Model: Odroid XU3 based on EXYNOS5422 Board: Odroid XU3 based on EXYNOS5422 Type: xu4 DRAM: 2 GiB --- But when I try this on eMMC it just freezes. I know we have to set and unset gpio pin (SD_0.RST) to trigger reset before reboot. --- root@odroidxu4e:~# echo 4 > /dev/watchdog [ 639.192617] [c3] watchdog watchdog0: watchdog did not stop! root@odroidxu4e:~# root@odroidxu4e:~# root@odroidxu4e:~# --- I would like to know what is way board reset after watchdog reset after timeout. In my opinion hw watchdog reset is non-functional on Odroid U3/XU3/XU4 boards due to hardware design (eMMC reset line triggered from software). I see no way to workaround this issue in the software. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [RFT PATCH 0/3] usb: misc: usb3503: Fix missing device when TFTP booting
me the .config you are using? Never mind. After some more testing I don't think it is hanging, instead it seems that the mmc isn't enabled/found and so it just sits waiting for the root partition to appear. That was fun. There are two problems that both caused the boot to end at the same place: first of all the root partition is now called mmcblk1p1 instead of mmcblk0p1 in 4.6, so it was just waiting for the root partition to appear. Nothing to do with your patch series, just unexpected. This is known "issue", it has been reported several times. This is caused by some changes in mmc core. The best workaround is to use PARTUUID instead of hardcoding root device path. The second is that enabling CONFIG_VIDEO_S5P_FIMC causes the boot to hang at that same place. I suspect there is a deadlock somewhere. I'm digging deeper into that but again, unrelated to your patch series. I've posted a fix a few days ago: https://patchwork.linuxtv.org/patch/34117/ A change to media device core causes deadlock on driver registration. Anyway, after disabling that config option I was finally able to test your patch series: Tested-by: Hans Verkuil <hans.verk...@cisco.com> Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [RFC PATCH 06/11] drivers: iommu: make of_xlate() interface DT agnostic
Hi Lorenzo, On 2016-04-19 13:30, Lorenzo Pieralisi wrote: Hi Marek, On Tue, Apr 19, 2016 at 10:28:02AM +0200, Marek Szyprowski wrote: Hello, On 2016-04-14 19:25, Lorenzo Pieralisi wrote: On systems booting with ACPI, the IOMMU drivers require the same kind of id mapping carried out with a DT tree through the of_xlate() API in order to map devices identifiers to IOMMU ones. On ACPI systems, since DT nodes are not present (ie struct device.of_node == NULL), to identify the device requiring the translation the struct device_node (and the structure used to pass translation information - struct of_phandle_args - that contains a struct device_node) cannot be used, so a generic translation structure to be used for IOMMU mapping should be defined, based on the firmware agnostic fwnode_handle type. This patch mechanically refactors/renames the of_xlate API to make it DT agnostic, by declaring a new type (struct iommu_fwspec), that allows the kernel to pass a device identifier (fwnode - which can represent either a DT node or an IOMMU FW node) and by changing the of_xlate signature so that it does not take anymore the DT specific of_phandle_args argument and replaces it with the DT agnostic iommu_fwspec one. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com> Cc: Matthias Brugger <matthias@gmail.com> Cc: Will Deacon <will.dea...@arm.com> Cc: Hanjun Guo <hanjun@linaro.org> Cc: Rob Herring <robh...@kernel.org> Cc: Krzysztof Kozlowski <k.kozlow...@samsung.com> Cc: Robin Murphy <robin.mur...@arm.com> Cc: Tomasz Nowicki <t...@semihalf.com> Cc: Joerg Roedel <j...@8bytes.org> Cc: Marek Szyprowski <m.szyprow...@samsung.com> I'm not sure if this is the right approach, although I have not enough knowledge on ACPI firmware. Do you plan to rewrite all subsystems to the new "fwspec" based interface? Right now of_xlate is rather common interface used by various subsystems. Maybe it will be much easier to Yes, that's a valid concern, when you say "it is rather common" though, it seems to me that the of_xlate footprint is still subsystem specific, so this patch should be self-contained anyway (granted, doing this conversion for a specific subsystem is questionable, I guess that what you are asking is, if you do it for IOMMU, why would not you do it for other subsystems ?). I was curious if you want to replace of_xlate() interface in other subsystems like clocks, power domains, regulators, etc. Each of_xlate interface is specific to particular subsystem, but they all more or less follows the same style, what makes it easier to understand the code. It is an RFC for this specific reason. just add acpi_xlate callback and plumb it to the generic code? Maybe later when similar code will be in other subsystems and drivers, it can be unified, having much more real use cases? Yes, that's a possibility, it means adding yet another hook into the IOMMU drivers, probably a simpler change than this one, I posted this code as and RFC to see which direction we want to take so further feedback is welcome we can then choose the best approach. Thanks, Lorenzo --- drivers/iommu/arm-smmu.c | 12 +++- drivers/iommu/exynos-iommu.c | 11 +++ drivers/iommu/mtk_iommu.c| 13 - drivers/iommu/of_iommu.c | 20 ++-- include/linux/iommu.h| 24 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 6c42770..84bcff7 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1440,18 +1440,20 @@ out_unlock: return ret; } -static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) +static int arm_smmu_fw_xlate(struct device *dev, struct iommu_fwspec *args) { struct arm_smmu_device *smmu; - struct platform_device *smmu_pdev; + struct platform_device *smmu_pdev = NULL; + + if (is_of_node(args->fwnode)) + smmu_pdev = of_find_device_by_node(to_of_node(args->fwnode)); - smmu_pdev = of_find_device_by_node(args->np); if (!smmu_pdev) return -ENODEV; smmu = platform_get_drvdata(smmu_pdev); - return arm_smmu_add_dev_streamid(smmu, dev, args->args[0]); + return arm_smmu_add_dev_streamid(smmu, dev, args->param[0]); } static struct iommu_ops arm_smmu_ops = { @@ -1468,7 +1470,7 @@ static struct iommu_ops arm_smmu_ops = { .device_group = arm_smmu_device_group, .domain_get_attr= arm_smmu_domain_get_attr, .domain_set_attr= arm_smmu_domain_set_attr, - .of_xlate = arm_smmu_of_xlate, + .fw_xlate = arm_smmu_fw_xlate, .pgsize_bitmap = -1UL, /* Restricted during device attach */ }; diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iomm
[PATCH v8] drivers: amba: properly handle devices with power domains
To read pid/cid registers, the probed device need to be properly turned on. When it is inside a power domain, the bus code should ensure that the given power domain is enabled before trying to access device's registers. However in some cases power domain (or clocks) might not be yet available. Returning -EPROBE_DEFER is not a solution in such case, because callers don't handle this special error code. Instead such devices are added to the special list and their registration is retried from periodic worker until all resources are available. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- Changelog: v8: - replaced notifier with periodic workqueue on Greg request v7: https://lkml.org/lkml/2016/4/13/201 - replaced late_initcall approach with a notifier registered to device core v6: https://lkml.org/lkml/2016/4/12/414 - got back to v1-style approach on Russell King request to avoid ABI break - use list for storing deferred devices and retry their registration from late_initcall v5: https://lkml.org/lkml/2016/2/10/179 - added 2 more patches to avoid regression with existing drivers (nvdimm and sa), for more information, see https://lkml.org/lkml/2015/12/17/390 - changed thread name to "AMBA: add complete support for power domains" v4: https://lkml.org/lkml/2015/12/2/52 - fixed more issues pointed by Ulf Hansson and Russell King v3: https://lkml.org/lkml/2015/12/1/334 - fixed issues pointed by Ulf Hansson - dropped patch for exynos4210 dts, because it already got queued for merging v2: https://lkml.org/lkml/2015/11/26/229 - added 2 patches from 'On-demand device probing' thread (https://lkml.org/lkml/2015/9/29/189), which move PID/CIR reading from amba_device_add() to amba_match() - moved dev_pm_domain_attach() to amba_match(), which is allowed to return -EPROBE_DEFER v1: http://www.spinics.net/lists/arm-kernel/msg463185.html - initial version --- drivers/amba/bus.c | 100 +++-- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index f0099360039e..a5b5c87e2114 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -336,16 +336,7 @@ static void amba_device_release(struct device *dev) kfree(d); } -/** - * amba_device_add - add a previously allocated AMBA device structure - * @dev: AMBA device allocated by amba_device_alloc - * @parent: resource parent for this devices resources - * - * Claim the resource, and read the device cell ID if not already - * initialized. Register the AMBA device with the Linux device - * manager. - */ -int amba_device_add(struct amba_device *dev, struct resource *parent) +static int amba_device_try_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; @@ -373,6 +364,12 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) goto err_release; } + ret = dev_pm_domain_attach(>dev, true); + if (ret == -EPROBE_DEFER) { + iounmap(tmp); + goto err_release; + } + ret = amba_get_enable_pclk(dev); if (ret == 0) { u32 pid, cid; @@ -398,6 +395,7 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) } iounmap(tmp); + dev_pm_domain_detach(>dev, true); if (ret) goto err_release; @@ -421,6 +419,88 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) err_out: return ret; } + +/* + * Registration of AMBA device require reading its pid and cid registers. + * To do this, the device must be turned on (if it is a part of power domain) + * and have clocks enabled. However in some cases those resources might not be + * yet available. Returning EPROBE_DEFER is not a solution in such case, + * because callers don't handle this special error code. Instead such devices + * are added to the special list and their registration is retried from + * periodic worker, until all resources are available and registration succeeds. + */ +struct deferred_device { + struct amba_device *dev; + struct resource *parent; + struct list_head node; +}; + +static LIST_HEAD(deferred_devices); +static DEFINE_MUTEX(deferred_devices_lock); + +static void amba_deferred_retry_func(struct work_struct *dummy); +static DECLARE_DELAYED_WORK(deferred_retry_work, amba_deferred_retry_func); + +#define DEFERRED_DEVICE_TIMEOUT (msecs_to_jiffies(5 * 1000)) + +static void amba_deferred_retry_func(struct work_struct *dummy) +{ + struct deferred_device *ddev, *tmp; + + mutex_lock(_devices_lock); + + list_for_each_entry_safe(ddev, tmp, _devices, node) { + int ret = amba_device_try_add(ddev->dev, ddev->parent); + + if (ret == -EPROBE_DEFER) + continue; + + list_del_init(>no
Re: [RFC PATCH 06/11] drivers: iommu: make of_xlate() interface DT agnostic
Hello, On 2016-04-14 19:25, Lorenzo Pieralisi wrote: On systems booting with ACPI, the IOMMU drivers require the same kind of id mapping carried out with a DT tree through the of_xlate() API in order to map devices identifiers to IOMMU ones. On ACPI systems, since DT nodes are not present (ie struct device.of_node == NULL), to identify the device requiring the translation the struct device_node (and the structure used to pass translation information - struct of_phandle_args - that contains a struct device_node) cannot be used, so a generic translation structure to be used for IOMMU mapping should be defined, based on the firmware agnostic fwnode_handle type. This patch mechanically refactors/renames the of_xlate API to make it DT agnostic, by declaring a new type (struct iommu_fwspec), that allows the kernel to pass a device identifier (fwnode - which can represent either a DT node or an IOMMU FW node) and by changing the of_xlate signature so that it does not take anymore the DT specific of_phandle_args argument and replaces it with the DT agnostic iommu_fwspec one. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com> Cc: Matthias Brugger <matthias@gmail.com> Cc: Will Deacon <will.dea...@arm.com> Cc: Hanjun Guo <hanjun@linaro.org> Cc: Rob Herring <robh...@kernel.org> Cc: Krzysztof Kozlowski <k.kozlow...@samsung.com> Cc: Robin Murphy <robin.mur...@arm.com> Cc: Tomasz Nowicki <t...@semihalf.com> Cc: Joerg Roedel <j...@8bytes.org> Cc: Marek Szyprowski <m.szyprow...@samsung.com> I'm not sure if this is the right approach, although I have not enough knowledge on ACPI firmware. Do you plan to rewrite all subsystems to the new "fwspec" based interface? Right now of_xlate is rather common interface used by various subsystems. Maybe it will be much easier to just add acpi_xlate callback and plumb it to the generic code? Maybe later when similar code will be in other subsystems and drivers, it can be unified, having much more real use cases? --- drivers/iommu/arm-smmu.c | 12 +++- drivers/iommu/exynos-iommu.c | 11 +++ drivers/iommu/mtk_iommu.c| 13 - drivers/iommu/of_iommu.c | 20 ++-- include/linux/iommu.h| 24 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 6c42770..84bcff7 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1440,18 +1440,20 @@ out_unlock: return ret; } -static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) +static int arm_smmu_fw_xlate(struct device *dev, struct iommu_fwspec *args) { struct arm_smmu_device *smmu; - struct platform_device *smmu_pdev; + struct platform_device *smmu_pdev = NULL; + + if (is_of_node(args->fwnode)) + smmu_pdev = of_find_device_by_node(to_of_node(args->fwnode)); - smmu_pdev = of_find_device_by_node(args->np); if (!smmu_pdev) return -ENODEV; smmu = platform_get_drvdata(smmu_pdev); - return arm_smmu_add_dev_streamid(smmu, dev, args->args[0]); + return arm_smmu_add_dev_streamid(smmu, dev, args->param[0]); } static struct iommu_ops arm_smmu_ops = { @@ -1468,7 +1470,7 @@ static struct iommu_ops arm_smmu_ops = { .device_group = arm_smmu_device_group, .domain_get_attr= arm_smmu_domain_get_attr, .domain_set_attr= arm_smmu_domain_set_attr, - .of_xlate = arm_smmu_of_xlate, + .fw_xlate = arm_smmu_fw_xlate, .pgsize_bitmap = -1UL, /* Restricted during device attach */ }; diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 5ecc86c..84ff5bb 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1250,13 +1250,16 @@ static void exynos_iommu_remove_device(struct device *dev) iommu_group_remove_device(dev); } -static int exynos_iommu_of_xlate(struct device *dev, -struct of_phandle_args *spec) +static int exynos_iommu_fw_xlate(struct device *dev, +struct iommu_fwspec *args) { struct exynos_iommu_owner *owner = dev->archdata.iommu; - struct platform_device *sysmmu = of_find_device_by_node(spec->np); + struct platform_device *sysmmu = NULL; struct sysmmu_drvdata *data; + if (is_of_node(args->fwnode)) + sysmmu = of_find_device_by_node(to_of_node(args->fwnode)); + if (!sysmmu) return -ENODEV; @@ -1290,7 +1293,7 @@ static struct iommu_ops exynos_iommu_ops = { .add_device = exynos_iommu_add_device, .remove_device = exynos_iommu_remove_device, .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE, - .o
Re: [PATCH] i2c: exynos5: Fix possible ABBA deadlock by keeping I2C clock prepared
Hello, On 2016-04-16 00:04, Javier Martinez Canillas wrote: The exynos5 I2C controller driver always prepares and enables a clock before using it and then disables unprepares it when the clock is not used anymore. But this can cause a possible ABBA deadlock in some scenarios since a driver that uses regmap to access its I2C registers, will first grab the regmap lock and then the I2C xfer function will grab the prepare lock when preparing the I2C clock. But since the clock driver also uses regmap for I2C accesses, preparing a clock will first grab the prepare lock and then the regmap lock when using the regmap API. An example of this happens on the Exynos5422 Odroid XU board where a s2mps11 PMIC is used and both the s2mps11 regulators and clk drivers share the same I2C regmap. The possible deadlock is reported by the kernel lockdep: Possible unsafe locking scenario: CPU0CPU1 lock(sec_core:428:(regmap)->lock); lock(prepare_lock); lock(sec_core:428:(regmap)->lock); lock(prepare_lock); *** DEADLOCK *** Fix this by only preparing the clock on probe and {en,dis}able in the rest of the driver. This patch is similar to commit 34e81ad5f0b6 ("i2c: s3c2410: fix ABBA deadlock by keeping clock prepared") that fixes the same bug in other driver for an I2C controller found in Samsung SoCs. I'm sorry, but this is not the right approach imho. It is just a workaround applied to specific driver, it also duplicates incorrect clock usage pattern (there is really no point keeping clock prepared all the time). IMHO this ABBA deadlock should be really fixed in clocks core (probably by removing global prepare mutex and replacing it with per clock controller mutexes). Without a proper patch this issue will hit us again with other i2c controllers or other drivers as well. Reported-by: Anand Moon <linux.am...@gmail.com> Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com> --- drivers/i2c/busses/i2c-exynos5.c | 20 +++- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index b29c7500461a..602633747149 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -671,7 +671,9 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, return -EIO; } - clk_prepare_enable(i2c->clk); + ret = clk_enable(i2c->clk); + if (ret) + return ret; for (i = 0; i < num; i++, msgs++) { stop = (i == num - 1); @@ -695,7 +697,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, } out: - clk_disable_unprepare(i2c->clk); + clk_disable(i2c->clk); return ret; } @@ -799,6 +801,10 @@ static int exynos5_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c); + clk_disable(i2c->clk); + + return 0; + err_clk: clk_disable_unprepare(i2c->clk); return ret; @@ -810,6 +816,8 @@ static int exynos5_i2c_remove(struct platform_device *pdev) i2c_del_adapter(>adap); + clk_unprepare(i2c->clk); + return 0; } @@ -830,16 +838,18 @@ static int exynos5_i2c_resume_noirq(struct device *dev) struct exynos5_i2c *i2c = platform_get_drvdata(pdev); int ret = 0; - clk_prepare_enable(i2c->clk); + ret = clk_enable(i2c->clk); + if (ret) + return ret; ret = exynos5_hsi2c_clock_setup(i2c); if (ret) { - clk_disable_unprepare(i2c->clk); + clk_disable(i2c->clk); return ret; } exynos5_i2c_init(i2c); - clk_disable_unprepare(i2c->clk); + clk_disable(i2c->clk); i2c->suspended = 0; return 0; Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH] phy: exynos-mipi-video: simplify check for coupled phy status
There is no need to access regmap of coupled phy to check its state - such information is already in the phy device itself, so use it directly. This let us to avoid possible access to registers of the device in the disabled power domain if the coupled phy is already disabled. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Acked-by: Sylwester Nawrocki <s.nawro...@samsung.com> --- drivers/phy/phy-exynos-mipi-video.c | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 8b851f7..6bee04c 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -229,19 +229,6 @@ struct exynos_mipi_video_phy { spinlock_t slock; }; -static inline int __is_running(const struct exynos_mipi_phy_desc *data, - struct exynos_mipi_video_phy *state) -{ - u32 val; - int ret; - - ret = regmap_read(state->regmaps[data->resetn_map], data->resetn_reg, ); - if (ret) - return 0; - - return val & data->resetn_val; -} - static int __set_phy_state(const struct exynos_mipi_phy_desc *data, struct exynos_mipi_video_phy *state, unsigned int on) { @@ -251,7 +238,7 @@ static int __set_phy_state(const struct exynos_mipi_phy_desc *data, /* disable in PMU sysreg */ if (!on && data->coupled_phy_id >= 0 && - !__is_running(state->phys[data->coupled_phy_id].data, state)) { + state->phys[data->coupled_phy_id].phy->power_count == 0) { regmap_read(state->regmaps[data->enable_map], data->enable_reg, ); val &= ~data->enable_val; -- 1.9.1
Re: [PATCH v2 00/10] Exynos IOMMU: proper runtime PM support (use device dependencies)
Dear Tobias On 2016-07-18 13:00, Tobias Jakobi wrote: Marek Szyprowski wrote: On 2016-07-15 15:21, Tobias Jakobi wrote: Tobias Jakobi wrote: Hello Marek, I've tested the patchset on 4.7-rc7 and noticed that it breaks reboot on my ODROID-X2. Going to check where exactly things break. Sadly it's the last patch where everything comes together: "iommu/exynos: Add proper runtime pm support" I still have to check if forcing runpm status to 'on' makes a difference. I suspect that the aggressive clock gating might be the reason? Thanks for testing. I will check this issue. Could you send me your .config? This is the config I'm currently using: https://github.com/tobiasjakobi/odroid-environment/blob/master/sourcecode/system/vanilla-4.7-debug.conf Do you think checking this with no_console_suspend makes sense? no_console_suspend switch won't provide more information, but I managed to reproduce your issue. I'm really confused how enabling runtime pm can cause problems with usb/smsc95xx ethernet driver (that is the reason for failed reboot). Maybe it is somehow related to the global relations between devices and drivers and the fact that creating the runtime pm links change the order of operations. I will check this again when Rafael send updated patches. Here is the log I got (after waiting some time): # reboot Broadcast message from root@target (ttySAC1) (Mon Jul 18 13:33:38 2016): The system is going down for reboot NOW! INIT: Switching to runlevel: 6 INIT: Sending processes the TERM signal [info] Using makefile-style concurrent boot in runlevel 6. [ ok ] Stopping cgroup management proxy daemon: cgproxy[] Stopping internet superserver: inetd. [] Stopping cgroup management daemon: cgmanagermax77686-rtc max77686-rtc: RTC alarm IRQ: 119 [ ok ] Shutting down ALSA...done. random: nonblocking pool is initialized [info] Saving the system clock. [info] Hardware Clock updated to Mon Jul 18 13:33:40 UTC 2016. [ ok ] Asking all remaining processes to terminate...done. [ ok ] All processes ended within 1 seconds...done. [ ok ] Stopping rpcbind daemon [ ok ] Deconfiguring network interfaces...done. [ ok ] Unmounting temporary filesystems...done. [ ok ] Deactivating swap...done. EXT4-fs (mmcblk1p2): re-mounted. Opts: (null) [info] Will now restart. smsc95xx 1-2:1.0 eth0: Failed to read reg index 0x0114: -110 smsc95xx 1-2:1.0 eth0: Error reading MII_ACCESS smsc95xx 1-2:1.0 eth0: MII is busy in smsc95xx_mdio_read smsc95xx 1-2:1.0 eth0: Failed to read MII_BMSR INFO: task kworker/0:1:410 blocked for more than 120 seconds. Not tainted 4.7.0-rc7-debug+ #155 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. kworker/0:1 D c06850a8 0 410 2 0x Workqueue: events_freezable mmc_rescan Backtrace: [] (__schedule) from [] (schedule+0x44/0xb0) r10: r9:eebe1d88 r8:c0686234 r7: r6:0002 r5:7fff r4:7fff [] (schedule) from [] (schedule_timeout+0x154/0x1b0) [] (schedule_timeout) from [] (wait_for_common+0xe0/0x174) r8:c0686234 r7: r6:0002 r5:eebe1d8c r4:7fff [] (wait_for_common) from [] (wait_for_completion+0x18/0x1c) r10:0001 r9: r8: r7:eebe1d88 r6:eebe1d78 r5:ee26 r4:eebe1de4 [] (wait_for_completion) from [] (mmc_wait_for_req+0xc8/0x15c) [] (mmc_wait_for_req) from [] (mmc_wait_for_cmd+0x6c/0xa4) r8:eef73d00 r7:0003 r6:ee26 r5:c0a02448 r4:eebe1de4 r3: [] (mmc_wait_for_cmd) from [] (mmc_send_status+0x8c/0xb0) r7:eebe1eb0 r6:ee26 r5:ee26 r4: [] (mmc_send_status) from [] (mmc_alive+0x18/0x1c) r4:ee26 [] (mmc_alive) from [] (_mmc_detect_card_removed+0x40/0x90) [] (_mmc_detect_card_removed) from [] (mmc_detect+0x2c/0x78) r5:ee2602bc r4:ee26 [] (mmc_detect) from [] (mmc_rescan+0x1b0/0x324) r5:ee2602bc r4:ee260368 [] (mmc_rescan) from [] (process_one_work+0x194/0x414) r8:eef73d00 r7:eebe1eb0 r6:eef70280 r5:ee260368 r4:eea24080 r3:c04e94fc [] (process_one_work) from [] (worker_thread+0x34/0x4d4) r10:eef70280 r9:c0a02100 r8:0008 r7:eef70280 r6:eea24098 r5:eef702b4 r4:eea24080 [] (worker_thread) from [] (kthread+0xf8/0x11c) r10: r9: r8: r7:c013aad8 r6:eea24080 r5: r4:eea29d00 [] (kthread) from [] (ret_from_fork+0x14/0x24) r7: r6: r5:c0141d20 r4:eea29d00 2 locks held by kworker/0:1/410: #0: ("events_freezable"){.+.+.+}, at: [] process_one_work+0x128/0x414 #1: ((&(>detect)->work)){+.+.+.}, at: [] process_one_work+0x128/0x414 Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 00/10] Exynos IOMMU: proper runtime PM support (use device dependencies)
Hi Tobias On 2016-07-18 18:43, Tobias Jakobi wrote: Marek Szyprowski wrote: On 2016-07-18 13:00, Tobias Jakobi wrote: Marek Szyprowski wrote: On 2016-07-15 15:21, Tobias Jakobi wrote: Tobias Jakobi wrote: Hello Marek, I've tested the patchset on 4.7-rc7 and noticed that it breaks reboot on my ODROID-X2. Going to check where exactly things break. Sadly it's the last patch where everything comes together: "iommu/exynos: Add proper runtime pm support" I still have to check if forcing runpm status to 'on' makes a difference. I suspect that the aggressive clock gating might be the reason? Thanks for testing. I will check this issue. Could you send me your .config? This is the config I'm currently using: https://github.com/tobiasjakobi/odroid-environment/blob/master/sourcecode/system/vanilla-4.7-debug.conf Do you think checking this with no_console_suspend makes sense? no_console_suspend switch won't provide more information, but I managed to reproduce your issue. I'm really confused how enabling runtime pm can cause problems with usb/smsc95xx ethernet driver (that is the reason for failed reboot). Maybe it is somehow related to the global relations between devices and drivers and the fact that creating the runtime pm links change the order of operations. I will check this again when Rafael send updated patches. Here is the log I got (after waiting some time): thanks for looking into this! I'll try to reproduce this on my board. I have to admit that I didn't wait too long for the hung task message to appear. I wonder if this has something to do with regulator code cutting some supplies too early. Is this on a X2 or a U2/U3? I've reproduced it on U3. I'm not sure if we currently model the regulator setup correctly here (IIRC then buck8 is supplying the LAN/USB block on U2/U3). IMHO it is not really related to regulator operations, but the sequence of shutting down logical devices in the system. For some reasons when pm links are used, something changes the order of operations in system shutdown procedure, what causes smsc95xx to hang. I have no idea why, but I don't have time to investigate it further. I will wait for the next release of Rafael's pm links patches and then check everything again. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH] [media] vb2: map dmabuf for planes on driver queue instead of vidioc_qbuf
) { + ret = __buf_map_dmabuf(vb); + if (ret) + return ret; + } + /* sync buffers */ for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, prepare, vb->planes[plane].mem_priv); call_void_vb_qop(vb, buf_queue, vb); + + return 0; } static int __buf_prepare(struct vb2_buffer *vb, const void *pb) @@ -1438,8 +1452,11 @@ static int vb2_start_streaming(struct vb2_queue *q) * If any buffers were queued before streamon, * we can now pass them to driver for processing. */ - list_for_each_entry(vb, >queued_list, queued_entry) - __enqueue_in_driver(vb); + list_for_each_entry(vb, >queued_list, queued_entry) { + ret = __enqueue_in_driver(vb); + if (ret < 0) + return ret; + } /* Tell the driver to start streaming */ q->start_streaming_called = 1; @@ -1540,8 +1557,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) * If already streaming, give the buffer to driver for processing. * If not, the buffer will be given to driver on next streamon. */ - if (q->start_streaming_called) - __enqueue_in_driver(vb); + if (q->start_streaming_called) { + ret = __enqueue_in_driver(vb); + if (ret) + return ret; + } /* Fill buffer information for the userspace */ if (pb) Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 00/10] Exynos IOMMU: proper runtime PM support (use device dependencies)
Hi Tobias, On 2016-07-15 15:21, Tobias Jakobi wrote: Tobias Jakobi wrote: Hello Marek, I've tested the patchset on 4.7-rc7 and noticed that it breaks reboot on my ODROID-X2. Going to check where exactly things break. Sadly it's the last patch where everything comes together: "iommu/exynos: Add proper runtime pm support" I still have to check if forcing runpm status to 'on' makes a difference. I suspect that the aggressive clock gating might be the reason? Thanks for testing. I will check this issue. Could you send me your .config? Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH] phy: exynos-mipi-video: simplify check for coupled phy status
There is no need to access regmap of coupled phy to check its state - such information is already in the phy device itself, so use it directly. This let us to avoid possible access to registers of the device in the disabled power domain if the coupled phy is already disabled. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/phy/phy-exynos-mipi-video.c | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 8b851f7..e185234 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -229,19 +229,6 @@ struct exynos_mipi_video_phy { spinlock_t slock; }; -static inline int __is_running(const struct exynos_mipi_phy_desc *data, - struct exynos_mipi_video_phy *state) -{ - u32 val; - int ret; - - ret = regmap_read(state->regmaps[data->resetn_map], data->resetn_reg, ); - if (ret) - return 0; - - return val & data->resetn_val; -} - static int __set_phy_state(const struct exynos_mipi_phy_desc *data, struct exynos_mipi_video_phy *state, unsigned int on) { @@ -251,7 +238,7 @@ static int __set_phy_state(const struct exynos_mipi_phy_desc *data, /* disable in PMU sysreg */ if (!on && data->coupled_phy_id >= 0 && - !__is_running(state->phys[data->coupled_phy_id].data, state)) { + state->phys[data->coupled_id].phy->power_count == 0) { regmap_read(state->regmaps[data->enable_map], data->enable_reg, ); val &= ~data->enable_val; -- 1.9.1
Re: [PATCH v5 18/44] [media] dma-mapping: Use unsigned long for dma_attrs
Hello, On 2016-06-30 10:25, Krzysztof Kozlowski wrote: Split out subsystem specific changes for easier reviews. This will be squashed with main commit. Signed-off-by: Krzysztof Kozlowski <k.kozlow...@samsung.com> [for vb2-core] Reviewed-by: Marek Szyprowski <m.szyprow...@samsung.com> Please note that vb2 code is being modified now by Hans Verkuil, who is working on complete removal of allocator contexts from vb2 queue. You can check his patches here: https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=context3 [for bdisp] Acked-by: Fabien Dessenne <fabien.desse...@st.com> --- drivers/media/platform/sti/bdisp/bdisp-hw.c| 26 +++--- drivers/media/v4l2-core/videobuf2-dma-contig.c | 30 +++--- drivers/media/v4l2-core/videobuf2-dma-sg.c | 19 include/media/videobuf2-dma-contig.h | 7 ++ 4 files changed, 26 insertions(+), 56 deletions(-) diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c index 052c932ac942..d86ba40eec8d 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-hw.c +++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c @@ -125,14 +125,11 @@ int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp) */ void bdisp_hw_free_nodes(struct bdisp_ctx *ctx) { - if (ctx && ctx->node[0]) { - DEFINE_DMA_ATTRS(attrs); - - dma_set_attr(DMA_ATTR_WRITE_COMBINE, ); + if (ctx && ctx->node[0]) dma_free_attrs(ctx->bdisp_dev->dev, sizeof(struct bdisp_node) * MAX_NB_NODE, - ctx->node[0], ctx->node_paddr[0], ); - } + ctx->node[0], ctx->node_paddr[0], + DMA_ATTR_WRITE_COMBINE); } /** @@ -150,12 +147,10 @@ int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx) unsigned int i, node_size = sizeof(struct bdisp_node); void *base; dma_addr_t paddr; - DEFINE_DMA_ATTRS(attrs); /* Allocate all the nodes within a single memory page */ - dma_set_attr(DMA_ATTR_WRITE_COMBINE, ); base = dma_alloc_attrs(dev, node_size * MAX_NB_NODE, , - GFP_KERNEL | GFP_DMA, ); + GFP_KERNEL | GFP_DMA, DMA_ATTR_WRITE_COMBINE); if (!base) { dev_err(dev, "%s no mem\n", __func__); return -ENOMEM; @@ -188,13 +183,9 @@ void bdisp_hw_free_filters(struct device *dev) { int size = (BDISP_HF_NB * NB_H_FILTER) + (BDISP_VF_NB * NB_V_FILTER); - if (bdisp_h_filter[0].virt) { - DEFINE_DMA_ATTRS(attrs); - - dma_set_attr(DMA_ATTR_WRITE_COMBINE, ); + if (bdisp_h_filter[0].virt) dma_free_attrs(dev, size, bdisp_h_filter[0].virt, - bdisp_h_filter[0].paddr, ); - } + bdisp_h_filter[0].paddr, DMA_ATTR_WRITE_COMBINE); } /** @@ -211,12 +202,11 @@ int bdisp_hw_alloc_filters(struct device *dev) unsigned int i, size; void *base; dma_addr_t paddr; - DEFINE_DMA_ATTRS(attrs); /* Allocate all the filters within a single memory page */ size = (BDISP_HF_NB * NB_H_FILTER) + (BDISP_VF_NB * NB_V_FILTER); - dma_set_attr(DMA_ATTR_WRITE_COMBINE, ); - base = dma_alloc_attrs(dev, size, , GFP_KERNEL | GFP_DMA, ); + base = dma_alloc_attrs(dev, size, , GFP_KERNEL | GFP_DMA, + DMA_ATTR_WRITE_COMBINE); if (!base) return -ENOMEM; diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 5361197f3e57..8009a582326b 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -23,7 +23,7 @@ struct vb2_dc_conf { struct device *dev; - struct dma_attrsattrs; + unsigned long attrs; }; struct vb2_dc_buf { @@ -32,7 +32,7 @@ struct vb2_dc_buf { unsigned long size; void*cookie; dma_addr_t dma_addr; - struct dma_attrsattrs; + unsigned long attrs; enum dma_data_direction dma_dir; struct sg_table *dma_sgt; struct frame_vector *vec; @@ -135,7 +135,7 @@ static void vb2_dc_put(void *buf_priv) kfree(buf->sgt_base); } dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr, - >attrs); + buf->attrs); put_device(buf->dev); kfree(buf); } @@ -153,14 +153,14 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size,
Re: [PATCH] pinctrl: samsung: mark PM functions as __maybe_unused
Hi Arnd, On 2017-02-01 17:16, Arnd Bergmann wrote: The rework of the suspend/resume handling uses the wrong #ifdef check, leading to a build warning without CONFIG_PM_SLEEP: drivers/pinctrl/samsung/pinctrl-samsung.c:1142:12: error: 'samsung_pinctrl_resume' defined but not used [-Werror=unused-function] drivers/pinctrl/samsung/pinctrl-samsung.c:1092:12: error: 'samsung_pinctrl_suspend' defined but not used [-Werror=unused-function] Using a __maybe_unused annotation instead of the #ifdef is a simple way to avoid this problem class. Fixes: 2b24efa8e5c5 ("pinctrl: samsung: Replace syscore ops with standard platform device pm_ops") Signed-off-by: Arnd Bergmann <a...@arndb.de> Thanks for the fix! Acked-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/pinctrl/samsung/pinctrl-samsung.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index d79eadad6c5f..d601b5303e73 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1083,13 +1083,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM /** * samsung_pinctrl_suspend - save pinctrl state for suspend * * Save data for all banks handled by this device. */ -static int samsung_pinctrl_suspend(struct device *dev) +static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) { struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); int i; @@ -1139,7 +1138,7 @@ static int samsung_pinctrl_suspend(struct device *dev) * We don't bother doing anything complicated to avoid glitching lines since * we're called before pad retention is turned off. */ -static int samsung_pinctrl_resume(struct device *dev) +static int __maybe_unused samsung_pinctrl_resume(struct device *dev) { struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); int i; @@ -1183,7 +1182,6 @@ static int samsung_pinctrl_resume(struct device *dev) return 0; } -#endif static const struct of_device_id samsung_pinctrl_dt_match[] = { #ifdef CONFIG_PINCTRL_EXYNOS Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface
Hi Joerg, On 2017-02-06 17:10, Joerg Roedel wrote: From: Joerg Roedel <jroe...@suse.de> Register Exynos IOMMUs to the IOMMU core and make them visible in sysfs. This patch does not add the links between IOMMUs and translated devices yet. Cc: Marek Szyprowski <m.szyprow...@samsung.com> Cc: linux-arm-ker...@lists.infradead.org Cc: linux-samsung-...@vger.kernel.org Signed-off-by: Joerg Roedel <jroe...@suse.de> --- drivers/iommu/exynos-iommu.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 57ba0d3..90f0f52 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -276,6 +276,8 @@ struct sysmmu_drvdata { struct list_head owner_node;/* node for owner controllers list */ phys_addr_t pgtable;/* assigned page table structure */ unsigned int version; /* our version */ + + struct iommu_device iommu; /* IOMMU core handle */ }; static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom) @@ -556,6 +558,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) struct device *dev = >dev; struct sysmmu_drvdata *data; struct resource *res; + resource_size_t ioaddr; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -565,6 +568,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) data->sfrbase = devm_ioremap_resource(dev, res); if (IS_ERR(data->sfrbase)) return PTR_ERR(data->sfrbase); + ioaddr = res->start; irq = platform_get_irq(pdev, 0); if (irq <= 0) { @@ -611,6 +615,18 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) data->sysmmu = dev; spin_lock_init(>lock); + ret = iommu_device_sysfs_add(>iommu, >dev, NULL, +"sysmmu.%pa", ); Can we stick to the common name across the /sysfs and use dev_name(data->sysmmu) or even dev_name(dev) here? ret = iommu_device_sysfs_add(>iommu, >dev, NULL, dev_name(dev)); + if (ret) + return ret; + + data->iommu.ops= _iommu_ops; + data->iommu.fwnode = >of_node->fwnode; + + ret = iommu_device_register(>iommu); + if (ret) + return ret; + platform_set_drvdata(pdev, data); __sysmmu_get_version(data); Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v3 0/7] Pad retentions support for Exynos5433
Hi All, On 2017-02-08 12:46, Lee Jones wrote: On Mon, 30 Jan 2017, Marek Szyprowski wrote: This patchset is a first step to add support for all power domains on Exynos5433 SoCs. This patchset contains patches for Exynos pin control driver and Exynos LPASS MFD driver, which are needed to make the platform ready for adding power domains support. Patches in this patchset depends on each other. They are order in such a way to make the changes bisectable. Patch #2 has compile dependency on #1. Patch #3 has runtime dependency on commit fa59aa70907b2 ("soc: samsung: pmu: Add dummy support for Exynos5433 SoC", for-v4.11/drivers-soc-exynos-pmu-the-joy-never-ends branch). Patch #4 has runtime dependency on #3. Patch #5 has runtime dependency on commit 7547162ac3514 ("arm64: dts: exynos: Add clocks to Exynos5433 LPASS module, next/dt64 branch). This patchset also directly depends on the "Move pad retention control to Exynos pin controller driver" patchset: https://www.spinics.net/lists/arm-kernel/msg556074.html Patches have been generated on top of linux-next from 30th January 2017 with the above mentioned patchset applied. This is a part of a larger task, which goal is to add support for power domains on Exynos5433 SoCs / TM2 boards. First version of the all patches needed to get it working have been pushed to the following git repo: https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.10-next-tm2-pd Best regards Marek Szyprowski Samsung R Institute Poland Looks like I reviewed v2. If the patches haven't changed that much, please apply my Acks to this set instead. Anything that has changed, please leave them off and repost. MFD related patches were not changed between v2 and v3. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface
Hi Joerg, On 2017-02-08 14:57, Joerg Roedel wrote: On Tue, Feb 07, 2017 at 01:36:15PM +0100, Marek Szyprowski wrote: + ret = iommu_device_sysfs_add(>iommu, >dev, NULL, +"sysmmu.%pa", ); Can we stick to the common name across the /sysfs and use dev_name(data->sysmmu) or even dev_name(dev) here? ret = iommu_device_sysfs_add(>iommu, >dev, NULL, dev_name(dev)); That means that we have multiple 'struct device' with the same name, no? I think will lead to confusion when using dev_printk, as its not clear anymore which device is refered to in the message. Each sysmmu device has unique name, like every other platform device instantiated from device tree. Here is an example from the OdroidXU3 (Exynos5422 based): # ls -1 /sys/bus/platform/devices/ | grep sysmmu 10a6.sysmmu 10a7.sysmmu 1120.sysmmu 1121.sysmmu 11d4.sysmmu 11f1.sysmmu 11f2.sysmmu 1288.sysmmu 1289.sysmmu 128a.sysmmu 128c.sysmmu 128d.sysmmu 128e.sysmmu 13e8.sysmmu 13e9.sysmmu 1464.sysmmu 1465.sysmmu 1468.sysmmu IMHO there is no need for open coding new unique names if device name, which already contains the base address, can be used instead. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v7 2/4] dmaengine: Forward slave device pointer to of_xlate callback
Hi All, On 2017-01-26 15:43, Marek Szyprowski wrote: On 2017-01-25 14:12, Lars-Peter Clausen wrote: On 01/25/2017 11:28 AM, Marek Szyprowski wrote: Add pointer to slave device to of_dma_xlate to let DMA engine driver to know which slave device is using given DMA channel. This will be later used to implement non-irq-safe runtime PM for DMA engine driver. of_dma_xlate() is used to translate from a OF phandle and a specifier to a DMA channel. On one hand this does not necessarily mean that the channel is actually going to be used by the slave that called the xlate function. Modifying the driver state when a lookup of the channel is done is a layering violation. And this approach is also missing a way to disassociate a slave from a DMA channel, e.g. when it is no longer used. On the other hand there are other mechanisms to translate between some kind of firmware handle to a DMA channel which are completely ignored here. So this approach does not work. This is something that needs to be done at the dmaengine level, not a the firmware resource translation level. And it needs a matching method that is called when the channel is disassociated from a device, when the device no longer uses the DMA channel. Frankly I agree that of_dma_xlate() should only return the requested channel to the dmaengine core and do not do any modification in the the driver state. However the current dma engine design and implementation breaks this rule. Please check the drivers - how do they implement of_xlate callback. They usually call dma_get_any_slave_channel, dma_get_slave_channel or __dma_request_channel there, which in turn calls dma_chan_get, which then calls back to device_alloc_chan_resources callback. Some of the drivers also do a hardware configuration or other resource allocation in of_xlate. This is a bit messy design and leave no place in the core to set slave device before device_alloc_chan_resources callback, where one would expect to have it already set. The best place to add new calls to the dmaengine drivers to set slave device would be just before device_alloc_chan_resources(), what in turn means that the current dmaengine core should do in dma_chan_get(). This would require to forward the slave device pointer via even more layers including the of_xlate callback too. IMHO this is not worth the effort. DMA engine core and API definitely needs some cleanup. During such cleanup the slave device pointer might be moved out of xlate into separate callback when the core gets ready for such operation. I ignored other paths for other firmware handle to a DMA channel translation mechanism because for the current pl330 driver they are simply not used. I assume that if one needs to implement similar things for drivers relying on them, he will update the respective DMA engine core parts. Slave device assignments can be cleared in device_chan_release_resources if this is needed and that what existing DMA engine drivers do with the resources allocated in the of_xlate callback... Vinod: could you comment this patchset? Is there a chance to get it merged or at least give it a try in -next? If not, could you provide some hints what should I do? Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 7/7] arm64: dts: exynos: configure TV path clocks for Ultra HD modes
Hi Andrzej, On 2017-01-23 08:56, Andrzej Hajda wrote: Ultra HD modes requires clock ticking at increased rate. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index f120d99..4d28e93 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi I think that exynos5433-tm2-common.dtsi is a better place for such definitions. They can be also moved to _disp node to match convention for the clocks configuration used on particular board. @@ -764,6 +764,17 @@ clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", "pclk_smmu_decon0x", "sclk_decon_vclk", "sclk_decon_eclk"; + assigned-clocks = + <_mif CLK_MOUT_SCLK_DECON_TV_ECLK_A>, + <_mif CLK_DIV_SCLK_DECON_TV_ECLK>, + <_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>, + <_disp CLK_MOUT_SCLK_DECON_TV_ECLK>; + assigned-clock-parents = + <_mif CLK_MOUT_BUS_PLL_DIV2>, + <0>, + <_mif CLK_SCLK_DECON_TV_ECLK_DISP>, + <_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>; + assigned-clock-rates = <0>, <4>; samsung,disp-sysreg = <_disp>; interrupt-names = "fifo", "vsync", "lcd_sys"; interrupts = , Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v7 2/4] dmaengine: Forward slave device pointer to of_xlate callback
Hi Lars, On 2017-01-25 14:12, Lars-Peter Clausen wrote: On 01/25/2017 11:28 AM, Marek Szyprowski wrote: Add pointer to slave device to of_dma_xlate to let DMA engine driver to know which slave device is using given DMA channel. This will be later used to implement non-irq-safe runtime PM for DMA engine driver. of_dma_xlate() is used to translate from a OF phandle and a specifier to a DMA channel. On one hand this does not necessarily mean that the channel is actually going to be used by the slave that called the xlate function. Modifying the driver state when a lookup of the channel is done is a layering violation. And this approach is also missing a way to disassociate a slave from a DMA channel, e.g. when it is no longer used. On the other hand there are other mechanisms to translate between some kind of firmware handle to a DMA channel which are completely ignored here. So this approach does not work. This is something that needs to be done at the dmaengine level, not a the firmware resource translation level. And it needs a matching method that is called when the channel is disassociated from a device, when the device no longer uses the DMA channel. Frankly I agree that of_dma_xlate() should only return the requested channel to the dmaengine core and do not do any modification in the the driver state. However the current dma engine design and implementation breaks this rule. Please check the drivers - how do they implement of_xlate callback. They usually call dma_get_any_slave_channel, dma_get_slave_channel or __dma_request_channel there, which in turn calls dma_chan_get, which then calls back to device_alloc_chan_resources callback. Some of the drivers also do a hardware configuration or other resource allocation in of_xlate. This is a bit messy design and leave no place in the core to set slave device before device_alloc_chan_resources callback, where one would expect to have it already set. The best place to add new calls to the dmaengine drivers to set slave device would be just before device_alloc_chan_resources(), what in turn means that the current dmaengine core should do in dma_chan_get(). This would require to forward the slave device pointer via even more layers including the of_xlate callback too. IMHO this is not worth the effort. DMA engine core and API definitely needs some cleanup. During such cleanup the slave device pointer might be moved out of xlate into separate callback when the core gets ready for such operation. I ignored other paths for other firmware handle to a DMA channel translation mechanism because for the current pl330 driver they are simply not used. I assume that if one needs to implement similar things for drivers relying on them, he will update the respective DMA engine core parts. Slave device assignments can be cleared in device_chan_release_resources if this is needed and that what existing DMA engine drivers do with the resources allocated in the of_xlate callback... Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 3/8] pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs
Hi Krzysztof, On 2017-01-27 19:02, Krzysztof Kozlowski wrote: On Thu, Jan 26, 2017 at 09:48:11PM +0200, Krzysztof Kozlowski wrote: On Thu, Jan 26, 2017 at 09:33:49AM +0100, Marek Szyprowski wrote: This patch adds support for retention control for Exynos5433 SoCs. Three groups of pins has been defined for retention control: common shared group for ALIVE, CPIF, eSE, FINGER, IMEM, NFC, PERIC, TOUCH pin banks and separate control for FSYS and AUD pin banks, for which PMU retention registers match whole banks. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/pinctrl/samsung/pinctrl-exynos.c| 58 + include/linux/soc/samsung/exynos-regs-pmu.h | 16 I already have some non-conflicting changes to exynos-regs-pmu.h in my branch. Now I want to add some more which will create conflicts. How about splitting the header to separate patch, so I will take it to my exynos-pmu branch? Okay, I will split this into 2 patches. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH v3 0/7] Pad retentions support for Exynos5433
Hello, This patchset is a first step to add support for all power domains on Exynos5433 SoCs. This patchset contains patches for Exynos pin control driver and Exynos LPASS MFD driver, which are needed to make the platform ready for adding power domains support. Patches in this patchset depends on each other. They are order in such a way to make the changes bisectable. Patch #2 has compile dependency on #1. Patch #3 has runtime dependency on commit fa59aa70907b2 ("soc: samsung: pmu: Add dummy support for Exynos5433 SoC", for-v4.11/drivers-soc-exynos-pmu-the-joy-never-ends branch). Patch #4 has runtime dependency on #3. Patch #5 has runtime dependency on commit 7547162ac3514 ("arm64: dts: exynos: Add clocks to Exynos5433 LPASS module, next/dt64 branch). This patchset also directly depends on the "Move pad retention control to Exynos pin controller driver" patchset: https://www.spinics.net/lists/arm-kernel/msg556074.html Patches have been generated on top of linux-next from 30th January 2017 with the above mentioned patchset applied. This is a part of a larger task, which goal is to add support for power domains on Exynos5433 SoCs / TM2 boards. First version of the all patches needed to get it working have been pushed to the following git repo: https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.10-next-tm2-pd Best regards Marek Szyprowski Samsung R Institute Poland Changelog: v3: - moved adding new PMU register defines to separate patch (requested by Krzysztof Kozlowski) - rebased onto Linux next-20170130 (removed "soc: samsung: pmu: Add dummy support for Exynos5433 SoC" and "arm64: dts: exynos: Add clocks to Exynos5433 LPASS module" patches, which are already merged) v2: - fixed issues pointed by Krzysztof Kozlowski: 1. added more checks to Exynos PMU driver for NULL drvdata 2. reused EXYNOS_WAKEUP_FROM_LOWPWR in retention data for Exynos5433 3. converted lpass driver to devm_clk_get 4. added missing ->remove callback to lpass driver v1: https://lkml.org/lkml/2017/1/25/214 - initial version Patch summary: Marek Szyprowski (7): soc: smasung: pmu: Add register defines for pad retention control pinctrl: samsung: Ensure that pad retention is disabled on driver init pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs mfd: exynos-lpass: Remove pad retention control mfd: exynos-lpass: Add support for clocks mfd: exynos-lpass: Add missing remove() function mfd: exynos-lpass: Add runtime PM support .../bindings/mfd/samsung,exynos5433-lpass.txt | 8 ++- drivers/mfd/exynos-lpass.c | 48 ++--- drivers/pinctrl/samsung/pinctrl-exynos.c | 63 ++ include/linux/mfd/syscon/exynos5-pmu.h | 3 -- include/linux/soc/samsung/exynos-regs-pmu.h| 16 ++ 5 files changed, 115 insertions(+), 23 deletions(-) -- 1.9.1
[PATCH v3 2/7] pinctrl: samsung: Ensure that pad retention is disabled on driver init
When pin controller device is a part of power domain, there is no guarantee that the power domain was not turned off and then on during boot process before probing of the pin control driver. If it happened, then pin control driver should ensure that pad retention is turned off during its probe call. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> --- drivers/pinctrl/samsung/pinctrl-exynos.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 63e51b56a22a..fa3802970570 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -777,6 +777,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) { struct samsung_retention_ctrl *ctrl; struct regmap *pmu_regs; + int i; ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL); if (!ctrl) @@ -794,6 +795,10 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) ctrl->enable = exynos_retention_enable; ctrl->disable = exynos_retention_disable; + /* Ensure that retention is disabled on driver init */ + for (i = 0; i < ctrl->nr_regs; i++) + regmap_write(pmu_regs, ctrl->regs[i], ctrl->value); + return ctrl; } -- 1.9.1
[PATCH v3 4/7] mfd: exynos-lpass: Remove pad retention control
Pad retention should be controlled from pin control driver, so remove it from Exynos LPASS driver. After this change, no more access to PMU regmap is needed, so remove also the code for handling PMU regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Acked-by: Krzysztof Kozlowski <k...@kernel.org> Acked-by: Sylwester Nawrocki <s.nawro...@samsung.com> --- .../bindings/mfd/samsung,exynos5433-lpass.txt | 2 -- drivers/mfd/exynos-lpass.c | 17 - include/linux/mfd/syscon/exynos5-pmu.h | 3 --- 3 files changed, 22 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index c110e118b79f..a8deaee82c44 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -5,7 +5,6 @@ Required properties: - compatible : "samsung,exynos5433-lpass" - reg : should contain the LPASS top SFR region location and size - - samsung,pmu-syscon : the phandle to the Power Management Unit node - #address-cells : should be 1 - #size-cells : should be 1 - ranges : must be present @@ -25,7 +24,6 @@ Example: audio-subsystem { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; - samsung,pmu-syscon = <_system_controller>; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 2e064fb8826f..17915daa2e80 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -51,8 +50,6 @@ #define LPASS_INTR_SFRBIT(0) struct exynos_lpass { - /* pointer to the Power Management Unit regmap */ - struct regmap *pmu; /* pointer to the LPASS TOP regmap */ struct regmap *top; }; @@ -81,10 +78,6 @@ static void exynos_lpass_enable(struct exynos_lpass *lpass) regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); - /* Activate related PADs from retention state */ - regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, -EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR); - exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_MEM_SW_RESET); @@ -95,9 +88,6 @@ static void exynos_lpass_disable(struct exynos_lpass *lpass) /* Mask any unmasked IP interrupt sources */ regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); - - /* Deactivate related PADs from retention state */ - regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, 0); } static const struct regmap_config exynos_lpass_reg_conf = { @@ -131,13 +121,6 @@ static int exynos_lpass_probe(struct platform_device *pdev) return PTR_ERR(lpass->top); } - lpass->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,pmu-syscon"); - if (IS_ERR(lpass->pmu)) { - dev_err(dev, "Failed to lookup PMU regmap\n"); - return PTR_ERR(lpass->pmu); - } - platform_set_drvdata(pdev, lpass); exynos_lpass_enable(lpass); diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h index c28ff21ca4d2..0622ae86f9db 100644 --- a/include/linux/mfd/syscon/exynos5-pmu.h +++ b/include/linux/mfd/syscon/exynos5-pmu.h @@ -46,7 +46,4 @@ #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) #define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) -#define EXYNOS5433_PAD_RETENTION_AUD_OPTION(0x3028) -#define EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR BIT(28) - #endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */ -- 1.9.1
[PATCH v3 5/7] mfd: exynos-lpass: Add support for clocks
Exynos LPASS requires some clocks to be enabled to make any access to its registers. This patch adds code for handling such clocks. For current set of registers it is enough to keep sfr0_ctrl clock enabled. Till now it worked only because those clocks were enabled by bootloader and driver probe() happened before they were disabled by clock core because of lack of users. Handling those clocks is also needed to make it possible to enable support for audio power domain. This patch requires adding sfr0_ctrl clock to device tree. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> Acked-by: Sylwester Nawrocki <s.nawro...@samsung.com> --- .../devicetree/bindings/mfd/samsung,exynos5433-lpass.txt | 6 ++ drivers/mfd/exynos-lpass.c | 10 ++ 2 files changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index a8deaee82c44..df664018c148 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -5,6 +5,10 @@ Required properties: - compatible : "samsung,exynos5433-lpass" - reg : should contain the LPASS top SFR region location and size + - clock-names : should contain following required clocks: "sfr0_ctrl" + - clocks : should contain clock specifiers of all clocks, which + input names have been specified in clock-names + property, in same order. - #address-cells : should be 1 - #size-cells : should be 1 - ranges : must be present @@ -24,6 +28,8 @@ Example: audio-subsystem { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 17915daa2e80..be264988bdc9 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -14,6 +14,7 @@ * only version 2 as published by the Free Software Foundation. */ +#include #include #include #include @@ -52,6 +53,7 @@ struct exynos_lpass { /* pointer to the LPASS TOP regmap */ struct regmap *top; + struct clk *sfr0_clk; }; static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) @@ -71,6 +73,8 @@ static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) static void exynos_lpass_enable(struct exynos_lpass *lpass) { + clk_prepare_enable(lpass->sfr0_clk); + /* Unmask SFR, DMA and I2S interrupt */ regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); @@ -88,6 +92,8 @@ static void exynos_lpass_disable(struct exynos_lpass *lpass) /* Mask any unmasked IP interrupt sources */ regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); + + clk_disable_unprepare(lpass->sfr0_clk); } static const struct regmap_config exynos_lpass_reg_conf = { @@ -114,6 +120,10 @@ static int exynos_lpass_probe(struct platform_device *pdev) if (IS_ERR(base_top)) return PTR_ERR(base_top); + lpass->sfr0_clk = devm_clk_get(dev, "sfr0_ctrl"); + if (IS_ERR(lpass->sfr0_clk)) + return PTR_ERR(lpass->sfr0_clk); + lpass->top = regmap_init_mmio(dev, base_top, _lpass_reg_conf); if (IS_ERR(lpass->top)) { -- 1.9.1
[PATCH v3 6/7] mfd: exynos-lpass: Add missing remove() function
Disable device on driver remove and release allocated regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> Acked-by: Sylwester Nawrocki <s.nawro...@samsung.com> --- drivers/mfd/exynos-lpass.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index be264988bdc9..9dbbedad916f 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -137,6 +137,16 @@ static int exynos_lpass_probe(struct platform_device *pdev) return of_platform_populate(dev->of_node, NULL, NULL, dev); } +static int exynos_lpass_remove(struct platform_device *pdev) +{ + struct exynos_lpass *lpass = platform_get_drvdata(pdev); + + exynos_lpass_disable(lpass); + regmap_exit(lpass->top); + + return 0; +} + static int __maybe_unused exynos_lpass_suspend(struct device *dev) { struct exynos_lpass *lpass = dev_get_drvdata(dev); @@ -171,6 +181,7 @@ static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend, .of_match_table = exynos_lpass_of_match, }, .probe = exynos_lpass_probe, + .remove = exynos_lpass_remove, }; module_platform_driver(exynos_lpass_driver); -- 1.9.1
[PATCH v3 3/7] pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs
This patch adds support for retention control for Exynos5433 SoCs. Three groups of pins has been defined for retention control: common shared group for ALIVE, CPIF, eSE, FINGER, IMEM, NFC, PERIC, TOUCH pin banks and separate control for FSYS and AUD pin banks, for which PMU retention registers match whole banks. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> --- drivers/pinctrl/samsung/pinctrl-exynos.c | 58 1 file changed, 58 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index fa3802970570..7b0e6cc35e04 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -1551,6 +1551,54 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), }; +/* PMU pin retention groups registers for Exynos5433 (without audio & fsys) */ +static const u32 exynos5433_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_TOP_OPTION, + EXYNOS5433_PAD_RETENTION_UART_OPTION, + EXYNOS5433_PAD_RETENTION_EBIA_OPTION, + EXYNOS5433_PAD_RETENTION_EBIB_OPTION, + EXYNOS5433_PAD_RETENTION_SPI_OPTION, + EXYNOS5433_PAD_RETENTION_MIF_OPTION, + EXYNOS5433_PAD_RETENTION_USBXTI_OPTION, + EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION, + EXYNOS5433_PAD_RETENTION_UFS_OPTION, + EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION, +}; + +static const struct samsung_retention_data exynos5433_retention_data __initconst = { + .regs= exynos5433_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .refcnt = _shared_retention_refcnt, + .init= exynos_retention_init, +}; + +/* PMU retention control for audio pins can be tied to audio pin bank */ +static const u32 exynos5433_audio_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_AUD_OPTION, +}; + +static const struct samsung_retention_data exynos5433_audio_retention_data __initconst = { + .regs= exynos5433_audio_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_audio_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .init= exynos_retention_init, +}; + +/* PMU retention control for mmc pins can be tied to fsys pin bank */ +static const u32 exynos5433_fsys_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_MMC0_OPTION, + EXYNOS5433_PAD_RETENTION_MMC1_OPTION, + EXYNOS5433_PAD_RETENTION_MMC2_OPTION, +}; + +static const struct samsung_retention_data exynos5433_fsys_retention_data __initconst = { + .regs= exynos5433_fsys_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_fsys_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .init= exynos_retention_init, +}; + /* * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes * ten gpio/pin-mux/pinconfig controllers. @@ -1564,6 +1612,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, .nr_ext_resources = 1, + .retention_data = _retention_data, }, { /* pin-controller instance 1 data */ .pin_banks = exynos5433_pin_banks1, @@ -1571,6 +1620,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _audio_retention_data, }, { /* pin-controller instance 2 data */ .pin_banks = exynos5433_pin_banks2, @@ -1578,6 +1628,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _retention_data, }, { /* pin-controller instance 3 data */ .pin_banks = exynos5433_pin_banks3, @@ -1585,6 +1636,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _retention_data, }, { /* pin-controller instance 4 data */ .pin_banks = exynos5433_pin_banks4, @@ -1592,6 +1644,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_in
Re: [PATCH v2 0/8] Pad retentions support for Exynos5433
Hi Krzysztof, On 2017-01-27 20:46, Krzysztof Kozlowski wrote: On Thu, Jan 26, 2017 at 09:33:46AM +0100, Marek Szyprowski wrote: This patchset is a first step to add support for all power domains on Exynos5433 SoCs. This patchset contains patches for Exynos pin control driver and Exynos LPASS MFD driver, which are needed to make the platform ready for adding power domains support. Patches in this patchset depends on each other. They are order in such a way to make the changes bisectable. Patch #3 has runtime dependency on #1. Patch #5 has runtime dependency on #3. Patch #6 has runtime dependency on #4. This patchset also directly depends on the "Move pad retention control to Exynos pin controller driver" patchset: https://www.spinics.net/lists/arm-kernel/msg556074.html Patches have been generated on top of linux-next from 25th January 2017. This is a part of a larger task, which goal is to add support for power domains on Exynos5433 SoCs / TM2 boards. All patches needed to get it working have been pushed to the following git repo: https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.10-next-tm2-pd I tried your branch above on Odroid U3 and it fails to boot. next-20170125 works fine. exynos_defconfig, booting from microSD. Board hangs (silently) on: [2.283437] usb 1-3: new high-speed USB device number 3 using exynos-ehci [2.473786] usb 1-3: New USB device found, idVendor=0424, idProduct=3503 [2.474856] usb 1-3: New USB device strings: Mfr=0, Product=0, SerialNumber=0 [2.482656] hub 1-3:1.0: USB hub found [2.486017] hub 1-3:1.0: 3 ports detected [ 55.037205] random: crng init done Full log attached. Huh... Reproduced. This is another reincarnation of the prepare_mutex in clock's core related deadlock, now caused by Exynos Audio Subsystem clock's driver, Exynos I2S driver and Samsung SDHCI driver. It looks that this issue becomes even more problematic now and urgently needs a proper fix, because it gets really hard to make more workarounds everywhere else. For now I will probably drop Exynos AudioSS patch from this series and send a revert for commit 9b41da80e09128574f09bed8dc5a5fc6f72a8239 ("ASoC: samsung: i2s: Provide I2S device for registered clocks"), which has to wait until the deadlock gets proper generic fix. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH v3 7/7] mfd: exynos-lpass: Add runtime PM support
Convert exisitng lpass-suspend/resume callbacks into runtime PM callbacks. This way Exynos LPASS driver will be ready for use with power domains enabled. LPASS will be runtime resumed/suspended as a result of its child devices runtime PM transitions. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Acked-by: Krzysztof Kozlowski <k...@kernel.org> Acked-by: Sylwester Nawrocki <s.nawro...@samsung.com> --- drivers/mfd/exynos-lpass.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 9dbbedad916f..6d735e22acda 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -132,6 +133,8 @@ static int exynos_lpass_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, lpass); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); exynos_lpass_enable(lpass); return of_platform_populate(dev->of_node, NULL, NULL, dev); @@ -141,7 +144,9 @@ static int exynos_lpass_remove(struct platform_device *pdev) { struct exynos_lpass *lpass = platform_get_drvdata(pdev); - exynos_lpass_disable(lpass); + pm_runtime_disable(>dev); + if (!pm_runtime_status_suspended(>dev)) + exynos_lpass_disable(lpass); regmap_exit(lpass->top); return 0; @@ -165,8 +170,11 @@ static int __maybe_unused exynos_lpass_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend, - exynos_lpass_resume); +static const struct dev_pm_ops lpass_pm_ops = { + SET_RUNTIME_PM_OPS(exynos_lpass_suspend, exynos_lpass_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, +pm_runtime_force_resume) +}; static const struct of_device_id exynos_lpass_of_match[] = { { .compatible = "samsung,exynos5433-lpass" }, -- 1.9.1
[PATCH v3 1/7] soc: smasung: pmu: Add register defines for pad retention control
Add PMU defines related to pad retention control. Will be later used by the Exynos pin controller driver. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- include/linux/soc/samsung/exynos-regs-pmu.h | 16 1 file changed, 16 insertions(+) diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index 9786c62d7159..49df0a01a2cc 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -631,4 +631,20 @@ | EXYNOS5420_KFC_USE_STANDBY_WFI2 \ | EXYNOS5420_KFC_USE_STANDBY_WFI3) +/* For EXYNOS5433 */ +#define EXYNOS5433_PAD_RETENTION_AUD_OPTION(0x3028) +#define EXYNOS5433_PAD_RETENTION_MMC2_OPTION (0x30C8) +#define EXYNOS5433_PAD_RETENTION_TOP_OPTION(0x3108) +#define EXYNOS5433_PAD_RETENTION_UART_OPTION (0x3128) +#define EXYNOS5433_PAD_RETENTION_MMC0_OPTION (0x3148) +#define EXYNOS5433_PAD_RETENTION_MMC1_OPTION (0x3168) +#define EXYNOS5433_PAD_RETENTION_EBIA_OPTION (0x3188) +#define EXYNOS5433_PAD_RETENTION_EBIB_OPTION (0x31A8) +#define EXYNOS5433_PAD_RETENTION_SPI_OPTION(0x31C8) +#define EXYNOS5433_PAD_RETENTION_MIF_OPTION(0x31E8) +#define EXYNOS5433_PAD_RETENTION_USBXTI_OPTION (0x3228) +#define EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION(0x3248) +#define EXYNOS5433_PAD_RETENTION_UFS_OPTION(0x3268) +#define EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION (0x32A8) + #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */ -- 1.9.1
[PATCH 1/7] soc: samsung: pmu: Add dummy support for Exynos5433 SoC
Add compatible for Exynos5433 SoC, so the driver will bind and let other drivers to use PMU regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/soc/samsung/exynos-pmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 813df6e7292d..effb8a8a78c6 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -90,6 +90,8 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) }, { .compatible = "samsung,exynos5420-pmu", .data = _pmu_data, + }, { + .compatible = "samsung,exynos5433-pmu", }, { /*sentinel*/ }, }; @@ -122,7 +124,7 @@ static int exynos_pmu_probe(struct platform_device *pdev) pmu_context->dev = dev; pmu_context->pmu_data = of_device_get_match_data(dev); - if (pmu_context->pmu_data->pmu_init) + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init) pmu_context->pmu_data->pmu_init(); platform_set_drvdata(pdev, pmu_context); -- 1.9.1
[PATCH 2/7] pinctrl: samsung: Ensure that pad retention is disabled on driver init
When pin controller device is a part of power domain, there is no guarantee that the power domain was not turned off and then on during boot process before probing of the pin control driver. If it happened, then pin control driver should ensure that pad retention is turned off during its probe call. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/pinctrl/samsung/pinctrl-exynos.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 63e51b56a22a..fa3802970570 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -777,6 +777,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) { struct samsung_retention_ctrl *ctrl; struct regmap *pmu_regs; + int i; ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL); if (!ctrl) @@ -794,6 +795,10 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) ctrl->enable = exynos_retention_enable; ctrl->disable = exynos_retention_disable; + /* Ensure that retention is disabled on driver init */ + for (i = 0; i < ctrl->nr_regs; i++) + regmap_write(pmu_regs, ctrl->regs[i], ctrl->value); + return ctrl; } -- 1.9.1
[PATCH 7/7] mfd: exynos-lpass: Add runtime PM support
Convert exisitng lpass-suspend/resume callbacks into runtime PM callbacks. This way Exynos LPASS driver will be ready for use with power domains enabled. LPASS will be runtime resumed/suspended as a result of its child devices runtime PM transitions. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/mfd/exynos-lpass.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 44d8ea1a978b..d383b2f6f207 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -132,6 +133,8 @@ static int exynos_lpass_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, lpass); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); exynos_lpass_enable(lpass); return of_platform_populate(dev->of_node, NULL, NULL, dev); @@ -155,8 +158,11 @@ static int __maybe_unused exynos_lpass_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend, - exynos_lpass_resume); +static const struct dev_pm_ops lpass_pm_ops = { + SET_RUNTIME_PM_OPS(exynos_lpass_suspend, exynos_lpass_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, +pm_runtime_force_resume) +}; static const struct of_device_id exynos_lpass_of_match[] = { { .compatible = "samsung,exynos5433-lpass" }, -- 1.9.1
[PATCH 3/7] pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs
This patch adds support for retention control for Exynos5433 SoCs. Three groups of pins has been defined for retention control: common shared group for ALIVE, CPIF, eSE, FINGER, IMEM, NFC, PERIC, TOUCH pin banks and separate control for FSYS and AUD pin banks, for which PMU retention registers match whole banks. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/pinctrl/samsung/pinctrl-exynos.c| 58 + include/linux/soc/samsung/exynos-regs-pmu.h | 19 ++ 2 files changed, 77 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index fa3802970570..f854c92209e1 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -1551,6 +1551,54 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), }; +/* PMU pin retention groups registers for Exynos5433 (without audio & fsys) */ +static const u32 exynos5433_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_TOP_OPTION, + EXYNOS5433_PAD_RETENTION_UART_OPTION, + EXYNOS5433_PAD_RETENTION_EBIA_OPTION, + EXYNOS5433_PAD_RETENTION_EBIB_OPTION, + EXYNOS5433_PAD_RETENTION_SPI_OPTION, + EXYNOS5433_PAD_RETENTION_MIF_OPTION, + EXYNOS5433_PAD_RETENTION_USBXTI_OPTION, + EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION, + EXYNOS5433_PAD_RETENTION_UFS_OPTION, + EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION, +}; + +static const struct samsung_retention_data exynos5433_retention_data __initconst = { + .regs= exynos5433_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_retention_regs), + .value = PAD_INITIATE_WAKEUP, + .refcnt = _shared_retention_refcnt, + .init= exynos_retention_init, +}; + +/* PMU retention control for audio pins can be tied to audio pin bank */ +static const u32 exynos5433_audio_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_AUD_OPTION, +}; + +static const struct samsung_retention_data exynos5433_audio_retention_data __initconst = { + .regs= exynos5433_audio_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_audio_retention_regs), + .value = PAD_INITIATE_WAKEUP, + .init= exynos_retention_init, +}; + +/* PMU retention control for mmc pins can be tied to fsys pin bank */ +static const u32 exynos5433_fsys_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_MMC0_OPTION, + EXYNOS5433_PAD_RETENTION_MMC1_OPTION, + EXYNOS5433_PAD_RETENTION_MMC2_OPTION, +}; + +static const struct samsung_retention_data exynos5433_fsys_retention_data __initconst = { + .regs= exynos5433_fsys_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_fsys_retention_regs), + .value = PAD_INITIATE_WAKEUP, + .init= exynos_retention_init, +}; + /* * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes * ten gpio/pin-mux/pinconfig controllers. @@ -1564,6 +1612,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, .nr_ext_resources = 1, + .retention_data = _retention_data, }, { /* pin-controller instance 1 data */ .pin_banks = exynos5433_pin_banks1, @@ -1571,6 +1620,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _audio_retention_data, }, { /* pin-controller instance 2 data */ .pin_banks = exynos5433_pin_banks2, @@ -1578,6 +1628,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _retention_data, }, { /* pin-controller instance 3 data */ .pin_banks = exynos5433_pin_banks3, @@ -1585,6 +1636,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _retention_data, }, { /* pin-controller instance 4 data */ .pin_banks = exynos5433_pin_banks4, @@ -1592,6 +1644,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = e
[PATCH 5/7] mfd: exynos-lpass: Remove pad retention control
Pad retention should be controlled from pin control driver, so remove it from Exynos LPASS driver. After this change, no more access to PMU regmap is needed, so remove also the code for handling PMU regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- .../bindings/mfd/samsung,exynos5433-lpass.txt | 2 -- drivers/mfd/exynos-lpass.c | 17 - include/linux/mfd/syscon/exynos5-pmu.h | 3 --- 3 files changed, 22 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index c110e118b79f..a8deaee82c44 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -5,7 +5,6 @@ Required properties: - compatible : "samsung,exynos5433-lpass" - reg : should contain the LPASS top SFR region location and size - - samsung,pmu-syscon : the phandle to the Power Management Unit node - #address-cells : should be 1 - #size-cells : should be 1 - ranges : must be present @@ -25,7 +24,6 @@ Example: audio-subsystem { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; - samsung,pmu-syscon = <_system_controller>; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 2e064fb8826f..17915daa2e80 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -51,8 +50,6 @@ #define LPASS_INTR_SFRBIT(0) struct exynos_lpass { - /* pointer to the Power Management Unit regmap */ - struct regmap *pmu; /* pointer to the LPASS TOP regmap */ struct regmap *top; }; @@ -81,10 +78,6 @@ static void exynos_lpass_enable(struct exynos_lpass *lpass) regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); - /* Activate related PADs from retention state */ - regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, -EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR); - exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_MEM_SW_RESET); @@ -95,9 +88,6 @@ static void exynos_lpass_disable(struct exynos_lpass *lpass) /* Mask any unmasked IP interrupt sources */ regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); - - /* Deactivate related PADs from retention state */ - regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, 0); } static const struct regmap_config exynos_lpass_reg_conf = { @@ -131,13 +121,6 @@ static int exynos_lpass_probe(struct platform_device *pdev) return PTR_ERR(lpass->top); } - lpass->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,pmu-syscon"); - if (IS_ERR(lpass->pmu)) { - dev_err(dev, "Failed to lookup PMU regmap\n"); - return PTR_ERR(lpass->pmu); - } - platform_set_drvdata(pdev, lpass); exynos_lpass_enable(lpass); diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h index c28ff21ca4d2..0622ae86f9db 100644 --- a/include/linux/mfd/syscon/exynos5-pmu.h +++ b/include/linux/mfd/syscon/exynos5-pmu.h @@ -46,7 +46,4 @@ #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) #define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) -#define EXYNOS5433_PAD_RETENTION_AUD_OPTION(0x3028) -#define EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR BIT(28) - #endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */ -- 1.9.1
[PATCH v7 2/4] dmaengine: Forward slave device pointer to of_xlate callback
Add pointer to slave device to of_dma_xlate to let DMA engine driver to know which slave device is using given DMA channel. This will be later used to implement non-irq-safe runtime PM for DMA engine driver. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Ulf Hansson <ulf.hans...@linaro.org> Acked-by: Arnd Bergmann <a...@arndb.de> --- drivers/dma/amba-pl08x.c| 2 +- drivers/dma/at_hdmac.c | 4 ++-- drivers/dma/at_xdmac.c | 2 +- drivers/dma/bcm2835-dma.c | 2 +- drivers/dma/coh901318.c | 2 +- drivers/dma/cppi41.c| 2 +- drivers/dma/dma-jz4780.c| 2 +- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw/platform.c | 2 +- drivers/dma/edma.c | 4 ++-- drivers/dma/fsl-edma.c | 2 +- drivers/dma/img-mdc-dma.c | 2 +- drivers/dma/imx-dma.c | 2 +- drivers/dma/imx-sdma.c | 2 +- drivers/dma/k3dma.c | 2 +- drivers/dma/lpc18xx-dmamux.c| 2 +- drivers/dma/mmp_pdma.c | 2 +- drivers/dma/mmp_tdma.c | 2 +- drivers/dma/moxart-dma.c| 2 +- drivers/dma/mxs-dma.c | 2 +- drivers/dma/nbpfaxi.c | 2 +- drivers/dma/of-dma.c| 19 --- drivers/dma/pl330.c | 3 ++- drivers/dma/pxa_dma.c | 2 +- drivers/dma/qcom/bam_dma.c | 2 +- drivers/dma/sh/rcar-dmac.c | 2 +- drivers/dma/sh/shdma-of.c | 2 +- drivers/dma/sh/usb-dmac.c | 2 +- drivers/dma/sirf-dma.c | 2 +- drivers/dma/st_fdma.c | 2 +- drivers/dma/ste_dma40.c | 2 +- drivers/dma/stm32-dma.c | 2 +- drivers/dma/sun4i-dma.c | 2 +- drivers/dma/sun6i-dma.c | 2 +- drivers/dma/tegra20-apb-dma.c | 2 +- drivers/dma/tegra210-adma.c | 2 +- drivers/dma/xilinx/xilinx_dma.c | 2 +- drivers/dma/xilinx/zynqmp_dma.c | 2 +- drivers/dma/zx_dma.c| 2 +- include/linux/of_dma.h | 19 +++ sound/soc/sh/rcar/dma.c | 5 +++-- sound/soc/sh/rcar/dvc.c | 3 ++- sound/soc/sh/rcar/rsnd.h| 3 ++- sound/soc/sh/rcar/src.c | 3 ++- sound/soc/sh/rcar/ssi.c | 3 ++- 45 files changed, 75 insertions(+), 61 deletions(-) diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 0b7c6ce629a6..194089c98755 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -2059,7 +2059,7 @@ static struct dma_chan *pl08x_find_chan_id(struct pl08x_driver_data *pl08x, } static struct dma_chan *pl08x_of_xlate(struct of_phandle_args *dma_spec, - struct of_dma *ofdma) +struct of_dma *ofdma, struct device *slave) { struct pl08x_driver_data *pl08x = ofdma->of_dma_data; struct dma_chan *dma_chan; diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 1baf3404a365..b228b263ac0c 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1788,7 +1788,7 @@ static bool at_dma_filter(struct dma_chan *chan, void *slave) } static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec, -struct of_dma *of_dma) + struct of_dma *of_dma, struct device *slave) { struct dma_chan *chan; struct at_dma_chan *atchan; @@ -1847,7 +1847,7 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec, } #else static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec, -struct of_dma *of_dma) + struct of_dma *of_dma, struct device *slave) { return NULL; } diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 7d4e0bcda9af..9ddd868c9b59 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -508,7 +508,7 @@ static inline void at_xdmac_increment_block_count(struct dma_chan *chan, } static struct dma_chan *at_xdmac_xlate(struct of_phandle_args *dma_spec, - struct of_dma *of_dma) + struct of_dma *of_dma, struct device *slave) { struct at_xdmac *atxdmac = of_dma->of_dma_data; struct at_xdmac_chan*atchan; diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index e18dc596cf24..e9c417ad2141 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -877,7 +877,7 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od) MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match); static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec, - struct of_dma *ofdma) +struct of_dma *ofdma, struct device *slave) { struct bcm2835_dmadev *d = ofdma->of_dma_data; struct dma_chan *chan; diff --git
[PATCH v7 1/4] dmaengine: pl330: remove pdata based initialization
This driver is now used only on platforms which support device tree, so it is safe to remove legacy platform data based initialization code. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Ulf Hansson <ulf.hans...@linaro.org> Acked-by: Arnd Bergmann <a...@arndb.de> For plat-samsung: Acked-by: Krzysztof Kozlowski <k...@kernel.org> --- arch/arm/plat-samsung/devs.c | 1 - drivers/dma/pl330.c | 42 -- include/linux/amba/pl330.h | 35 --- 3 files changed, 8 insertions(+), 70 deletions(-) delete mode 100644 include/linux/amba/pl330.h diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 03fac123676d..dc269d9143bc 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -10,7 +10,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 7539f73df9e0..78be12b45a45 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -2076,18 +2075,6 @@ static void pl330_tasklet(unsigned long data) } } -bool pl330_filter(struct dma_chan *chan, void *param) -{ - u8 *peri_id; - - if (chan->device->dev->driver != _driver.drv) - return false; - - peri_id = chan->private; - return *peri_id == (unsigned long)param; -} -EXPORT_SYMBOL(pl330_filter); - static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { @@ -2832,7 +2819,6 @@ static int __maybe_unused pl330_resume(struct device *dev) static int pl330_probe(struct amba_device *adev, const struct amba_id *id) { - struct dma_pl330_platdata *pdat; struct pl330_config *pcfg; struct pl330_dmac *pl330; struct dma_pl330_chan *pch, *_p; @@ -2842,8 +2828,6 @@ static int __maybe_unused pl330_resume(struct device *dev) int num_chan; struct device_node *np = adev->dev.of_node; - pdat = dev_get_platdata(>dev); - ret = dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(32)); if (ret) return ret; @@ -2856,7 +2840,7 @@ static int __maybe_unused pl330_resume(struct device *dev) pd = >ddma; pd->dev = >dev; - pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; + pl330->mcbufsz = 0; /* get quirk */ for (i = 0; i < ARRAY_SIZE(of_quirks); i++) @@ -2900,10 +2884,7 @@ static int __maybe_unused pl330_resume(struct device *dev) INIT_LIST_HEAD(>channels); /* Initialize channel parameters */ - if (pdat) - num_chan = max_t(int, pdat->nr_valid_peri, pcfg->num_chan); - else - num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); + num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); pl330->num_peripherals = num_chan; @@ -2915,11 +2896,8 @@ static int __maybe_unused pl330_resume(struct device *dev) for (i = 0; i < num_chan; i++) { pch = >peripherals[i]; - if (!adev->dev.of_node) - pch->chan.private = pdat ? >peri_id[i] : NULL; - else - pch->chan.private = adev->dev.of_node; + pch->chan.private = adev->dev.of_node; INIT_LIST_HEAD(>submitted_list); INIT_LIST_HEAD(>work_list); INIT_LIST_HEAD(>completed_list); @@ -2932,15 +2910,11 @@ static int __maybe_unused pl330_resume(struct device *dev) list_add_tail(>chan.device_node, >channels); } - if (pdat) { - pd->cap_mask = pdat->cap_mask; - } else { - dma_cap_set(DMA_MEMCPY, pd->cap_mask); - if (pcfg->num_peri) { - dma_cap_set(DMA_SLAVE, pd->cap_mask); - dma_cap_set(DMA_CYCLIC, pd->cap_mask); - dma_cap_set(DMA_PRIVATE, pd->cap_mask); - } + dma_cap_set(DMA_MEMCPY, pd->cap_mask); + if (pcfg->num_peri) { + dma_cap_set(DMA_SLAVE, pd->cap_mask); + dma_cap_set(DMA_CYCLIC, pd->cap_mask); + dma_cap_set(DMA_PRIVATE, pd->cap_mask); } pd->device_alloc_chan_resources = pl330_alloc_chan_resources; diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h deleted file mode 100644 index fe93758e8403.. --- a/include/linux/amba/pl330.h +++ /dev/null @@ -1,35 +0,0 @@ -/* linux/include/linux/amba/pl330.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh <jassi.b...@samsung.co
[PATCH v7 0/4] DMA Engine: switch PL330 driver to non-irq-safe runtime PM
Hello, This patchset changes the way the runtime PM is implemented in the PL330 DMA engine driver. The main goal of such change is to add support for the audio power domain to Exynos5 SoCs (5250, 542x, 5433, probably others) and let it to be properly turned off, when no audio is being used. Switching to non-irq-safe runtime PM is required to properly let power domain to be turned off (irq-safe runtime PM keeps power domain turned on all the time) and to integrate with clock controller's runtime PM (this cannot be workarounded any other way, PL330 uses clocks from the controller, which belongs to the same power domain). For more details of the proposed change to the PL330 driver see patch #4. Audio power domain on Exynos5 SoCs contains following hardware modules: 1. clock controller 2. pin controller 3. PL330 DMA controller 4. I2S audio controller Patches for adding or fixing runtime PM for each of the above devices is handled separately. Runtime PM patches for clock controllers is possible and has been proposed in the following thread (pending review): "[PATCH v4 0/4] Add runtime PM support for clocks (on Exynos SoC example)", http://www.spinics.net/lists/arm-kernel/msg550747.html Runtime PM support for Exynos pin controller has been posted in the following thread: "[PATCH 0/9] Runtime PM for Exynos pin controller driver", http://www.spinics.net/lists/arm-kernel/msg550161.html Exynos I2S driver supports runtime PM, but some fixes were needed for it and they are already queued to linux-next. This patchset is based on linux-next from 25th January 2017 with "dmaengine: pl330: fix double lock" patch applied. Best regards Marek Szyprowski Samsung R Institute Poland Changelog: v7: - added missing of_dma_request_slave_channel API change to sound/soc/sh/rcar driver - extended commit message with information about drawbacks of irq-safe runtime pm - added Ulf's reviewed-by tags v6: https://www.spinics.net/lists/arm-kernel/msg557377.html - fixed pl330 system sleep suspend/resume callbacks, previous implementation incorrectly tried to unprepare clocks unconditionally - after a fix pl330 suspend/resume callbacks can be simply replaced by generic pm_runtime_force_{suspend,resume} helpers, what simplifies code even more v5: https://www.spinics.net/lists/arm-kernel/msg555001.html - added Acks - additional mutex is indeed not needed, rely on dma_list_mutex in dmaengine core, added comment about locking v4: http://www.spinics.net/lists/dmaengine/msg12329.html - rebased onto "dmaengine: pl330: fix double lock" patch: http://www.spinics.net/lists/dmaengine/msg12289.html - added a mutex to protect runtime PM links creation/removal to avoid races - moved mem2mem channel case handing to pl330_{add,del}_slave_pm_link functions to simplify code and error paths v3: http://www.spinics.net/lists/dmaengine/msg12245.html - removed pl330_filter function as suggested by Arnd Bergmann - removed pl330.h from arch/arm/plat-samsung/devs.c - fixes some minor style issues pointed by Krzysztof Kozlowski v2: https://www.spinics.net/lists/arm-kernel/msg552772.html - rebased onto linux next-20170109 - improved patch description - separated patch #3 from #4 (storing a pointer to slave device for each DMA channel) as requested by Krzysztof Kozlowski v1: https://www.spinics.net/lists/arm-kernel/msg550008.html - initial version Patch summary: Marek Szyprowski (4): dmaengine: pl330: remove pdata based initialization dmaengine: Forward slave device pointer to of_xlate callback dmaengine: pl330: Store pointer to slave device dmaengine: pl330: Don't require irq-safe runtime PM arch/arm/plat-samsung/devs.c| 1 - drivers/dma/amba-pl08x.c| 2 +- drivers/dma/at_hdmac.c | 4 +- drivers/dma/at_xdmac.c | 2 +- drivers/dma/bcm2835-dma.c | 2 +- drivers/dma/coh901318.c | 2 +- drivers/dma/cppi41.c| 2 +- drivers/dma/dma-jz4780.c| 2 +- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw/platform.c | 2 +- drivers/dma/edma.c | 4 +- drivers/dma/fsl-edma.c | 2 +- drivers/dma/img-mdc-dma.c | 2 +- drivers/dma/imx-dma.c | 2 +- drivers/dma/imx-sdma.c | 2 +- drivers/dma/k3dma.c | 2 +- drivers/dma/lpc18xx-dmamux.c| 2 +- drivers/dma/mmp_pdma.c | 2 +- drivers/dma/mmp_tdma.c | 2 +- drivers/dma/moxart-dma.c| 2 +- drivers/dma/mxs-dma.c | 2 +- drivers/dma/nbpfaxi.c | 2 +- drivers/dma/of-dma.c| 19 ++-- drivers/dma/pl330.c | 220 drivers/dma/pxa_dma.c | 2 +- drivers/dma/qcom/bam_dma.c | 2 +- drivers/dma/sh/rcar-dmac.c | 2 +- drivers/dma/sh/shdma-of.c | 2 +- drivers/dma/sh/usb-dmac.c | 2 +- drivers/dma/sirf-dma.c | 2 +- drivers/dma/s
[PATCH v7 4/4] dmaengine: pl330: Don't require irq-safe runtime PM
This patch replaces irq-safe runtime PM with non-irq-safe version based on the new approach. Existing, irq-safe runtime PM implementation for PL330 was not bringing much benefits of its own - only clocks were enabled/disabled. Another limitation of irq-safe runtime PM is a fact, that it may prevent the generic PM domain (genpd) from being powered off, particularly in cases when the genpd doesn't have the GENPD_FLAG_IRQ_SAFE set. Till now non-irq-safe runtime PM implementation was only possible by calling pm_runtime_get/put functions from alloc/free_chan_resources. All other DMA engine API functions cannot be called from a context, which permits sleeping. Such implementation, in practice would result in keeping DMA controller's device active almost all the time, because most of the slave device drivers (DMA engine clients) acquire DMA channel in their probe() function and released it during driver removal. This patch provides a new, different approach. It is based on an observation that there can be only one slave device using each DMA channel. PL330 hardware always has dedicated channels for each peripheral device. Using recently introduced device dependencies (links) infrastructure one can ensure proper runtime PM state of PL330 DMA controller basing on the runtime PM state of the slave device. In this approach in pl330_alloc_chan_resources() function a new dependency is being created between PL330 DMA controller device (as a supplier) and given slave device (as a consumer). This way PL330 DMA controller device runtime active counter is increased when the slave device is resumed and decreased the same time when given slave device is put to suspend. This way it has been ensured to keep PL330 DMA controller runtime active if there is an active used of any of its DMA channels. Slave device pointer is initially stored in per-channel data in of_dma_xlate callback. This is similar to what has been already implemented in Exynos IOMMU driver in commit 2f5f44f205cc95 ("iommu/exynos: Use device dependency links to control runtime pm"). If slave device doesn't implement runtime PM or keeps device runtime active all the time, then PL330 DMA controller will be runtime active all the time when channel is being allocated. If one requests memory-to-memory channel, runtime active counter is increased unconditionally. This might be a drawback of this approach, but PL330 is not really used for memory-to-memory operations due to poor performance in such operations compared to the CPU. Removal of irq-safe runtime PM is based on the revert of the following commits: 1. commit 5c9e6c2b2ba3 "dmaengine: pl330: fix runtime pm support" 2. commit 81cc6edc0870 "dmaengine: pl330: Fix hang on dmaengine_terminate_all on certain boards" 3. commit ae43b3289186 "ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12" Introducing non-irq-safe runtime power management finally allows to turn off audio power domain on Exynos5 SoCs. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> Reviewed-by: Ulf Hansson <ulf.hans...@linaro.org> Acked-by: Arnd Bergmann <a...@arndb.de> --- drivers/dma/pl330.c | 166 +--- 1 file changed, 66 insertions(+), 100 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index c77a3494659c..dff7228198f6 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -268,9 +268,6 @@ enum pl330_byteswap { #define NR_DEFAULT_DESC16 -/* Delay for runtime PM autosuspend, ms */ -#define PL330_AUTOSUSPEND_DELAY 20 - /* Populated by the PL330 core driver for DMA API driver's info */ struct pl330_config { u32 periph_id; @@ -449,8 +446,8 @@ struct dma_pl330_chan { bool cyclic; /* for runtime pm tracking */ - bool active; struct device *slave; + struct device_link *slave_link; }; struct pl330_dmac { @@ -2008,7 +2005,6 @@ static void pl330_tasklet(unsigned long data) struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; struct dma_pl330_desc *desc, *_dt; unsigned long flags; - bool power_down = false; spin_lock_irqsave(>lock, flags); @@ -2023,18 +2019,10 @@ static void pl330_tasklet(unsigned long data) /* Try to submit a req imm. next to the last completed cookie */ fill_queue(pch); - if (list_empty(>work_list)) { - spin_lock(>thread->dmac->lock); - _stop(pch->thread); - spin_unlock(>thread->dmac->lock); - power_down = true; - pch->active = false; - } else { - /* Make sure the PL330 Channel thread is active */ - spin_lock(>thread->dmac->lock); - _start(pch->thread); - spin_unlock(>thread->dmac-&g
[PATCH v7 3/4] dmaengine: pl330: Store pointer to slave device
Store the pointer to slave device, which requested our channel. It will be later used to implement runtime PM of PL330 DMA controller. Although DMA channels might be requested many times, each DMA peripheral channel is physically dedicated only for specific hardware, so there should be only one slave device for each channel. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> Reviewed-by: Ulf Hansson <ulf.hans...@linaro.org> Acked-by: Arnd Bergmann <a...@arndb.de> --- drivers/dma/pl330.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b6b2cc912380..c77a3494659c 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -450,6 +450,7 @@ struct dma_pl330_chan { /* for runtime pm tracking */ bool active; + struct device *slave; }; struct pl330_dmac { @@ -2093,6 +2094,14 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec, if (chan_id >= pl330->num_peripherals) return NULL; + if (!pl330->peripherals[chan_id].slave) { + pl330->peripherals[chan_id].slave = slave; + } else if (pl330->peripherals[chan_id].slave != slave) { + dev_err(pl330->ddma.dev, + "Can't use same channel with multiple slave devices!\n"); + return NULL; + } + return dma_get_slave_channel(>peripherals[chan_id].chan); } -- 1.9.1
Re: [PATCH] ARM: dts: Odroid XU4: fix USB3.0 ports
Hi Krzysztof, On 2017-01-25 08:55, Krzysztof Kozlowski wrote: On Wed, Jan 25, 2017 at 7:51 AM, Anand Moon <linux.am...@gmail.com> wrote: On 24 January 2017 at 19:18, Richard Genoud <richard.gen...@gmail.com> wrote: Since commit 2164a476205ccc ("usb: dwc3: set SUSPHY bit for all cores"), the USB ports on odroid-XU4 don't work anymore. Inserting an usb key (USB2.0) on the USB3.0 port result in: [ 64.488264] xhci-hcd xhci-hcd.2.auto: Port resume took longer than 2 msec, port status = 0xc400fe3 [ 74.568156] xhci-hcd xhci-hcd.2.auto: xHCI host not responding to stop endpoint command. [ 74.574806] xhci-hcd xhci-hcd.2.auto: Assuming host is dying, halting host. [ 74.601970] xhci-hcd xhci-hcd.2.auto: HC died; cleaning up [ 74.606276] usb 3-1: USB disconnect, device number 2 [ 74.613565] usb 4-1: USB disconnect, device number 2 [ 74.621208] usb usb3-port1: couldn't allocate usb_device NB: it's not related to USB2.0 devices, I get the same result with an USB3.0 device (SATA to USB3 for instance). NB2: it doesn't happen on an odriod-XU3 board, that doesn't have the realtek RTL8153 chip. If the lines: if (dwc->revision > DWC3_REVISION_194A) reg |= DWC3_GUSB3PIPECTL_SUSPHY; are commented out, the USB3.0 start working. For a full analyse: https://lkml.org/lkml/2017/1/18/678 Felipe suggested that suspend should be disabled temporarily while what's wrong with DCW3 is figured out. Tested on Odroid XU4 Suggested-by: Felipe Balbi <felipe.ba...@linux.intel.com> Tested-by: Richard Genoud <richard.gen...@gmail.com> Signed-off-by: Richard Genoud <richard.gen...@gmail.com> Cc: sta...@vger.kernel.org # 4.4+ Fixes: 2164a476205ccc ("usb: dwc3: set SUSPHY bit for all cores") --- arch/arm/boot/dts/exynos5422-odroidxu4.dts | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts index 2faf88627a48..f62dbd9b5ad3 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -43,6 +43,15 @@ status = "okay"; }; +_dwc3_0 { + /* +* without that, usb devices are not recognized when +* they are plugged. +* cf: https://lkml.org/lkml/2017/1/18/678 +*/ + snps,dis_u3_susphy_quirk; +}; + _dwc3_1 { dr_mode = "host"; }; -- Thanks for this patch. But could you consider moving this changes as below. https://lkml.org/lkml/2015/3/18/400 The patch above (and other DTS patches from the set) was not even sent to linux-samsung-soc nor to me... It is sad how easily one's work can disappear. Also, it is really worthless to solve the same problem twice. Well, they were sent about 2 years ago... and you were also working on this topic. ;) Cc Marek and Bartlomiej, Guys, do you want to continue with Robert's patch (linked above by Anand)? If yes, please take the ownership (Robert's address is not valid anymore). If not, I will take Richard's patch after resubmission. Take Richard's patch because it has a bit more details describing why such quirk is needed. Richard: in Roberts patch there is also a quirk for USB 2.0 mode (snps,dis_u2_susphy_quirk). Could you check if it really needed? Maybe it would make sense to set those quirks for both DWC3 controllers, as this issue with PHY suspend seems to be a Exynos specific thing. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH 4/7] arm64: dts: exynos: Add clocks to Exynos5433 LPASS module
Exynos5433 LPASS module requires some clocks for proper operation with power domain. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 57c7bbeb65a7..16072c1c3ed3 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1494,6 +1494,8 @@ audio-subsystem@1140 { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; samsung,pmu-syscon = <_system_controller>; #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH 6/7] mfd: exynos-lpass: Add support for clocks
Exynos LPASS requires some clocks to be enabled to make any access to its registers. This patch adds code for handling such clocks. For current set of registers it is enough to keep sfr0_ctrl clock enabled. Till now it worked only because those clocks were enabled by bootloader and driver probe() happened before they were disabled by clock core because of lack of users. Handling those clocks is also needed to make it possible to enable support for audio power domain. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- .../devicetree/bindings/mfd/samsung,exynos5433-lpass.txt | 6 ++ drivers/mfd/exynos-lpass.c | 10 ++ 2 files changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index a8deaee82c44..df664018c148 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -5,6 +5,10 @@ Required properties: - compatible : "samsung,exynos5433-lpass" - reg : should contain the LPASS top SFR region location and size + - clock-names : should contain following required clocks: "sfr0_ctrl" + - clocks : should contain clock specifiers of all clocks, which + input names have been specified in clock-names + property, in same order. - #address-cells : should be 1 - #size-cells : should be 1 - ranges : must be present @@ -24,6 +28,8 @@ Example: audio-subsystem { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 17915daa2e80..44d8ea1a978b 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -14,6 +14,7 @@ * only version 2 as published by the Free Software Foundation. */ +#include #include #include #include @@ -52,6 +53,7 @@ struct exynos_lpass { /* pointer to the LPASS TOP regmap */ struct regmap *top; + struct clk *sfr0_clk; }; static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) @@ -71,6 +73,8 @@ static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) static void exynos_lpass_enable(struct exynos_lpass *lpass) { + clk_prepare_enable(lpass->sfr0_clk); + /* Unmask SFR, DMA and I2S interrupt */ regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); @@ -88,6 +92,8 @@ static void exynos_lpass_disable(struct exynos_lpass *lpass) /* Mask any unmasked IP interrupt sources */ regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); + + clk_disable_unprepare(lpass->sfr0_clk); } static const struct regmap_config exynos_lpass_reg_conf = { @@ -114,6 +120,10 @@ static int exynos_lpass_probe(struct platform_device *pdev) if (IS_ERR(base_top)) return PTR_ERR(base_top); + lpass->sfr0_clk = clk_get(dev, "sfr0_ctrl"); + if (IS_ERR(lpass->sfr0_clk)) + return PTR_ERR(lpass->sfr0_clk); + lpass->top = regmap_init_mmio(dev, base_top, _lpass_reg_conf); if (IS_ERR(lpass->top)) { -- 1.9.1
[PATCH 0/7] Pad retentions support for Exynos5433
Hello, This patchset is a first step to add support for all power domains on Exynos5433 SoCs. This patchset contains patches for Exynos pin control driver and Exynos LPASS MFD driver, which are needed to make the platform ready for adding power domains support. Patches in this patchset depends on each other. They are order in such a way to make the changes bisectable. Patch #3 has runtime dependency on #1. Patch #5 has runtime dependency on #3. Patch #6 has runtime dependency on #4. This patchset also directly depends on the "Move pad retention control to Exynos pin controller driver" patchset: https://www.spinics.net/lists/arm-kernel/msg556074.html Patches have been generated on top of linux-next from 25th January 2017. This is a part of a larger task, which goal is to add support for power domains on Exynos5433 SoCs / TM2 boards. All patches needed to get it working have been pushed to the following git repo: https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.10-next-tm2-pd Best regards Marek Szyprowski Samsung R Institute Poland Patch summary: Marek Szyprowski (7): soc: samsung: pmu: Add dummy support for Exynos5433 SoC pinctrl: samsung: Ensure that pad retention is disabled on driver init pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs arm64: dts: exynos: Add clocks to Exynos5433 LPASS module mfd: exynos-lpass: Remove pad retention control mfd: exynos-lpass: Add support for clocks mfd: exynos-lpass: Add runtime PM support .../bindings/mfd/samsung,exynos5433-lpass.txt | 8 ++- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 + drivers/mfd/exynos-lpass.c | 35 ++-- drivers/pinctrl/samsung/pinctrl-exynos.c | 63 ++ drivers/soc/samsung/exynos-pmu.c | 4 +- include/linux/mfd/syscon/exynos5-pmu.h | 3 -- include/linux/soc/samsung/exynos-regs-pmu.h| 19 +++ 7 files changed, 110 insertions(+), 24 deletions(-) -- 1.9.1
[PATCH v2 3/8] pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs
This patch adds support for retention control for Exynos5433 SoCs. Three groups of pins has been defined for retention control: common shared group for ALIVE, CPIF, eSE, FINGER, IMEM, NFC, PERIC, TOUCH pin banks and separate control for FSYS and AUD pin banks, for which PMU retention registers match whole banks. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/pinctrl/samsung/pinctrl-exynos.c| 58 + include/linux/soc/samsung/exynos-regs-pmu.h | 16 2 files changed, 74 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index fa3802970570..7b0e6cc35e04 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -1551,6 +1551,54 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), }; +/* PMU pin retention groups registers for Exynos5433 (without audio & fsys) */ +static const u32 exynos5433_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_TOP_OPTION, + EXYNOS5433_PAD_RETENTION_UART_OPTION, + EXYNOS5433_PAD_RETENTION_EBIA_OPTION, + EXYNOS5433_PAD_RETENTION_EBIB_OPTION, + EXYNOS5433_PAD_RETENTION_SPI_OPTION, + EXYNOS5433_PAD_RETENTION_MIF_OPTION, + EXYNOS5433_PAD_RETENTION_USBXTI_OPTION, + EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION, + EXYNOS5433_PAD_RETENTION_UFS_OPTION, + EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION, +}; + +static const struct samsung_retention_data exynos5433_retention_data __initconst = { + .regs= exynos5433_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .refcnt = _shared_retention_refcnt, + .init= exynos_retention_init, +}; + +/* PMU retention control for audio pins can be tied to audio pin bank */ +static const u32 exynos5433_audio_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_AUD_OPTION, +}; + +static const struct samsung_retention_data exynos5433_audio_retention_data __initconst = { + .regs= exynos5433_audio_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_audio_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .init= exynos_retention_init, +}; + +/* PMU retention control for mmc pins can be tied to fsys pin bank */ +static const u32 exynos5433_fsys_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_MMC0_OPTION, + EXYNOS5433_PAD_RETENTION_MMC1_OPTION, + EXYNOS5433_PAD_RETENTION_MMC2_OPTION, +}; + +static const struct samsung_retention_data exynos5433_fsys_retention_data __initconst = { + .regs= exynos5433_fsys_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_fsys_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .init= exynos_retention_init, +}; + /* * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes * ten gpio/pin-mux/pinconfig controllers. @@ -1564,6 +1612,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, .nr_ext_resources = 1, + .retention_data = _retention_data, }, { /* pin-controller instance 1 data */ .pin_banks = exynos5433_pin_banks1, @@ -1571,6 +1620,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _audio_retention_data, }, { /* pin-controller instance 2 data */ .pin_banks = exynos5433_pin_banks2, @@ -1578,6 +1628,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _retention_data, }, { /* pin-controller instance 3 data */ .pin_banks = exynos5433_pin_banks3, @@ -1585,6 +1636,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) .eint_gpio_init = exynos_eint_gpio_init, .suspend= exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = _retention_data, }, { /* pin-controller instance 4 data */ .pin_banks = exynos5433_pin_banks4, @@ -1592,6 +1644,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
[PATCH v2 4/8] arm64: dts: exynos: Add clocks to Exynos5433 LPASS module
Exynos5433 LPASS module requires some clocks for proper operation with power domain. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 57c7bbeb65a7..16072c1c3ed3 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1494,6 +1494,8 @@ audio-subsystem@1140 { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; samsung,pmu-syscon = <_system_controller>; #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH v2 0/8] Pad retentions support for Exynos5433
Hello, This patchset is a first step to add support for all power domains on Exynos5433 SoCs. This patchset contains patches for Exynos pin control driver and Exynos LPASS MFD driver, which are needed to make the platform ready for adding power domains support. Patches in this patchset depends on each other. They are order in such a way to make the changes bisectable. Patch #3 has runtime dependency on #1. Patch #5 has runtime dependency on #3. Patch #6 has runtime dependency on #4. This patchset also directly depends on the "Move pad retention control to Exynos pin controller driver" patchset: https://www.spinics.net/lists/arm-kernel/msg556074.html Patches have been generated on top of linux-next from 25th January 2017. This is a part of a larger task, which goal is to add support for power domains on Exynos5433 SoCs / TM2 boards. All patches needed to get it working have been pushed to the following git repo: https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.10-next-tm2-pd Best regards Marek Szyprowski Samsung R Institute Poland Changelog: v2: - fixed issues pointed by Krzysztof Kozlowski: 1. added more checks to Exynos PMU driver for NULL drvdata 2. reused EXYNOS_WAKEUP_FROM_LOWPWR in retention data for Exynos5433 3. converted lpass driver to devm_clk_get 4. added missing ->remove callback to lpass driver v1: https://lkml.org/lkml/2017/1/25/214 - initial version Patch summary: Marek Szyprowski (8): soc: samsung: pmu: Add dummy support for Exynos5433 SoC pinctrl: samsung: Ensure that pad retention is disabled on driver init pinctrl: samsung: Add support for pad retention control for Exynos5433 SoCs arm64: dts: exynos: Add clocks to Exynos5433 LPASS module mfd: exynos-lpass: Remove pad retention control mfd: exynos-lpass: Add support for clocks mfd: exynos-lpass: Add missing remove() function mfd: exynos-lpass: Add runtime PM support .../bindings/mfd/samsung,exynos5433-lpass.txt | 8 ++- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 + drivers/mfd/exynos-lpass.c | 48 ++--- drivers/pinctrl/samsung/pinctrl-exynos.c | 63 ++ drivers/soc/samsung/exynos-pmu.c | 6 ++- include/linux/mfd/syscon/exynos5-pmu.h | 3 -- include/linux/soc/samsung/exynos-regs-pmu.h| 16 ++ 7 files changed, 121 insertions(+), 25 deletions(-) -- 1.9.1
[PATCH v2 7/8] mfd: exynos-lpass: Add missing remove() function
Disable device on driver remove and release allocated regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/mfd/exynos-lpass.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index be264988bdc9..9dbbedad916f 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -137,6 +137,16 @@ static int exynos_lpass_probe(struct platform_device *pdev) return of_platform_populate(dev->of_node, NULL, NULL, dev); } +static int exynos_lpass_remove(struct platform_device *pdev) +{ + struct exynos_lpass *lpass = platform_get_drvdata(pdev); + + exynos_lpass_disable(lpass); + regmap_exit(lpass->top); + + return 0; +} + static int __maybe_unused exynos_lpass_suspend(struct device *dev) { struct exynos_lpass *lpass = dev_get_drvdata(dev); @@ -171,6 +181,7 @@ static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend, .of_match_table = exynos_lpass_of_match, }, .probe = exynos_lpass_probe, + .remove = exynos_lpass_remove, }; module_platform_driver(exynos_lpass_driver); -- 1.9.1
[PATCH v2 5/8] mfd: exynos-lpass: Remove pad retention control
Pad retention should be controlled from pin control driver, so remove it from Exynos LPASS driver. After this change, no more access to PMU regmap is needed, so remove also the code for handling PMU regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Acked-by: Krzysztof Kozlowski <k...@kernel.org> --- .../bindings/mfd/samsung,exynos5433-lpass.txt | 2 -- drivers/mfd/exynos-lpass.c | 17 - include/linux/mfd/syscon/exynos5-pmu.h | 3 --- 3 files changed, 22 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index c110e118b79f..a8deaee82c44 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -5,7 +5,6 @@ Required properties: - compatible : "samsung,exynos5433-lpass" - reg : should contain the LPASS top SFR region location and size - - samsung,pmu-syscon : the phandle to the Power Management Unit node - #address-cells : should be 1 - #size-cells : should be 1 - ranges : must be present @@ -25,7 +24,6 @@ Example: audio-subsystem { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; - samsung,pmu-syscon = <_system_controller>; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 2e064fb8826f..17915daa2e80 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -51,8 +50,6 @@ #define LPASS_INTR_SFRBIT(0) struct exynos_lpass { - /* pointer to the Power Management Unit regmap */ - struct regmap *pmu; /* pointer to the LPASS TOP regmap */ struct regmap *top; }; @@ -81,10 +78,6 @@ static void exynos_lpass_enable(struct exynos_lpass *lpass) regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); - /* Activate related PADs from retention state */ - regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, -EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR); - exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_MEM_SW_RESET); @@ -95,9 +88,6 @@ static void exynos_lpass_disable(struct exynos_lpass *lpass) /* Mask any unmasked IP interrupt sources */ regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); - - /* Deactivate related PADs from retention state */ - regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, 0); } static const struct regmap_config exynos_lpass_reg_conf = { @@ -131,13 +121,6 @@ static int exynos_lpass_probe(struct platform_device *pdev) return PTR_ERR(lpass->top); } - lpass->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,pmu-syscon"); - if (IS_ERR(lpass->pmu)) { - dev_err(dev, "Failed to lookup PMU regmap\n"); - return PTR_ERR(lpass->pmu); - } - platform_set_drvdata(pdev, lpass); exynos_lpass_enable(lpass); diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h index c28ff21ca4d2..0622ae86f9db 100644 --- a/include/linux/mfd/syscon/exynos5-pmu.h +++ b/include/linux/mfd/syscon/exynos5-pmu.h @@ -46,7 +46,4 @@ #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) #define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) -#define EXYNOS5433_PAD_RETENTION_AUD_OPTION(0x3028) -#define EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR BIT(28) - #endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */ -- 1.9.1
Re: [PATCH 1/2] soc: samsung: pmu: Remove unused and duplicated defines
Hi Krzysztof, On 2017-01-25 20:34, Krzysztof Kozlowski wrote: The exynos-regs-pmu.h was never a complete list of PMU registers. It contained a lot of holes for registers which are not used. However, a lot of unused defines came with porting the code from vendor kernel. Few of defines were also duplicated. Remove them so the file will be slightly smaller. Signed-off-by: Krzysztof Kozlowski <k...@kernel.org> Thanks for the cleanup! If you are touching this, you may also want to unify multiple headers for the Exynos PMU regs: include/linux/soc/samsung/exynos-regs-pmu.h linux/mfd/syscon/exynos4-pmu.h linux/mfd/syscon/exynos5-pmu.h > [...] Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 4/7] arm64: dts: exynos: Add clocks to Exynos5433 LPASS module
Hi Krzysztof, On 2017-01-25 20:50, Krzysztof Kozlowski wrote: On Wed, Jan 25, 2017 at 12:50:28PM +0100, Marek Szyprowski wrote: Exynos5433 LPASS module requires some clocks for proper operation with power domain. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 57c7bbeb65a7..16072c1c3ed3 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1494,6 +1494,8 @@ audio-subsystem@1140 { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; You wrote that 6/7 depends on this. I prefer not to take DTS changes if the corresponding user (driver) is still under discussion because the bindings might change. I'll take it when bindings got acked or accepted. Well, audio support in 4.9 is still not functional due to missing other patches to ALSA SoC, so nothing will break as for now if we manage to get this into v4.10. BTW, the 6/7 is a quite reasonable ABI break, but for the sake of documentation - why you did not continue with the patch for marking bidings as experimental/under-development? Because I had no time to list all breaks, what was requested by Rob. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 4/7] arm64: dts: exynos: Add clocks to Exynos5433 LPASS module
Hi Krzysztof, On 2017-01-26 09:40, Krzysztof Kozlowski wrote: On Thu, Jan 26, 2017 at 9:18 AM, Marek Szyprowski <m.szyprow...@samsung.com> wrote: On 2017-01-25 20:50, Krzysztof Kozlowski wrote: On Wed, Jan 25, 2017 at 12:50:28PM +0100, Marek Szyprowski wrote: Exynos5433 LPASS module requires some clocks for proper operation with power domain. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 57c7bbeb65a7..16072c1c3ed3 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1494,6 +1494,8 @@ audio-subsystem@1140 { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; You wrote that 6/7 depends on this. I prefer not to take DTS changes if the corresponding user (driver) is still under discussion because the bindings might change. I'll take it when bindings got acked or accepted. Well, audio support in 4.9 is still not functional due to missing other patches to ALSA SoC, so nothing will break as for now if we manage to get this into v4.10. Get this into v4.10? So this needs some additional explanation in the commit message why this is a fix. Probably one more sentence would be enough. Or did you mean v4.11? Yes, I meant v4.11. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH v2 8/8] mfd: exynos-lpass: Add runtime PM support
Convert exisitng lpass-suspend/resume callbacks into runtime PM callbacks. This way Exynos LPASS driver will be ready for use with power domains enabled. LPASS will be runtime resumed/suspended as a result of its child devices runtime PM transitions. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Acked-by: Krzysztof Kozlowski <k...@kernel.org> --- drivers/mfd/exynos-lpass.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 9dbbedad916f..6d735e22acda 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -132,6 +133,8 @@ static int exynos_lpass_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, lpass); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); exynos_lpass_enable(lpass); return of_platform_populate(dev->of_node, NULL, NULL, dev); @@ -141,7 +144,9 @@ static int exynos_lpass_remove(struct platform_device *pdev) { struct exynos_lpass *lpass = platform_get_drvdata(pdev); - exynos_lpass_disable(lpass); + pm_runtime_disable(>dev); + if (!pm_runtime_status_suspended(>dev)) + exynos_lpass_disable(lpass); regmap_exit(lpass->top); return 0; @@ -165,8 +170,11 @@ static int __maybe_unused exynos_lpass_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend, - exynos_lpass_resume); +static const struct dev_pm_ops lpass_pm_ops = { + SET_RUNTIME_PM_OPS(exynos_lpass_suspend, exynos_lpass_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, +pm_runtime_force_resume) +}; static const struct of_device_id exynos_lpass_of_match[] = { { .compatible = "samsung,exynos5433-lpass" }, -- 1.9.1
[PATCH v2 6/8] mfd: exynos-lpass: Add support for clocks
Exynos LPASS requires some clocks to be enabled to make any access to its registers. This patch adds code for handling such clocks. For current set of registers it is enough to keep sfr0_ctrl clock enabled. Till now it worked only because those clocks were enabled by bootloader and driver probe() happened before they were disabled by clock core because of lack of users. Handling those clocks is also needed to make it possible to enable support for audio power domain. This patch requires adding sfr0_ctrl clock to device tree. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- .../devicetree/bindings/mfd/samsung,exynos5433-lpass.txt | 6 ++ drivers/mfd/exynos-lpass.c | 10 ++ 2 files changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index a8deaee82c44..df664018c148 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -5,6 +5,10 @@ Required properties: - compatible : "samsung,exynos5433-lpass" - reg : should contain the LPASS top SFR region location and size + - clock-names : should contain following required clocks: "sfr0_ctrl" + - clocks : should contain clock specifiers of all clocks, which + input names have been specified in clock-names + property, in same order. - #address-cells : should be 1 - #size-cells : should be 1 - ranges : must be present @@ -24,6 +28,8 @@ Example: audio-subsystem { compatible = "samsung,exynos5433-lpass"; reg = <0x1140 0x100>, <0x1150 0x08>; + clocks = <_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 17915daa2e80..be264988bdc9 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -14,6 +14,7 @@ * only version 2 as published by the Free Software Foundation. */ +#include #include #include #include @@ -52,6 +53,7 @@ struct exynos_lpass { /* pointer to the LPASS TOP regmap */ struct regmap *top; + struct clk *sfr0_clk; }; static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) @@ -71,6 +73,8 @@ static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) static void exynos_lpass_enable(struct exynos_lpass *lpass) { + clk_prepare_enable(lpass->sfr0_clk); + /* Unmask SFR, DMA and I2S interrupt */ regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); @@ -88,6 +92,8 @@ static void exynos_lpass_disable(struct exynos_lpass *lpass) /* Mask any unmasked IP interrupt sources */ regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); + + clk_disable_unprepare(lpass->sfr0_clk); } static const struct regmap_config exynos_lpass_reg_conf = { @@ -114,6 +120,10 @@ static int exynos_lpass_probe(struct platform_device *pdev) if (IS_ERR(base_top)) return PTR_ERR(base_top); + lpass->sfr0_clk = devm_clk_get(dev, "sfr0_ctrl"); + if (IS_ERR(lpass->sfr0_clk)) + return PTR_ERR(lpass->sfr0_clk); + lpass->top = regmap_init_mmio(dev, base_top, _lpass_reg_conf); if (IS_ERR(lpass->top)) { -- 1.9.1
[PATCH v2 2/8] pinctrl: samsung: Ensure that pad retention is disabled on driver init
When pin controller device is a part of power domain, there is no guarantee that the power domain was not turned off and then on during boot process before probing of the pin control driver. If it happened, then pin control driver should ensure that pad retention is turned off during its probe call. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Krzysztof Kozlowski <k...@kernel.org> --- drivers/pinctrl/samsung/pinctrl-exynos.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 63e51b56a22a..fa3802970570 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -777,6 +777,7 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) { struct samsung_retention_ctrl *ctrl; struct regmap *pmu_regs; + int i; ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL); if (!ctrl) @@ -794,6 +795,10 @@ static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) ctrl->enable = exynos_retention_enable; ctrl->disable = exynos_retention_disable; + /* Ensure that retention is disabled on driver init */ + for (i = 0; i < ctrl->nr_regs; i++) + regmap_write(pmu_regs, ctrl->regs[i], ctrl->value); + return ctrl; } -- 1.9.1
[PATCH v2 1/8] soc: samsung: pmu: Add dummy support for Exynos5433 SoC
Add compatible for Exynos5433 SoC, so the driver will bind and let other drivers to use PMU regmap. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/soc/samsung/exynos-pmu.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 813df6e7292d..56d9244ff981 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -44,7 +44,7 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) unsigned int i; const struct exynos_pmu_data *pmu_data; - if (!pmu_context) + if (!pmu_context || !pmu_context->pmu_data) return; pmu_data = pmu_context->pmu_data; @@ -90,6 +90,8 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) }, { .compatible = "samsung,exynos5420-pmu", .data = _pmu_data, + }, { + .compatible = "samsung,exynos5433-pmu", }, { /*sentinel*/ }, }; @@ -122,7 +124,7 @@ static int exynos_pmu_probe(struct platform_device *pdev) pmu_context->dev = dev; pmu_context->pmu_data = of_device_get_match_data(dev); - if (pmu_context->pmu_data->pmu_init) + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init) pmu_context->pmu_data->pmu_init(); platform_set_drvdata(pdev, pmu_context); -- 1.9.1
Re: [GIT PULL] soc: samsung: Drivers for v4.11
Hi Linus, On 2017-01-26 10:13, Linus Walleij wrote: On Fri, Jan 20, 2017 at 7:13 PM, Krzysztof Kozlowski <k...@kernel.org> wrote: Few changes in Exynos PMU driver including one that is needed by pinctrl driver for runtime PM. We want to move forward with the RPM for our drivers while keeping still DT ABI. This tag is also for Linus Walleij to pull - base for pinctrl changes. Do I need it? I.e. will my branch not compile without this, or is this just a runtime problem? "[PATCH v3 11/13] pinctrl: samsung: Move retention control from mach-exynos to the pinctrl driver" has compile time dependency on the changes included in that tag. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 0/8] Pad retentions support for Exynos5433
Hi Linus, On 2017-01-26 10:50, Linus Walleij wrote: On Thu, Jan 26, 2017 at 9:33 AM, Marek Szyprowski <m.szyprow...@samsung.com> wrote: Patches in this patchset depends on each other. They are order in such a way to make the changes bisectable. Patch #3 has runtime dependency on #1. Patch #5 has runtime dependency on #3. Patch #6 has runtime dependency on #4. This patchset also directly depends on the "Move pad retention control to Exynos pin controller driver" patchset: https://www.spinics.net/lists/arm-kernel/msg556074.html Do we *have* to merge it runtime-bisectably? I'm asking because we need a huge immutable branch (I guess in the MFD subsystem) to deal with that. It'd be great if I could just apply the pinctrl patches in isolation, then Lee applies the MFD patches in isolation, everything compiles in isolation but maye just work once both pinctrl and MFD are merged upstream, as in linux-next or Torvalds' tree. I always thought that it is good to prepare patches in such a way that they don't break runtime bisectability, especially if this is just a matter of applying a few patches via the other tree. In this case it will work fine if MFD patches gets applied with Lee Jones ack via pinctrl tree (I remember that MFD changes were often applied via the other trees in the past). That is one of the reasons why using a system-agnostic syscon regmap lookup is so good, BTW. I've just explained my rationale about the regmap lookup in the separate mail. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH] dma-buf: add support for compat ioctl
Add compat ioctl support to dma-buf. This lets one to use DMA_BUF_IOCTL_SYNC ioctl from 32bit application on 64bit kernel. Data structures for both 32 and 64bit modes are same, so there is no need for additional translation layer. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/dma-buf/dma-buf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 718f832a5c71..0007b792827b 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -325,6 +325,9 @@ static long dma_buf_ioctl(struct file *file, .llseek = dma_buf_llseek, .poll = dma_buf_poll, .unlocked_ioctl = dma_buf_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = dma_buf_ioctl, +#endif }; /* -- 1.9.1
Re: [PATCH] dma-buf: add support for compat ioctl
Dear All, On 2017-02-21 15:37, Marek Szyprowski wrote: Hi Christian, On 2017-02-21 14:59, Christian König wrote: Am 21.02.2017 um 14:21 schrieb Marek Szyprowski: Add compat ioctl support to dma-buf. This lets one to use DMA_BUF_IOCTL_SYNC ioctl from 32bit application on 64bit kernel. Data structures for both 32 and 64bit modes are same, so there is no need for additional translation layer. Well I might be wrong, but IIRC compat_ioctl was just optional and if not specified unlocked_ioctl was called instead. If that is true your patch wouldn't have any effect at all. Well, then why I got -ENOTTY in the 32bit test app for this ioctl on 64bit ARM64 kernel without this patch? I've checked in fs/compat_ioctl.c, I see no fallback in COMPAT_SYSCALL_DEFINE3, so one has to provide compat_ioctl callback to have ioctl working with 32bit apps. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH] dma-buf: add support for compat ioctl
Hi Christian, On 2017-02-21 14:59, Christian König wrote: Am 21.02.2017 um 14:21 schrieb Marek Szyprowski: Add compat ioctl support to dma-buf. This lets one to use DMA_BUF_IOCTL_SYNC ioctl from 32bit application on 64bit kernel. Data structures for both 32 and 64bit modes are same, so there is no need for additional translation layer. Well I might be wrong, but IIRC compat_ioctl was just optional and if not specified unlocked_ioctl was called instead. If that is true your patch wouldn't have any effect at all. Well, then why I got -ENOTTY in the 32bit test app for this ioctl on 64bit ARM64 kernel without this patch? Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH v2] iommu: iova: Consolidate code for adding new node to iovad domain rbtree
This patch consolidates almost the same code used in iova_insert_rbtree() and __alloc_and_insert_iova_range() functions. While touching this code, replace BUG() with WARN_ON(1) to avoid taking down the whole system in case of corrupted iova tree or incorrect calls. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- v2: - replaced BUG() with WARN_ON(1) as suggested by Robin Murphy v1: - initial version --- drivers/iommu/iova.c | 87 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index b7268a14184f..e80a4105ac2a 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -100,6 +100,34 @@ static unsigned long iova_rcache_get(struct iova_domain *iovad, } } +/* Insert the iova into domain rbtree by holding writer lock */ +static void +iova_insert_rbtree(struct rb_root *root, struct iova *iova, + struct rb_node *start) +{ + struct rb_node **new, *parent = NULL; + + new = (start) ? : &(root->rb_node); + /* Figure out where to put new node */ + while (*new) { + struct iova *this = rb_entry(*new, struct iova, node); + + parent = *new; + + if (iova->pfn_lo < this->pfn_lo) + new = &((*new)->rb_left); + else if (iova->pfn_lo > this->pfn_lo) + new = &((*new)->rb_right); + else { + WARN_ON(1); /* this should not happen */ + return; + } + } + /* Add new node and rebalance tree. */ + rb_link_node(>node, parent, new); + rb_insert_color(>node, root); +} + /* * Computes the padding size required, to make the start address * naturally aligned on the power-of-two order of its size @@ -157,35 +185,8 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, new->pfn_lo = limit_pfn - (size + pad_size) + 1; new->pfn_hi = new->pfn_lo + size - 1; - /* Insert the new_iova into domain rbtree by holding writer lock */ - /* Add new node and rebalance tree. */ - { - struct rb_node **entry, *parent = NULL; - - /* If we have 'prev', it's a valid place to start the - insertion. Otherwise, start from the root. */ - if (prev) - entry = - else - entry = >rbroot.rb_node; - - /* Figure out where to put new node */ - while (*entry) { - struct iova *this = rb_entry(*entry, struct iova, node); - parent = *entry; - - if (new->pfn_lo < this->pfn_lo) - entry = &((*entry)->rb_left); - else if (new->pfn_lo > this->pfn_lo) - entry = &((*entry)->rb_right); - else - BUG(); /* this should not happen */ - } - - /* Add new node and rebalance tree. */ - rb_link_node(>node, parent, entry); - rb_insert_color(>node, >rbroot); - } + /* If we have 'prev', it's a valid place to start the insertion. */ + iova_insert_rbtree(>rbroot, new, prev); __cached_rbnode_insert_update(iovad, saved_pfn, new); spin_unlock_irqrestore(>iova_rbtree_lock, flags); @@ -194,28 +195,6 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, return 0; } -static void -iova_insert_rbtree(struct rb_root *root, struct iova *iova) -{ - struct rb_node **new = &(root->rb_node), *parent = NULL; - /* Figure out where to put new node */ - while (*new) { - struct iova *this = rb_entry(*new, struct iova, node); - - parent = *new; - - if (iova->pfn_lo < this->pfn_lo) - new = &((*new)->rb_left); - else if (iova->pfn_lo > this->pfn_lo) - new = &((*new)->rb_right); - else - BUG(); /* this should not happen */ - } - /* Add new node and rebalance tree. */ - rb_link_node(>node, parent, new); - rb_insert_color(>node, root); -} - static struct kmem_cache *iova_cache; static unsigned int iova_cache_users; static DEFINE_MUTEX(iova_cache_mutex); @@ -505,7 +484,7 @@ void put_iova_domain(struct iova_domain *iovad) iova = alloc_and_init_iova(pfn_lo, pfn_hi); if (iova) - iova_insert_rbtree(>rbroot, iova); + iova_insert_rbtree(>rbroot, iova, NULL); return iova; } @@ -612,11 +591,11 @@ struct iova * rb_erase(>node, >rbroot);
[PATCH] iommu: iova: Consolidate code for adding new node to iovad domain rbtree
This patch consolidates almost the same code used in iova_insert_rbtree() and __alloc_and_insert_iova_range() functions. There is no functional change. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/iommu/iova.c | 85 +++- 1 file changed, 31 insertions(+), 54 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index b7268a14184f..32b9c2fb37b6 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -100,6 +100,32 @@ static unsigned long iova_rcache_get(struct iova_domain *iovad, } } +/* Insert the iova into domain rbtree by holding writer lock */ +static void +iova_insert_rbtree(struct rb_root *root, struct iova *iova, + struct rb_node *start) +{ + struct rb_node **new, *parent = NULL; + + new = (start) ? : &(root->rb_node); + /* Figure out where to put new node */ + while (*new) { + struct iova *this = rb_entry(*new, struct iova, node); + + parent = *new; + + if (iova->pfn_lo < this->pfn_lo) + new = &((*new)->rb_left); + else if (iova->pfn_lo > this->pfn_lo) + new = &((*new)->rb_right); + else + BUG(); /* this should not happen */ + } + /* Add new node and rebalance tree. */ + rb_link_node(>node, parent, new); + rb_insert_color(>node, root); +} + /* * Computes the padding size required, to make the start address * naturally aligned on the power-of-two order of its size @@ -157,35 +183,8 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, new->pfn_lo = limit_pfn - (size + pad_size) + 1; new->pfn_hi = new->pfn_lo + size - 1; - /* Insert the new_iova into domain rbtree by holding writer lock */ - /* Add new node and rebalance tree. */ - { - struct rb_node **entry, *parent = NULL; - - /* If we have 'prev', it's a valid place to start the - insertion. Otherwise, start from the root. */ - if (prev) - entry = - else - entry = >rbroot.rb_node; - - /* Figure out where to put new node */ - while (*entry) { - struct iova *this = rb_entry(*entry, struct iova, node); - parent = *entry; - - if (new->pfn_lo < this->pfn_lo) - entry = &((*entry)->rb_left); - else if (new->pfn_lo > this->pfn_lo) - entry = &((*entry)->rb_right); - else - BUG(); /* this should not happen */ - } - - /* Add new node and rebalance tree. */ - rb_link_node(>node, parent, entry); - rb_insert_color(>node, >rbroot); - } + /* If we have 'prev', it's a valid place to start the insertion. */ + iova_insert_rbtree(>rbroot, new, prev); __cached_rbnode_insert_update(iovad, saved_pfn, new); spin_unlock_irqrestore(>iova_rbtree_lock, flags); @@ -194,28 +193,6 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, return 0; } -static void -iova_insert_rbtree(struct rb_root *root, struct iova *iova) -{ - struct rb_node **new = &(root->rb_node), *parent = NULL; - /* Figure out where to put new node */ - while (*new) { - struct iova *this = rb_entry(*new, struct iova, node); - - parent = *new; - - if (iova->pfn_lo < this->pfn_lo) - new = &((*new)->rb_left); - else if (iova->pfn_lo > this->pfn_lo) - new = &((*new)->rb_right); - else - BUG(); /* this should not happen */ - } - /* Add new node and rebalance tree. */ - rb_link_node(>node, parent, new); - rb_insert_color(>node, root); -} - static struct kmem_cache *iova_cache; static unsigned int iova_cache_users; static DEFINE_MUTEX(iova_cache_mutex); @@ -505,7 +482,7 @@ void put_iova_domain(struct iova_domain *iovad) iova = alloc_and_init_iova(pfn_lo, pfn_hi); if (iova) - iova_insert_rbtree(>rbroot, iova); + iova_insert_rbtree(>rbroot, iova, NULL); return iova; } @@ -612,11 +589,11 @@ struct iova * rb_erase(>node, >rbroot); if (prev) { - iova_insert_rbtree(>rbroot, prev); + iova_insert_rbtree(>rbroot, prev, NULL); iova->pfn_lo = pfn_lo; } if (next) { - iova_insert_rbtree(>rbroot, next); + iova_insert_rbtree(>rbroot, next, NULL); iova->pfn_hi = pfn_hi; } spin_unlock_irqrestore(>iova_rbtree_lock, flags); -- 1.9.1
Re: [PATCH v8 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
Hi Vinod, On 2017-02-13 16:47, Vinod Koul wrote: On Mon, Feb 13, 2017 at 04:32:32PM +0100, Ulf Hansson wrote: [...] Although, I don't know of other examples, besides the runtime PM use case, where non-atomic channel prepare/unprepare would make sense. Do you? The primary ask for that has been to enable runtime_pm for drivers. It's not a new ask, but we somehow haven't gotten around to do it. Okay, I see. As I said earlier, if we want to solve that problem a better idea is to actually split the prepare as we discussed in [1] This way we can get a non atomic descriptor allocate/prepare and release. Yes we need to redesign the APIs to solve this, but if you guys are up for it, I think we can do it and avoid any further round abouts :) Adding/re-designing dma APIs is a viable option to solve the runtime PM case. Changes would be needed for all related dma client drivers as well, although if that's what we need to do - let's do it. Yes, but do bear in mind that some cases do need atomic prepare. The primary cases for DMA had that in mind and also submitting next transaction from the callback (tasklet) context, so that won't go away. It would help in other cases where clients know that they will not be in atomic context so we provide additional non-atomic "allocation" followed by prepare, so that drivers can split the work among these and people can do runtime_pm and other things.. That for sharing the details. It seems like some dma expert really need to be heavily involved if we ever are going to complete this work. :-) Sure, I will help out :) If anyone of you are in Portland next week, then we can discuss these f2f. I will try taking a stab at the new API design next week. I'm not going to Portland, but I hope that you will have a fruitful discussion there. [...] Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v7 2/4] dmaengine: Forward slave device pointer to of_xlate callback
Hi Vinod, On 2017-02-09 05:11, Vinod Koul wrote: On Thu, Jan 26, 2017 at 03:43:05PM +0100, Marek Szyprowski wrote: On 2017-01-25 14:12, Lars-Peter Clausen wrote: On 01/25/2017 11:28 AM, Marek Szyprowski wrote: Add pointer to slave device to of_dma_xlate to let DMA engine driver to know which slave device is using given DMA channel. This will be later used to implement non-irq-safe runtime PM for DMA engine driver. of_dma_xlate() is used to translate from a OF phandle and a specifier to a DMA channel. On one hand this does not necessarily mean that the channel is actually going to be used by the slave that called the xlate function. Modifying the driver state when a lookup of the channel is done is a layering violation. And this approach is also missing a way to disassociate a slave from a DMA channel, e.g. when it is no longer used. On the other hand there are other mechanisms to translate between some kind of firmware handle to a DMA channel which are completely ignored here. So this approach does not work. This is something that needs to be done at the dmaengine level, not a the firmware resource translation level. And it needs a matching method that is called when the channel is disassociated >from a device, when the device no longer uses the DMA channel. Frankly I agree that of_dma_xlate() should only return the requested channel to the dmaengine core and do not do any modification in the the driver state. True.. However the current dma engine design and implementation breaks this rule. Please check the drivers - how do they implement of_xlate callback. They usually call dma_get_any_slave_channel, dma_get_slave_channel or __dma_request_channel there, which in turn calls dma_chan_get, which then calls back to device_alloc_chan_resources callback. Some of the drivers also do a hardware configuration or other resource allocation in of_xlate. This is a bit messy design and leave no place in the core to set slave device before device_alloc_chan_resources callback, where one would expect to have it already set. We shouldn't be doing much at this stage. We operate on a channel, so the channel is returned to the client. We need to do these HW configurations when the channel has to be prepred for a txn. IMHO, any HW configurations should be done in alloc_chan_resources callback and it would be best if a pointer of slave device will come as a parameter to it. The best place to add new calls to the dmaengine drivers to set slave device would be just before device_alloc_chan_resources(), what in turn means that the current dmaengine core should do in dma_chan_get(). This would require to forward the slave device pointer via even more layers including the of_xlate callback too. IMHO this is not worth the effort. DMA engine core and API definitely needs some cleanup. During such cleanup the slave device pointer might be moved out of xlate into separate callback when the core gets ready for such operation. Yes agreed on that, plus the runtime handling needs to be built in, right now the APIs dont work well with it, we disucssed these during the KS and this goes without saying, patches are welcome :) Okay, so what is the conclusion? Do you want me to do the whole rework of dma engine core to get this runtime pm patchset for pl330 merged??? Is there any roadmap for this rework prepared, so I can at least take a look at the amount of work needed to be done? I'm rather new to dma engine framework and I only wanted to fix pl330 driver not to block turning off the power domain on Exynos5422/5433 SoCs. I can also check again if there is any other way to find the slave device in alloc_chan_resources, like for example scanning the device tree for phandles, to avoid changing dmaengine core as this turned out to be too problematic before one will do the proper dma engine core rework. > ... Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v8 1/3] dmaengine: Add new device_{set,release}_slave callbacks
Hi Vinod, On 2017-02-13 02:42, Vinod Koul wrote: On Fri, Feb 10, 2017 at 01:07:41PM +0100, Marek Szyprowski wrote: Hi Vinod, On 2017-02-10 05:34, Vinod Koul wrote: On Thu, Feb 09, 2017 at 03:22:49PM +0100, Marek Szyprowski wrote: Add two new callbacks to DMA engine device. They will used to provide access to slave device (the device which requested given DMA channel) You mean access to client devices? Yes. It looks that I was confused by the code, where the term 'slave' appears a few times. 'Client' is a bit more appropriate then. for DMA engine driver. Access to slave device might be useful for example for implementing advanced runtime power management. DMA slave channels are exclusive, so only one slave device can be set for a given DMA slave channel. That is not a right assumption and my worry here. With virt-dma we don't really assume a hardware channel and exclusive. Certain implementation may do that but from framework we cannot assume that. Okay, I came to such conclusion basing one the dma engine code, but maybe I missed something. However in such case such callback will be called for each client device and it will be up to the driver to handle that. Thats right, but the assumption that we will have once physical channel maynot be true. device_set_slave() will be called after the device_alloc_chan_resources() and device_release_slave() before the device_free_chan_resources(). Okay, I had to relook at the series to get around this part. Sorry but we can't call it set_slave, it is actually set_client/consumer That's okay, the name of the callbacks should be changed. In our context slaves means dmaengine slave devices aka provider. Client would be the consumer and not slave. I'm a new to the DMA engine framework, I'm sorry for using wrong terms. That's fine :-) we all learn incrementally. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/dma/dmaengine.c | 27 --- include/linux/dmaengine.h | 10 ++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 24e0221fd66d..5b7089d8be4d 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -705,6 +705,7 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) { struct dma_device *d, *_d; struct dma_chan *chan = NULL; + int ret; /* If device-tree is present get slave info from here */ if (dev->of_node) @@ -715,8 +716,9 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) chan = acpi_dma_request_slave_chan_by_name(dev, name); if (chan) { - /* Valid channel found or requester need to be deferred */ - if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER) + if (!IS_ERR(chan)) + goto found; + if (PTR_ERR(chan) == -EPROBE_DEFER) return chan; } @@ -738,7 +740,21 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) } mutex_unlock(_list_mutex); - return chan ? chan : ERR_PTR(-EPROBE_DEFER); + if (!chan) + return ERR_PTR(-EPROBE_DEFER); + if (IS_ERR(chan)) + return chan; +found: + if (chan->device->device_set_slave) { + chan->slave = dev; + ret = chan->device->device_set_slave(chan, dev); + if (ret) { + chan->slave = NULL; + dma_release_channel(chan); + chan = ERR_PTR(ret); + } + } + return chan; } EXPORT_SYMBOL_GPL(dma_request_chan); @@ -786,6 +802,11 @@ void dma_release_channel(struct dma_chan *chan) mutex_lock(_list_mutex); WARN_ONCE(chan->client_count != 1, "chan reference count %d != 1\n", chan->client_count); + if (chan->slave) { + if (chan->device->device_release_slave) + chan->device->device_release_slave(chan); + chan->slave = NULL; + } dma_chan_put(chan); /* drop PRIVATE cap enabled by __dma_request_channel() */ if (--chan->device->privatecnt == 0) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 533680860865..d22299e37e69 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -277,6 +277,9 @@ struct dma_chan { struct dma_router *router; void *route_data; + /* Only for SLAVE channels */ + struct device *slave; so assuming you refer to consumer aka client here, why do we need set if we store it here. DMA engine driver might need to do something with it (like setting up a pm link for example) before starting any operations. It would be great if the pointer to client device is available in device_alloc
Re: [PATCH v8 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
Hi Ulf, On 2017-02-13 12:11, Ulf Hansson wrote: If we could set up the device link already at device initialization, it should also be possible to avoid getting -EPROBE_DEFER for dma client drivers when requesting their dma channels. Well if we defer then driver will regiser with dmaengine after it is probed, so a client will either get a channel or not. IOW we won't get -EPROBE_DEFER. I didn't quite get this. What do you mean by "if we defer..."? Defer into *what* and defer of *what*? Could you please elaborate. [...] Again, allow me to fill in. This issue exists for all ARM SoC which has a dma controller residing in a PM domain. I think that is quite many. Currently the only solution I have seen for this problem, but which I really dislike. That is, each dma client driver requests/releases their dma channel from their respective ->runtime_suspend|resume() callbacks - then the dma driver can use the dma request/release hooks, to do pm_runtime_get|put() which then becomes non-irq-safe. Yeah that is not the best way to do. But looking at it current one doesnt seem best fit either. So on seeing the device_link_add() I was thinking that this is some SoC dependent problem being solved whereas the problem statmement is non-atomic channel prepare. You may be right. Although, I don't know of other examples, besides the runtime PM use case, where non-atomic channel prepare/unprepare would make sense. Do you? Changing GFP_ATOMIC to GFP_KERNEL in some calls in the DMA engine drivers would be also a nice present for the memory management subsystem if there is no real reason to drain atomic pools. As I said earlier, if we want to solve that problem a better idea is to actually split the prepare as we discussed in [1] This way we can get a non atomic descriptor allocate/prepare and release. Yes we need to redesign the APIs to solve this, but if you guys are up for it, I think we can do it and avoid any further round abouts :) Adding/re-designing dma APIs is a viable option to solve the runtime PM case. Changes would be needed for all related dma client drivers as well, although if that's what we need to do - let's do it. [...] So besides solving the irq-safe issue for dma driver, using the device-links has additionally two advantages. I already mentioned the -EPROBE_DEFER issue above. The second thing, is the runtime/system PM relations we get for free by using the links. In other words, the dma driver/core don't need to care about dealing with pm_runtime_get|put() as that would be managed by the dma client driver. Yeah sorry took me a while to figure that out :), If we do a different API then dmaengine core can call pm_runtime_get|put() from non-atomic context. Yes, it can and this works from runtime PM point of view. But the following issues would remain unsolved. 1) Dependencies between dma drivers and dma client drivers during system PM. For example, a dma client driver needs the dma controller to be operational (remain system resumed), until the dma client driver itself becomes system suspended. The *only* currently available solution for this, is to try to system suspend the dma controller later than the dma client, via using the *late or the *noirq system PM callbacks. This works for most cases, but it becomes a problem when the dma client also needs to be system suspended at the *late or the *noirq phase. Clearly this solution that doesn't scale. Using device links explicitly solves this problem as it allows to specify this dependency between devices. Frankly, then creating device links has to be added to EVERY subsystem, which involves getting access to the resources provided by the other device. More or less this will apply to all kernel frameworks, which provide kind of ABC_get_XYZ(dev, ...) functions (like clk_get, phy_get, dma_chan_get, ...). Sounds like a topic for another lng discussion. 2) We won't avoid dma clients from getting -EPROBE_DEFER when requesting their dma channels in their ->probe() routines. This would be possible, if we can set up the device links at device initialization. The question is which core (DMA engine?, kernel device subsystem?) and how to find all clients before they call dma_chan_get(). Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v8 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
Hi Ulf, On 2017-02-10 14:57, Ulf Hansson wrote: On 10 February 2017 at 12:51, Marek Szyprowski <m.szyprow...@samsung.com> wrote: On 2017-02-10 05:50, Vinod Koul wrote: On Thu, Feb 09, 2017 at 03:22:51PM +0100, Marek Szyprowski wrote: +static int pl330_set_slave(struct dma_chan *chan, struct device *slave) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct pl330_dmac *pl330 = pch->dmac; + int i; + + mutex_lock(>rpm_lock); + + for (i = 0; i < pl330->num_peripherals; i++) { + if (pl330->peripherals[i].chan.slave == slave && + pl330->peripherals[i].slave_link) { + pch->slave_link = pl330->peripherals[i].slave_link; + goto done; + } + } + + pch->slave_link = device_link_add(slave, pl330->ddma.dev, + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); So you are going to add the link on channel allocation and tear down on the freeup. Right. Channel allocation is typically done once per driver operation and it won't hurt system performance. I am not sure I really like the idea here. Could you point what's wrong with it? First, these thing shouldn't be handled in the drivers. These things should be set in core and each driver setting the links doesn't sound great to me. Which core? And what's wrong with the device links? They have been introduced to model relations between devices that are behind the usual parent/child/bus topology. I think Vinod mean the dmaengine core. Which also would make perfect sense to me as it would benefit all dma drivers. The only related PM thing, that shall be the decision of the driver, is whether it wants to enable runtime PM or not, during ->probe(). So do you want to create the links during the DMAengine driver probe? How do you plan to find all the client devices? Please note that you really want to create links to devices which will really use the DMA engine calls. Some client drivers might decide in runtime weather to use DMA engine or not, depending on other data. Second, should the link be always there and we only mange the state? Here it seems that we have link being created and destroyed, so why not mark it ACTIVE and DORMANT instead... Link state is managed by device core and should not be touched by the drivers. It is related to both provider and consumer drivers states (probed/not probed/etc). Second we would need to create those links first. The question is where to create them then. Just to fill in, to me this is really also the key question. If we could set up the device link already at device initialization, it should also be possible to avoid getting -EPROBE_DEFER for dma client drivers when requesting their dma channels. At the first glance this sounds like an ultimate solution for all problems, but I don't think that device links can be used this way. If I get it right, you would like to create links on client device initialization, preferably somewhere in the kernel driver core. This will be handled somehow by a completely generic code, which will create a link each pair of devices, which are connected by a phandle. Is this what you meant? Please note that that time no driver for both client and provider are probed. IMHO that doesn't look like a right generic approach How that code will know get following information: 1. is it really needed to create a link for given device pair? 2. what link flags should it use? 3. what about circular dependencies? 4. what about runtime optional dependencies? 5. what about non-dt platforms? acpi? This looks like another newer ending story of "how can we avoid deferred probe in a generic way". IMHO we should first solve the problem of irq-safe runtime PM in DMA engine drivers first. I proposed how it can be done with device links. With no changes in the client API. Later if one decide to extend the client API in a way it will allow other runtime PM implementation - I see no problem to convert pl330 driver to the new approach, but for the time being - this would be the easiest way to get it really functional. Lastly, looking at th description of the issue here, am perceiving (maybe my understanding is not quite right here) that you have an IP block in SoC which has multiple things and share common stuff and doing right PM is a challenge for you, right? Nope. Doing right PM in my SoC is not that complex and I would say it is rather typical for any embedded stuff. It works fine (in terms of the power consumption reduction) when all drivers simply properly manage their runtime PM state, thus if device is not in use, the state is set to suspended and finally, the power domain gets turned off. I've used device links for PM only because the current DMA engine API is simply insufficient to implement it in the other way. I want to let a power domain, which contains
Re: [PATCH v8 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
Hi Vinod, On 2017-02-13 03:03, Vinod Koul wrote: On Fri, Feb 10, 2017 at 02:57:09PM +0100, Ulf Hansson wrote: On 10 February 2017 at 12:51, Marek Szyprowski <m.szyprow...@samsung.com> wrote: On 2017-02-10 05:50, Vinod Koul wrote: On Thu, Feb 09, 2017 at 03:22:51PM +0100, Marek Szyprowski wrote: +static int pl330_set_slave(struct dma_chan *chan, struct device *slave) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct pl330_dmac *pl330 = pch->dmac; + int i; + + mutex_lock(>rpm_lock); + + for (i = 0; i < pl330->num_peripherals; i++) { + if (pl330->peripherals[i].chan.slave == slave && + pl330->peripherals[i].slave_link) { + pch->slave_link = pl330->peripherals[i].slave_link; + goto done; + } + } + + pch->slave_link = device_link_add(slave, pl330->ddma.dev, + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); So you are going to add the link on channel allocation and tear down on the freeup. Right. Channel allocation is typically done once per driver operation and it won't hurt system performance. I am not sure I really like the idea here. Could you point what's wrong with it? First, these thing shouldn't be handled in the drivers. These things should be set in core and each driver setting the links doesn't sound great to me. Which core? And what's wrong with the device links? They have been introduced to model relations between devices that are behind the usual parent/child/bus topology. I think Vinod mean the dmaengine core. Which also would make perfect sense to me as it would benefit all dma drivers. Right. The only related PM thing, that shall be the decision of the driver, is whether it wants to enable runtime PM or not, during ->probe(). We can do pm_runtime_enabled() to check and that and do when enabled.. Another subtle issue is that there can be only one link between devices, but it is common to request more than one channel per client device (for example "tx" and "rx"), but this can be handled by internal reference counting. Second, should the link be always there and we only mange the state? Here it seems that we have link being created and destroyed, so why not mark it ACTIVE and DORMANT instead... Link state is managed by device core and should not be touched by the drivers. It is related to both provider and consumer drivers states (probed/not probed/etc). Second we would need to create those links first. The question is where to create them then. Just to fill in, to me this is really also the key question. If we could set up the device link already at device initialization, it should also be possible to avoid getting -EPROBE_DEFER for dma client drivers when requesting their dma channels. Well if we defer then driver will regiser with dmaengine after it is probed, so a client will either get a channel or not. IOW we won't get -EPROBE_DEFER. I don't get how this will work. IMHO the link should be created WHEN client driver requests the channel, because otherwise we will get links that might be not used at all (for example optional DMA usage, but the link will force DMA controller to active state even if client device doesn't want to use DMA at all). So if client requests it for the first time and the DMA engine has not been probed yet, there is no way to avoid -EPROBE_DEFER. Lastly, looking at th description of the issue here, am perceiving (maybe my understanding is not quite right here) that you have an IP block in SoC which has multiple things and share common stuff and doing right PM is a challenge for you, right? Nope. Doing right PM in my SoC is not that complex and I would say it is rather typical for any embedded stuff. It works fine (in terms of the power consumption reduction) when all drivers simply properly manage their runtime PM state, thus if device is not in use, the state is set to suspended and finally, the power domain gets turned off. I've used device links for PM only because the current DMA engine API is simply insufficient to implement it in the other way. I want to let a power domain, which contains a few devices, among those a PL330 device, to get turned off when there is no activity. Handling power domain power on / off requires non-atomic context, what is typical for runtime pm calls. For that I need to have non-irq-safe runtime pm implemented for all devices that belongs to that domains. Again, allow me to fill in. This issue exists for all ARM SoC which has a dma controller residing in a PM domain. I think that is quite many. Currently the only solution I have seen for this problem, but which I really dislike. That is, each dma client driver requests/releases their dma channel from their respective ->runtime_suspend|resume() callbacks - then the dma driver can use the dma request/rel
Re: [PATCH v7 2/4] dmaengine: Forward slave device pointer to of_xlate callback
Hi Ulf, On 2017-02-09 10:55, Ulf Hansson wrote: Yes agreed on that, plus the runtime handling needs to be built in, right now the APIs dont work well with it, we disucssed these during the KS and this goes without saying, patches are welcome :) Okay, so what is the conclusion? Do you want me to do the whole rework of dma engine core to get this runtime pm patchset for pl330 merged??? Is there any roadmap for this rework prepared, so I can at least take a look at the amount of work needed to be done? I'm rather new to dma engine framework and I only wanted to fix pl330 driver not to block turning off the power domain on Exynos5422/5433 SoCs. As you probably know, this is a common problem for many dma devices, slave devices and platforms. Right, this is a common issue and someone has to finally find a solution for it. If possible, it would be great if we could avoid a solution that doesn't force changes to lots of "dma consumer" drivers. My current solution doesn't require changing ANY "dma consumer" driver. However, I have one more idea how to avoid touching dma engine ("provider") drivers as well. This will also address some issues pointed by Lars. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v8 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
Hi Vinod, On 2017-02-10 05:50, Vinod Koul wrote: On Thu, Feb 09, 2017 at 03:22:51PM +0100, Marek Szyprowski wrote: +static int pl330_set_slave(struct dma_chan *chan, struct device *slave) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct pl330_dmac *pl330 = pch->dmac; + int i; + + mutex_lock(>rpm_lock); + + for (i = 0; i < pl330->num_peripherals; i++) { + if (pl330->peripherals[i].chan.slave == slave && + pl330->peripherals[i].slave_link) { + pch->slave_link = pl330->peripherals[i].slave_link; + goto done; + } + } + + pch->slave_link = device_link_add(slave, pl330->ddma.dev, + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); So you are going to add the link on channel allocation and tear down on the freeup. Right. Channel allocation is typically done once per driver operation and it won't hurt system performance. I am not sure I really like the idea here. Could you point what's wrong with it? First, these thing shouldn't be handled in the drivers. These things should be set in core and each driver setting the links doesn't sound great to me. Which core? And what's wrong with the device links? They have been introduced to model relations between devices that are behind the usual parent/child/bus topology. Second, should the link be always there and we only mange the state? Here it seems that we have link being created and destroyed, so why not mark it ACTIVE and DORMANT instead... Link state is managed by device core and should not be touched by the drivers. It is related to both provider and consumer drivers states (probed/not probed/etc). Second we would need to create those links first. The question is where to create them then. Lastly, looking at th description of the issue here, am perceiving (maybe my understanding is not quite right here) that you have an IP block in SoC which has multiple things and share common stuff and doing right PM is a challenge for you, right? Nope. Doing right PM in my SoC is not that complex and I would say it is rather typical for any embedded stuff. It works fine (in terms of the power consumption reduction) when all drivers simply properly manage their runtime PM state, thus if device is not in use, the state is set to suspended and finally, the power domain gets turned off. I've used device links for PM only because the current DMA engine API is simply insufficient to implement it in the other way. I want to let a power domain, which contains a few devices, among those a PL330 device, to get turned off when there is no activity. Handling power domain power on / off requires non-atomic context, what is typical for runtime pm calls. For that I need to have non-irq-safe runtime pm implemented for all devices that belongs to that domains. The problem with PL330 driver is that it use irq-safe runtime pm, which like it was stated in the patch description doesn't bring much benefits. To switch to standard (non-irq-safe) runtime pm, the pm_runtime calls have to be done from a context which permits sleeping. The problem with DMA engine driver API is that most of its callbacks have to be IRQ-safe and frankly only device_{alloc,release}_chan_resources() what more or less maps to dma_request_chan()/dma_release_channel() and friends. There are DMA engine drivers which do runtime PM calls there (tegra20-apb-dma, sirf-dma, cppi41, rcar-dmac), but this is not really efficient. DMA engine clients usually allocate dma channel during their probe() and keep them for the whole driver life. In turn this very similar to calling pm_runtime_get() in the DMA engine driver probe(). The result of both approaches is that DMA engine device keeps its power domain enabled almost all the time. This problem is also mentioned in the DMA engine TODO list, you have pointed me yesterday. To avoid such situation that DMA engine driver blocks turning off the power domain and avoid changing DMA engine client API I came up with the device links pm based approach. I don't want to duplicate the description here, the details were in the patch description, however if you have any particular question about the details, let me know and I will try to clarify it more. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v8 1/3] dmaengine: Add new device_{set,release}_slave callbacks
Hi Vinod, On 2017-02-10 05:34, Vinod Koul wrote: On Thu, Feb 09, 2017 at 03:22:49PM +0100, Marek Szyprowski wrote: Add two new callbacks to DMA engine device. They will used to provide access to slave device (the device which requested given DMA channel) You mean access to client devices? Yes. It looks that I was confused by the code, where the term 'slave' appears a few times. 'Client' is a bit more appropriate then. for DMA engine driver. Access to slave device might be useful for example for implementing advanced runtime power management. DMA slave channels are exclusive, so only one slave device can be set for a given DMA slave channel. That is not a right assumption and my worry here. With virt-dma we don't really assume a hardware channel and exclusive. Certain implementation may do that but from framework we cannot assume that. Okay, I came to such conclusion basing one the dma engine code, but maybe I missed something. However in such case such callback will be called for each client device and it will be up to the driver to handle that. device_set_slave() will be called after the device_alloc_chan_resources() and device_release_slave() before the device_free_chan_resources(). Okay, I had to relook at the series to get around this part. Sorry but we can't call it set_slave, it is actually set_client/consumer That's okay, the name of the callbacks should be changed. In our context slaves means dmaengine slave devices aka provider. Client would be the consumer and not slave. I'm a new to the DMA engine framework, I'm sorry for using wrong terms. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/dma/dmaengine.c | 27 --- include/linux/dmaengine.h | 10 ++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 24e0221fd66d..5b7089d8be4d 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -705,6 +705,7 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) { struct dma_device *d, *_d; struct dma_chan *chan = NULL; + int ret; /* If device-tree is present get slave info from here */ if (dev->of_node) @@ -715,8 +716,9 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) chan = acpi_dma_request_slave_chan_by_name(dev, name); if (chan) { - /* Valid channel found or requester need to be deferred */ - if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER) + if (!IS_ERR(chan)) + goto found; + if (PTR_ERR(chan) == -EPROBE_DEFER) return chan; } @@ -738,7 +740,21 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) } mutex_unlock(_list_mutex); - return chan ? chan : ERR_PTR(-EPROBE_DEFER); + if (!chan) + return ERR_PTR(-EPROBE_DEFER); + if (IS_ERR(chan)) + return chan; +found: + if (chan->device->device_set_slave) { + chan->slave = dev; + ret = chan->device->device_set_slave(chan, dev); + if (ret) { + chan->slave = NULL; + dma_release_channel(chan); + chan = ERR_PTR(ret); + } + } + return chan; } EXPORT_SYMBOL_GPL(dma_request_chan); @@ -786,6 +802,11 @@ void dma_release_channel(struct dma_chan *chan) mutex_lock(_list_mutex); WARN_ONCE(chan->client_count != 1, "chan reference count %d != 1\n", chan->client_count); + if (chan->slave) { + if (chan->device->device_release_slave) + chan->device->device_release_slave(chan); + chan->slave = NULL; + } dma_chan_put(chan); /* drop PRIVATE cap enabled by __dma_request_channel() */ if (--chan->device->privatecnt == 0) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 533680860865..d22299e37e69 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -277,6 +277,9 @@ struct dma_chan { struct dma_router *router; void *route_data; + /* Only for SLAVE channels */ + struct device *slave; so assuming you refer to consumer aka client here, why do we need set if we store it here. DMA engine driver might need to do something with it (like setting up a pm link for example) before starting any operations. It would be great if the pointer to client device is available in device_alloc_chan_resources(), but propagating it there is not possible without significant changes. That's why I came with this a separate callback. Maybe the client device shouldn't be stored in the dma_chan structure at all and left to the drivers to use or manag
Re: [PATCH 10/11] iommu/exynos: Make use of iommu_device_register interface
Hi On 2017-02-09 12:32, Joerg Roedel wrote: From: Joerg Roedel <jroe...@suse.de> Register Exynos IOMMUs to the IOMMU core and make them visible in sysfs. This patch does not add the links between IOMMUs and translated devices yet. Cc: Marek Szyprowski <m.szyprow...@samsung.com> Cc: linux-arm-ker...@lists.infradead.org Cc: linux-samsung-...@vger.kernel.org Signed-off-by: Joerg Roedel <jroe...@suse.de> Acked-by: Marek Szyprowski <m.szyprow...@samsung.com> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/iommu/exynos-iommu.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 57ba0d3..64325d8 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -276,6 +276,8 @@ struct sysmmu_drvdata { struct list_head owner_node;/* node for owner controllers list */ phys_addr_t pgtable;/* assigned page table structure */ unsigned int version; /* our version */ + + struct iommu_device iommu; /* IOMMU core handle */ }; static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom) @@ -611,6 +613,18 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) data->sysmmu = dev; spin_lock_init(>lock); + ret = iommu_device_sysfs_add(>iommu, >dev, NULL, +dev_name(data->sysmmu)); + if (ret) + return ret; + + iommu_device_set_ops(>iommu, _iommu_ops); + iommu_device_set_fwnode(>iommu, >of_node->fwnode); + + ret = iommu_device_register(>iommu); + if (ret) + return ret; + platform_set_drvdata(pdev, data); __sysmmu_get_version(data); Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH v8 0/3] DMA Engine: switch PL330 driver to non-irq-safe runtime PM
Hello, This patchset changes the way the runtime PM is implemented in the PL330 DMA engine driver. The main goal of such change is to add support for the audio power domain to Exynos5 SoCs (5250, 542x, 5433, probably others) and let it to be properly turned off, when no audio is being used. Switching to non-irq-safe runtime PM is required to properly let power domain to be turned off (irq-safe runtime PM keeps power domain turned on all the time) and to integrate with clock controller's runtime PM (this cannot be workarounded any other way, PL330 uses clocks from the controller, which belongs to the same power domain). For more details of the proposed change to the PL330 driver see patch #3. Audio power domain on Exynos5 SoCs contains following hardware modules: 1. clock controller 2. pin controller 3. PL330 DMA controller 4. I2S audio controller Patches for adding or fixing runtime PM for each of the above devices is handled separately. Runtime PM patches for clock controllers is possible and has been proposed in the following thread (pending review): "[PATCH v4 0/4] Add runtime PM support for clocks (on Exynos SoC example)", http://www.spinics.net/lists/arm-kernel/msg550747.html Runtime PM support for Exynos pin controller has been posted in the following thread: "[PATCH 0/9] Runtime PM for Exynos pin controller driver", http://www.spinics.net/lists/arm-kernel/msg550161.html Exynos I2S driver supports runtime PM, but some fixes were needed for it and they are already queued to linux-next. This patchset is based on linux-next from 9th February 2017. Best regards Marek Szyprowski Samsung R Institute Poland Changelog: v8: - reworked slave device assignment, now it is done in separate callbacks as requested by Lars-Peter Clausen, no more changes to of_xlate callback in every dma engine driver are needed in this approach - reworked pl330 patch to use new device_{set,release}_slave callbacks - dropped tags because of the code changes - rebased onto linux next-20170209 v7: https://www.spinics.net/lists/arm-kernel/msg557696.html - added missing of_dma_request_slave_channel API change to sound/soc/sh/rcar driver - extended commit message with information about drawbacks of irq-safe runtime pm - added Ulf's reviewed-by tags v6: https://www.spinics.net/lists/arm-kernel/msg557377.html - fixed pl330 system sleep suspend/resume callbacks, previous implementation incorrectly tried to unprepare clocks unconditionally - after a fix pl330 suspend/resume callbacks can be simply replaced by generic pm_runtime_force_{suspend,resume} helpers, what simplifies code even more v5: https://www.spinics.net/lists/arm-kernel/msg555001.html - added Acks - additional mutex is indeed not needed, rely on dma_list_mutex in dmaengine core, added comment about locking v4: http://www.spinics.net/lists/dmaengine/msg12329.html - rebased onto "dmaengine: pl330: fix double lock" patch: http://www.spinics.net/lists/dmaengine/msg12289.html - added a mutex to protect runtime PM links creation/removal to avoid races - moved mem2mem channel case handing to pl330_{add,del}_slave_pm_link functions to simplify code and error paths v3: http://www.spinics.net/lists/dmaengine/msg12245.html - removed pl330_filter function as suggested by Arnd Bergmann - removed pl330.h from arch/arm/plat-samsung/devs.c - fixes some minor style issues pointed by Krzysztof Kozlowski v2: https://www.spinics.net/lists/arm-kernel/msg552772.html - rebased onto linux next-20170109 - improved patch description - separated patch #3 from #4 (storing a pointer to slave device for each DMA channel) as requested by Krzysztof Kozlowski v1: https://www.spinics.net/lists/arm-kernel/msg550008.html - initial version Patch summary: Marek Szyprowski (3): dmaengine: Add new device_{set,release}_slave callbacks dmaengine: pl330: remove pdata based initialization dmaengine: pl330: Don't require irq-safe runtime PM arch/arm/plat-samsung/devs.c | 1 - drivers/dma/dmaengine.c | 27 +- drivers/dma/pl330.c | 219 +-- include/linux/amba/pl330.h | 35 --- include/linux/dmaengine.h| 10 ++ 5 files changed, 119 insertions(+), 173 deletions(-) delete mode 100644 include/linux/amba/pl330.h -- 1.9.1
[PATCH v8 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
This patch replaces irq-safe runtime PM with non-irq-safe version based on the new approach. Existing, irq-safe runtime PM implementation for PL330 was not bringing much benefits of its own - only clocks were enabled/disabled. Another limitation of irq-safe runtime PM is a fact, that it may prevent the generic PM domain (genpd) from being powered off, particularly in cases when the genpd doesn't have the GENPD_FLAG_IRQ_SAFE set. Till now non-irq-safe runtime PM implementation was only possible by calling pm_runtime_get/put functions from alloc/free_chan_resources. All other DMA engine API functions cannot be called from a context, which permits sleeping. Such implementation, in practice would result in keeping DMA controller's device active almost all the time, because most of the slave device drivers (DMA engine clients) acquire DMA channel in their probe() function and released it during driver removal. This patch provides a new, different approach. It is based on an observation that there can be only one slave device using each DMA channel. PL330 hardware always has dedicated channels for each peripheral device. Using recently introduced device dependencies (links) infrastructure one can ensure proper runtime PM state of PL330 DMA controller basing on the runtime PM state of the slave device. In this approach in pl330_set_slave() function a new dependency is being created between PL330 DMA controller device (as a supplier) and given slave device (as a consumer). This way PL330 DMA controller device runtime active counter is increased when the slave device is resumed and decreased the same time when given slave device is put to suspend. This way it has been ensured to keep PL330 DMA controller runtime active if there is an active used of any of its DMA channels. This is similar to what has been already implemented in Exynos IOMMU driver in commit 2f5f44f205cc95 ("iommu/exynos: Use device dependency links to control runtime pm"). If slave device doesn't implement runtime PM or keeps device runtime active all the time, then PL330 DMA controller will be runtime active all the time when channel is being allocated. If one requests memory-to-memory channel, runtime active counter is increased unconditionally. This might be a drawback of this approach, but PL330 is not really used for memory-to-memory operations due to poor performance in such operations compared to the CPU. Removal of irq-safe runtime PM is based on the revert of the following commits: 1. commit 5c9e6c2b2ba3 "dmaengine: pl330: fix runtime pm support" 2. commit 81cc6edc0870 "dmaengine: pl330: Fix hang on dmaengine_terminate_all on certain boards" 3. commit ae43b3289186 "ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12" Introducing non-irq-safe runtime power management finally allows to turn off audio power domain on Exynos5 SoCs. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/dma/pl330.c | 177 +++- 1 file changed, 77 insertions(+), 100 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 8b0da7fa520d..17efad418faa 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -268,9 +269,6 @@ enum pl330_byteswap { #define NR_DEFAULT_DESC16 -/* Delay for runtime PM autosuspend, ms */ -#define PL330_AUTOSUSPEND_DELAY 20 - /* Populated by the PL330 core driver for DMA API driver's info */ struct pl330_config { u32 periph_id; @@ -449,7 +447,7 @@ struct dma_pl330_chan { bool cyclic; /* for runtime pm tracking */ - bool active; + struct device_link *slave_link; }; struct pl330_dmac { @@ -463,6 +461,8 @@ struct pl330_dmac { struct list_head desc_pool; /* To protect desc_pool manipulation */ spinlock_t pool_lock; + /* For management of slave PM links */ + struct mutex rpm_lock; /* Size of MicroCode buffers for each channel. */ unsigned mcbufsz; @@ -2008,7 +2008,6 @@ static void pl330_tasklet(unsigned long data) struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; struct dma_pl330_desc *desc, *_dt; unsigned long flags; - bool power_down = false; spin_lock_irqsave(>lock, flags); @@ -2023,18 +2022,10 @@ static void pl330_tasklet(unsigned long data) /* Try to submit a req imm. next to the last completed cookie */ fill_queue(pch); - if (list_empty(>work_list)) { - spin_lock(>thread->dmac->lock); - _stop(pch->thread); - spin_unlock(>thread->dmac->lock); - power_down = true; - pch->active = false; - } else { - /* Make sure the PL330 Channel thread is active */ -
[PATCH v8 1/3] dmaengine: Add new device_{set,release}_slave callbacks
Add two new callbacks to DMA engine device. They will used to provide access to slave device (the device which requested given DMA channel) for DMA engine driver. Access to slave device might be useful for example for implementing advanced runtime power management. DMA slave channels are exclusive, so only one slave device can be set for a given DMA slave channel. device_set_slave() will be called after the device_alloc_chan_resources() and device_release_slave() before the device_free_chan_resources(). Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/dma/dmaengine.c | 27 --- include/linux/dmaengine.h | 10 ++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 24e0221fd66d..5b7089d8be4d 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -705,6 +705,7 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) { struct dma_device *d, *_d; struct dma_chan *chan = NULL; + int ret; /* If device-tree is present get slave info from here */ if (dev->of_node) @@ -715,8 +716,9 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) chan = acpi_dma_request_slave_chan_by_name(dev, name); if (chan) { - /* Valid channel found or requester need to be deferred */ - if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER) + if (!IS_ERR(chan)) + goto found; + if (PTR_ERR(chan) == -EPROBE_DEFER) return chan; } @@ -738,7 +740,21 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name) } mutex_unlock(_list_mutex); - return chan ? chan : ERR_PTR(-EPROBE_DEFER); + if (!chan) + return ERR_PTR(-EPROBE_DEFER); + if (IS_ERR(chan)) + return chan; +found: + if (chan->device->device_set_slave) { + chan->slave = dev; + ret = chan->device->device_set_slave(chan, dev); + if (ret) { + chan->slave = NULL; + dma_release_channel(chan); + chan = ERR_PTR(ret); + } + } + return chan; } EXPORT_SYMBOL_GPL(dma_request_chan); @@ -786,6 +802,11 @@ void dma_release_channel(struct dma_chan *chan) mutex_lock(_list_mutex); WARN_ONCE(chan->client_count != 1, "chan reference count %d != 1\n", chan->client_count); + if (chan->slave) { + if (chan->device->device_release_slave) + chan->device->device_release_slave(chan); + chan->slave = NULL; + } dma_chan_put(chan); /* drop PRIVATE cap enabled by __dma_request_channel() */ if (--chan->device->privatecnt == 0) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 533680860865..d22299e37e69 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -277,6 +277,9 @@ struct dma_chan { struct dma_router *router; void *route_data; + /* Only for SLAVE channels */ + struct device *slave; + void *private; }; @@ -686,6 +689,10 @@ struct dma_filter { * @device_alloc_chan_resources: allocate resources and return the * number of allocated descriptors * @device_free_chan_resources: release DMA channel's resources + * @device_set_slave: provide access to the slave device, which requested + * given DMA channel, called after @device_alloc_chan_resources + * @device_release_slave: finishes access to the slave device, called + * before @device_free_chan_resources * @device_prep_dma_memcpy: prepares a memcpy operation * @device_prep_dma_xor: prepares a xor operation * @device_prep_dma_xor_val: prepares a xor validation operation @@ -746,6 +753,9 @@ struct dma_device { int (*device_alloc_chan_resources)(struct dma_chan *chan); void (*device_free_chan_resources)(struct dma_chan *chan); + int (*device_set_slave)(struct dma_chan *chan, struct device *slave); + void (*device_release_slave)(struct dma_chan *chan); + struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)( struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, size_t len, unsigned long flags); -- 1.9.1
[PATCH v8 2/3] dmaengine: pl330: remove pdata based initialization
This driver is now used only on platforms which support device tree, so it is safe to remove legacy platform data based initialization code. Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Reviewed-by: Ulf Hansson <ulf.hans...@linaro.org> Acked-by: Arnd Bergmann <a...@arndb.de> For plat-samsung: Acked-by: Krzysztof Kozlowski <k...@kernel.org> --- arch/arm/plat-samsung/devs.c | 1 - drivers/dma/pl330.c | 42 -- include/linux/amba/pl330.h | 35 --- 3 files changed, 8 insertions(+), 70 deletions(-) delete mode 100644 include/linux/amba/pl330.h diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 03fac123676d..dc269d9143bc 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -10,7 +10,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index f37f4978dabb..8b0da7fa520d 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -2077,18 +2076,6 @@ static void pl330_tasklet(unsigned long data) } } -bool pl330_filter(struct dma_chan *chan, void *param) -{ - u8 *peri_id; - - if (chan->device->dev->driver != _driver.drv) - return false; - - peri_id = chan->private; - return *peri_id == (unsigned long)param; -} -EXPORT_SYMBOL(pl330_filter); - static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { @@ -2833,7 +2820,6 @@ static int __maybe_unused pl330_resume(struct device *dev) static int pl330_probe(struct amba_device *adev, const struct amba_id *id) { - struct dma_pl330_platdata *pdat; struct pl330_config *pcfg; struct pl330_dmac *pl330; struct dma_pl330_chan *pch, *_p; @@ -2843,8 +2829,6 @@ static int __maybe_unused pl330_resume(struct device *dev) int num_chan; struct device_node *np = adev->dev.of_node; - pdat = dev_get_platdata(>dev); - ret = dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(32)); if (ret) return ret; @@ -2857,7 +2841,7 @@ static int __maybe_unused pl330_resume(struct device *dev) pd = >ddma; pd->dev = >dev; - pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; + pl330->mcbufsz = 0; /* get quirk */ for (i = 0; i < ARRAY_SIZE(of_quirks); i++) @@ -2901,10 +2885,7 @@ static int __maybe_unused pl330_resume(struct device *dev) INIT_LIST_HEAD(>channels); /* Initialize channel parameters */ - if (pdat) - num_chan = max_t(int, pdat->nr_valid_peri, pcfg->num_chan); - else - num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); + num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); pl330->num_peripherals = num_chan; @@ -2916,11 +2897,8 @@ static int __maybe_unused pl330_resume(struct device *dev) for (i = 0; i < num_chan; i++) { pch = >peripherals[i]; - if (!adev->dev.of_node) - pch->chan.private = pdat ? >peri_id[i] : NULL; - else - pch->chan.private = adev->dev.of_node; + pch->chan.private = adev->dev.of_node; INIT_LIST_HEAD(>submitted_list); INIT_LIST_HEAD(>work_list); INIT_LIST_HEAD(>completed_list); @@ -2933,15 +2911,11 @@ static int __maybe_unused pl330_resume(struct device *dev) list_add_tail(>chan.device_node, >channels); } - if (pdat) { - pd->cap_mask = pdat->cap_mask; - } else { - dma_cap_set(DMA_MEMCPY, pd->cap_mask); - if (pcfg->num_peri) { - dma_cap_set(DMA_SLAVE, pd->cap_mask); - dma_cap_set(DMA_CYCLIC, pd->cap_mask); - dma_cap_set(DMA_PRIVATE, pd->cap_mask); - } + dma_cap_set(DMA_MEMCPY, pd->cap_mask); + if (pcfg->num_peri) { + dma_cap_set(DMA_SLAVE, pd->cap_mask); + dma_cap_set(DMA_CYCLIC, pd->cap_mask); + dma_cap_set(DMA_PRIVATE, pd->cap_mask); } pd->device_alloc_chan_resources = pl330_alloc_chan_resources; diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h deleted file mode 100644 index fe93758e8403.. --- a/include/linux/amba/pl330.h +++ /dev/null @@ -1,35 +0,0 @@ -/* linux/include/linux/amba/pl330.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh <jassi.b...@samsung.co
Re: [PATCH 1/2] [media] exynos-gsc: Fix unbalanced pm_runtime_enable() error
Hi Javier, On 2017-01-18 01:30, Javier Martinez Canillas wrote: Commit a006c04e6218 ("[media] exynos-gsc: Fixup clock management at ->remove()") changed the driver's .remove function logic to fist do a pm_runtime_get_sync() to make sure the device is powered before attempting to gate the gsc clock. But the commit also removed a pm_runtime_disable() call that leads to an unbalanced pm_runtime_enable() error if the driver is removed and re-probed: exynos-gsc 13e0.video-scaler: Unbalanced pm_runtime_enable! exynos-gsc 13e1.video-scaler: Unbalanced pm_runtime_enable! Fixes: a006c04e6218 ("[media] exynos-gsc: Fixup clock management at ->remove()") Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com> I must have mixed something during the rebase of the Ulf's patch, because the original one kept pm_runtime_disable in the right place: http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317678.html I'm really sorry. Acked-by: Marek Szyprowski <m.szyprow...@samsung.com> --- drivers/media/platform/exynos-gsc/gsc-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index cbf75b6194b4..83272f10722d 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1118,6 +1118,7 @@ static int gsc_remove(struct platform_device *pdev) clk_disable_unprepare(gsc->clock[i]); pm_runtime_put_noidle(>dev); + pm_runtime_disable(>dev); dev_dbg(>dev, "%s driver unloaded\n", pdev->name); return 0; Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 2/2] [media] exynos-gsc: Fix imprecise external abort due disabled power domain
Hi Javier, On 2017-01-18 01:30, Javier Martinez Canillas wrote: Commit 15f90ab57acc ("[media] exynos-gsc: Make driver functional when CONFIG_PM is unset") removed the implicit dependency that the driver had with CONFIG_PM, since it relied on the config option to be enabled. In order to work with !CONFIG_PM, the GSC reset logic that happens in the runtime resume callback had to be executed on the probe function. The problem is that if CONFIG_PM is enabled, the power domain for the GSC could be disabled and so an attempt to write to the GSC_SW_RESET register leads to an unhandled fault / imprecise external abort error: Driver core ensures that driver's probe() is called with respective power domain turned on, so this is not the right reason for the proposed change. [ 10.178825] Unhandled fault: imprecise external abort (0x1406) at 0x [ 10.186982] pgd = ed728000 [ 10.190847] [] *pgd= [ 10.195553] Internal error: : 1406 [#1] PREEMPT SMP ARM [ 10.229761] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 10.237134] task: ed49e400 task.stack: ed724000 [ 10.242934] PC is at gsc_wait_reset+0x5c/0x6c [exynos_gsc] [ 10.249710] LR is at gsc_probe+0x300/0x33c [exynos_gsc] [ 10.256139] pc : []lr : []psr: 60070013 [ 10.256139] sp : ed725d30 ip : fp : 0001 [ 10.271492] r10: eea74800 r9 : ecd6a2c0 r8 : ed7d8854 [ 10.277912] r7 : ed7d8c08 r6 : ed7d8810 r5 : 8ecd r4 : c0c03900 [ 10.285664] r3 : r2 : 0001 r1 : ed7d8b98 r0 : ed7d8810 So only do a GSC reset if CONFIG_PM is disabled, since if is enabled the runtime PM resume callback will be called by the VIDIOC_STREAMON ioctl, making the reset in probe unneeded. Fixes: 15f90ab57acc ("[media] exynos-gsc: Make driver functional when CONFIG_PM is unset") Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com> Frankly, I don't get why this change is needed. --- I-ve only tested with CONFIG_PM enabled since my Exynos5422 Odroid XU4 board fails to boot when the config option is disabled. Best regards, Javier drivers/media/platform/exynos-gsc/gsc-core.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 83272f10722d..42e1e09ea915 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1083,8 +1083,10 @@ static int gsc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gsc); - gsc_hw_set_sw_reset(gsc); - gsc_wait_reset(gsc); + if (!IS_ENABLED(CONFIG_PM)) { + gsc_hw_set_sw_reset(gsc); + gsc_wait_reset(gsc); + } vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 2/2] [media] exynos-gsc: Fix imprecise external abort due disabled power domain
Hi Javier, On 2017-01-19 18:51, Javier Martinez Canillas wrote: On 01/19/2017 11:56 AM, Javier Martinez Canillas wrote: On 01/19/2017 11:17 AM, Marek Szyprowski wrote: [snip] Also when removing the exynos_gsc driver, I get the same error: # rmmod s5p_mfc [ 106.405972] s5p-mfc 1100.codec: Removing 1100.codec # rmmod exynos_gsc [ 227.008559] Unhandled fault: imprecise external abort (0x1c06) at 0x00048e14 [ 227.015116] pgd = ed5dc000 [ 227.017213] [00048e14] *pgd=b17c6835 [ 227.020889] Internal error: : 1c06 [#1] PREEMPT SMP ARM ... [ 227.241585] [] (gsc_wait_reset [exynos_gsc]) from [] (gsc_runtime_resume+0x9c/0xec [exynos_gsc]) [ 227.252331] [] (gsc_runtime_resume [exynos_gsc]) from [] (genpd_runtime_resume+0x120/0x1d4) [ 227.262294] [] (genpd_runtime_resume) from [] (__rpm_callback+0xc8/0x218) # cat /sys/kernel/debug/pm_genpd/pm_genpd_summary domain status slaves /device runtime status -- power-domain@100440C0 on /devices/platform/soc/1445.mixeractive /devices/platform/soc/1453.hdmi active power-domain@10044120 on power-domain@10044060 off-0 power-domain@10044020 on power-domain@10044000 on /devices/platform/soc/13e0.video-scaler suspended /devices/platform/soc/13e1.video-scaler resuming This seems to be caused by some needed clocks to access the power domains to be gated, since I don't get these erros when passing clk_ignore_unused as parameter in the kernel command line. I found the issue. The problem was that Exynos5422 needs not only the CLK_ACLK_ 300_GSCL but also CLK_ACLK432_SCALER to be ungated in order to access the GSCL IP block. The Exynos5422 manual shows in Figure 7-14 that ACLK_432_SCLAER is needed for the internal buses. Exynos5420 only needs CLK_ACLK_ 300_GSCL to be ungated. With following hack, the issue goes away for the gsc_pd in the Odroid XU4: diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 8c8b495cbf0d..9876ec28b94c 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -586,7 +586,7 @@ static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = { GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam", GATE_BUS_TOP, 24, 0, 0), GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", - GATE_BUS_TOP, 27, 0, 0), + GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), }; # cat /sys/kernel/debug/pm_genpd/pm_genpd_summary domain status slaves /device runtime status -- power-domain@100440C0 on /devices/platform/soc/1445.mixeractive /devices/platform/soc/1453.hdmi active power-domain@10044120 on power-domain@10044060 off-0 /devices/platform/soc/1100.codecsuspended power-domain@10044020 on power-domain@10044000 off-0 /devices/platform/soc/13e0.video-scaler suspended /devices/platform/soc/13e1.video-scaler suspended # rmmod s5p_mfc [ 82.885227] s5p-mfc 1100.codec: Removing 1100.codec # rmmod exynos_gsc # cat /sys/kernel/debug/pm_genpd/pm_genpd_summary domain status slaves /device runtime status -- power-domain@100440C0 on /devices/platform/soc/1445.mixeractive /devices/platform/soc/1453.hdmi active power-domain@10044120 on power-domain@10044060 off-0 power-domain@10044020 on power-domain@10044000 off-0 I'll post a proper patch for the exynos5800.dtsi, to override the clocks in the gsc_pd device node. I also see that the two power domains that fail to be disabled msc_pd (power-domain@10044120) and isp_pd (power-domain@10044020) don't have clocks defined in the exynos54xx.dtsi. I'll add clocks for those too. Please send this patch instead of adding more clocks to the power domains. This way we will avoid adding more dependencies to userspace (DT ABI). Likely those clocks are also needed to access any device in that power domains. Later, once the runtime PM for clocks get merged, a patch for exynos542x clocks driver can be made to replace IS_CRITICAL with proper runtime handling. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 2/2] [media] exynos-gsc: Fix imprecise external abort due disabled power domain
Hi Javier, On 2017-01-19 15:56, Javier Martinez Canillas wrote: Thanks a lot for your feedback. On 01/19/2017 11:17 AM, Marek Szyprowski wrote: On 2017-01-18 01:30, Javier Martinez Canillas wrote: Commit 15f90ab57acc ("[media] exynos-gsc: Make driver functional when CONFIG_PM is unset") removed the implicit dependency that the driver had with CONFIG_PM, since it relied on the config option to be enabled. In order to work with !CONFIG_PM, the GSC reset logic that happens in the runtime resume callback had to be executed on the probe function. The problem is that if CONFIG_PM is enabled, the power domain for the GSC could be disabled and so an attempt to write to the GSC_SW_RESET register leads to an unhandled fault / imprecise external abort error: Driver core ensures that driver's probe() is called with respective power domain turned on, so this is not the right reason for the proposed change. Ok, I misunderstood the relationship between runtime PM and the power domains then. I thought the power domains were only powered on when the runtime PM framework resumed an associated device (i.e: pm_runtime_get_sync() is called). Power domains are implemented transparently for the drivers. Even when driver doesn't support runtime pm, but its device is in the power domain, the core will ensure that the domain will be turned on all the time the driver is bound to the device. But even if this isn't the case, shouldn't the reset in probe only be needed if CONFIG_PM isn't enabled? (IOW, $SUBJECT but with another commit message). This looks like an over-engineering. I don't like polluting driver code with conditional statements like IS_ENABLED(CONFIG_*). It should not hurt to reset the device in driver probe, especially just in case the device was left in some partially configured/working state by bootloader or previous kernel run (if started from kexec). Adding this conditional code to avoid some issues with power domain or clocks configuration also suggests that one should instead solve the problem elsewhere. Driver should be able to access device registers in its probe() in any case without the additional hacks. [ 10.178825] Unhandled fault: imprecise external abort (0x1406) at 0x [ 10.186982] pgd = ed728000 [ 10.190847] [] *pgd= [ 10.195553] Internal error: : 1406 [#1] PREEMPT SMP ARM [ 10.229761] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 10.237134] task: ed49e400 task.stack: ed724000 [ 10.242934] PC is at gsc_wait_reset+0x5c/0x6c [exynos_gsc] [ 10.249710] LR is at gsc_probe+0x300/0x33c [exynos_gsc] [ 10.256139] pc : []lr : []psr: 60070013 [ 10.256139] sp : ed725d30 ip : fp : 0001 [ 10.271492] r10: eea74800 r9 : ecd6a2c0 r8 : ed7d8854 [ 10.277912] r7 : ed7d8c08 r6 : ed7d8810 r5 : 8ecd r4 : c0c03900 [ 10.285664] r3 : r2 : 0001 r1 : ed7d8b98 r0 : ed7d8810 So only do a GSC reset if CONFIG_PM is disabled, since if is enabled the runtime PM resume callback will be called by the VIDIOC_STREAMON ioctl, making the reset in probe unneeded. Fixes: 15f90ab57acc ("[media] exynos-gsc: Make driver functional when CONFIG_PM is unset") Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com> Frankly, I don't get why this change is needed. Yes, it seems $SUBJECT is just papering over the real issue. There's something really wrong with the Exynos power domains, I see that PDs can't be disabled by the genpd framework, exynos_pd_power_off() fail: # dmesg | grep power-domain [4.893318] Power domain power-domain@10044020 disable failed [4.893342] Power domain power-domain@10044120 disable failed [4.893711] Power domain power-domain@10044000 disable failed [ 12.690052] Power domain power-domain@10044000 disable failed [ 12.703963] Power domain power-domain@10044000 disable failed So PD are kept on even when unused / attached devices are suspended. Only the mfc_pd (power-domain@10044060) is correctly turned off. # cat /sys/kernel/debug/pm_genpd/pm_genpd_summary domain status slaves /device runtime status -- power-domain@100440C0 on /devices/platform/soc/1445.mixeractive /devices/platform/soc/1453.hdmi active power-domain@10044120 on power-domain@10044060 off-0 /devices/platform/soc/1100.codecsuspended power-domain@10044020 on power-domain@10044000 on /devices/platform/soc/13e0.video-scaler suspended /devices/platform/soc/13e1.video-scaler suspended Also when removing the exynos_gsc driver, I get the same error: # rmmod s5p_mfc [ 106.405972] s5p-mfc 1100.codec: Removing 1100.codec # rmmod exynos_gsc [ 227.008559] Unhandled fault
Re: [PATCH 1/2] ARM: dts: Add TOPEET itop core board SCP package version
regulator-max-microvolt = <180>; + op_mode = <1>; /* Normal Mode */ + }; + + ldo28_reg: LDO28 { + regulator-name = "DVDD12"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + op_mode = <1>; /* Normal Mode */ + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <85>; + regulator-max-microvolt = <110>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <85>; + regulator-max-microvolt = <1456250>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck3_reg: BUCK3 { + regulator-name = "vdd_int"; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <120>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck4_reg: BUCK4 { + regulator-name = "vdd_g3d"; + regulator-min-microvolt = <75>; + regulator-max-microvolt = <150>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck5_reg: BUCK5 { + regulator-name = "vdd_m12"; + regulator-min-microvolt = <75>; + regulator-max-microvolt = <150>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck6_reg: BUCK6 { + regulator-name = "vdd12_5m"; + regulator-min-microvolt = <75>; + regulator-max-microvolt = <150>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck7_reg: BUCK7 { + regulator-name = "pvdd_buck7"; + regulator-min-microvolt = <75>; + regulator-max-microvolt = <200>; + regulator-boot-on; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck8_reg: BUCK8 { + regulator-name = "pvdd_buck8"; + regulator-min-microvolt = <75>; + regulator-max-microvolt = <150>; + regulator-boot-on; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck9_reg: BUCK9 { + regulator-name = "vddf28_emmc"; + regulator-min-microvolt = <75>; + regulator-max-microvolt = <300>; + op_mode = <1>; /* Normal Mode */ + }; + }; + }; +}; + +_1 { + hsic_reset: hsic-reset { + samsung,pins = "gpm2-4"; + samsung,pin-function = <1>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; +}; + + { + samsung,mfc-r = <0x4300 0x80>; + samsung,mfc-l = <0x5100 0x80>; + status = "okay"; +}; Since v4.8-rc1 MFC driver has been converted to generic reserved memory bindings, so samsung,mfc-* properties are obsoleted and no longer used. If you want to use MFC driver with reserved memory, please just add following line to your dts: #include "exynos-mfc-reserved-memory.dtsi" Please refer to dts of other boards for more examples. + +_0 { + pinctrl-0 = <_clk _cmd _bus4 _bus8>; + pinctrl-names = "default"; + status = "okay"; + vmmc-supply = <_reg>; + + num-slots = <1>; + broken-cd; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + bus-width = <8>; + cap-mmc-highspeed; +}; + + { + status = "okay"; +}; + + { + vusb_d-supply = <_reg>; + vusb_a-supply = <_reg>; +}; + + { + status = "okay"; +}; Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 5/7] arm64: dts: exynos: Add dts files for Samsung Exynos5433 64bit SoC
Hello, On 2016-08-16 08:35, Chanwoo Choi wrote: This patch adds new Exynos5433 dtsi to support 64-bit Exynos5433 SoC based on Octa-core CPUs (quad Cortex-A57 and quad Cortex-A53). And Exynos5433 supports PSCI (Power State Coordination Interface) v0.1. This patch includes following Device Tree node to support Exynos5433 SoC: 1. Octa cores for big.LITTLE architecture - Cortex-A53 LITTLE Quad-core - Cortex-A57 big Quad-core - Support PSCI v0.1 2. Clock controller node - CMU_TOP : clocks for IMEM/FSYS/G3D/GSCL/HEVC/MSCL/G2D/MFC/PERIC/PERIS - CMU_CPIF : clocks for LLI (Low Latency Interface) - CMU_MIF : clocks for DRAM Memory Controller - CMU_PERIC : clocks for UART/I2C/SPI/I2S/PCM/SPDIF/PWM/SLIMBUS - CMU_PERIS : clocks for PMU/TMU/MCT/WDT/RTC/SECKEY/TZPC - CMU_FSYS : clocks for USB/UFS/SDMMC/TSI/PDMA - CMU_G2D : clocks for G2D/MDMA - CMU_DISP : clocks for DECON/HDMI/DSIM/MIXER - CMU_AUD : clocks for Cortex-A5/BUS/AUDIO - CMU_BUS{0|1|2} : clocks for global data buses and global peripheral buses - CMU_G3D : clocks for 3D Graphics Engine - CMU_GSCL : clocks for GSCALER - CMU_APOLLO: clocks for Cortex-A53 Quad-core processor. - CMU_ATLAS : clocks for Cortex-A57 Quad-core processor, CoreSight and L2 cache controller. - CMU_MSCL : clocks for M2M (Memory to Memory) scaler and JPEG IPs. - CMU_MFC : clocks for MFC (Multi-Format Codec) IP. - CMU_HEVC : clocks for HEVC(High Efficiency Video Codec) decoder IP. - CMU_ISP : clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs. - CMU_CAM0 : clocks for MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1} IPs. - CMU_CAM1 : clocks for COrtex-A5/MIPI_CSIS2/FIMC_LITE_C/FIMC-FD IPs. 3. pinctrl node for GPIO - alive/aud/cpif/ese/finger/fsys/imem/nfc/peric/touch pad 4. Timer - ARM architecture timer (armv8-timer) - MCT (Multi Core Timer) timer 5. Interrupt controller (GIC-400) 6. BUS devices - HS-I2C (High-Speed I2C) device - SPI (Serial Peripheral Interface) device 7. Sound devices - I2S bus - LPASS (Low Power Audio Subsystem) 8. Power management devices - CPUFREQ for for Cortex-A53/A57 - TMU (Thermal Management Unit) for Cortex-A53/A57, G3D, ISP 9. Display controller devices - DECON (Display and enhancement controller) for panel output - DSI (Display Serial Interface) - MIC (Mobile Image Compressor) - IOMMU for GSCL/DECON/TV/MFC/JPEG/FLITE/3AA/FIMC I would prefer to instantiate only SYSMMU controllers for the devices that have been already added, so initially there will by only SYSMMUs for DECON. Other (GSCL, TV, MFC, JPEG, CAMERA ISP) can be added later together with respective master device nodes. 10. USB - USB 3.0 DRD (Dual Role Device) controller - USB 3.0 Host controller 11. Storage devices - MSHC (Mobile Stoarage Host Controller) 12. Misc devices - UART device - ADC (Analog Digital Converter) - PWM (Pulse Width Modulation) - ADMA (Advanced DMA) and PDMA (Peripheral DMA) Signed-off-by: Chanwoo Choi <cw00.c...@samsung.com> Signed-off-by: Jaehoon Chung <jh80.ch...@samsung.com> Signed-off-by: Seung-Woo Kim <sw0312@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.s...@samsung.com> Signed-off-by: Inki Dae <inki@samsung.com> Signed-off-by: Jonghwa Lee <jonghwa3@samsung.com> Signed-off-by: Beomho Seo <beomho@samsung.com> Signed-off-by: Jaewon Kim <jaewon02@samsung.com> Signed-off-by: Hyungwon Hwang <human.hw...@samsung.com> Signed-off-by: Inha Song <ideal.s...@samsung.com> Signed-off-by: Ingi kim <ingi2@samsung.com> Signed-off-by: Krzysztof Kozlowski <k.kozlow...@samsung.com> Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com> Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawro...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi | 794 ++ .../dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi | 23 + .../dts/exynos/exynos5433-tmu-sensor-conf.dtsi | 22 + arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi | 306 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 1580 5 files changed, 2725 insertions(+) create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi create mode 100644 arch/arm64/boot/dts/exynos/exynos5433.dtsi (snipped) Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 3/4] dt-binding: remoteproc: venus rproc dt binding document
Hi, On 2016-09-01 16:58, Stanimir Varbanov wrote: Hi, Cc: Marek ... But I presume we have the implementation issue of dma_alloc_coherent() failing in either case with the 5MB size. I think we need to look into I'd be good to include Marek Szyprowski? At least he will know what design restrictions there are. Please do. The more I look at this the more I think we must use the existing infrastructure for allocating "dma memory". Getting dma_alloc_coherent() supporting non-power-of-2 memory regions would Just to be precise it should be dma_alloc_from_coherent(). Marek, what is your opinion on that, can we make dma_alloc_from_coherent able to allocate memory for sizes with bigger granularity. For your convenience here [1] is the mail thread. There should be no technical restrictions to add support for bigger granularity than power-of-2. dma_alloc_from_coherent uses standard bitmap based allocator, so it already support tracking allocations of arbitrary size. However for the small allocations (smaller than 64KiB?, 512KiB?) it would make sense to keep nearest-power-of-2 round up to prevent memory fragmentation. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v3 2/2] iommu/exynos: Add proper runtime pm support
ight check if all needed signals from DMA engine HW are ready. If not it will fail to start avoid lockup of starting without DMA engine HW being ready. However I don't have much experience with DMA engine and drivers. I only helped in adding DMA engine support to Samsung UART driver and in the hardware manual there is information about additional lines between DMA controller and UART module, which are used in the DMA mode. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland