* [PATCH 2/4] clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
From: Chanwoo Choi @ 2017-01-16 3:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-3-krzk@kernel.org>
Hi,
On 2017? 01? 14? 21:36, Krzysztof Kozlowski wrote:
> Support for Exynos4415 is going away because there are no internal nor
> external users.
>
> Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
> the platform cannot be instantiated so remove also the drivers.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
> .../devicetree/bindings/clock/exynos4415-clock.txt | 38 -
> drivers/clk/samsung/Makefile | 1 -
> drivers/clk/samsung/clk-exynos4415.c | 1022 --------------------
> include/dt-bindings/clock/exynos4415.h | 360 -------
> 4 files changed, 1421 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
> delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
> delete mode 100644 include/dt-bindings/clock/exynos4415.h
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
[snip]
--
Best Regards,
Chanwoo Choi
S/W Center, Samsung Electronics
^ permalink raw reply
* [PATCH 3/4] pinctrl: samsung: Remove support for Exynos4415 (SoC not supported anymore)
From: Chanwoo Choi @ 2017-01-16 3:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-4-krzk@kernel.org>
On 2017? 01? 14? 21:36, Krzysztof Kozlowski wrote:
> Support for Exynos4415 is going away because there are no internal nor
> external users.
>
> Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
> the platform cannot be instantiated so remove also the drivers.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
> drivers/pinctrl/samsung/pinctrl-exynos.c | 75 -------------------------------
> drivers/pinctrl/samsung/pinctrl-samsung.c | 2 -
> drivers/pinctrl/samsung/pinctrl-samsung.h | 1 -
> 3 files changed, 78 deletions(-)
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
[snip]
--
Best Regards,
Chanwoo Choi
S/W Center, Samsung Electronics
^ permalink raw reply
* [PATCH 1/4] ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
From: Chanwoo Choi @ 2017-01-16 3:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-2-krzk@kernel.org>
On 2017? 01? 14? 21:36, Krzysztof Kozlowski wrote:
> Support for Exynos4415 is going away because there are no internal nor
> external users.
>
> Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
> the platform cannot be instantiated so remove also the mach code.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
> arch/arm/mach-exynos/Kconfig | 5 -----
> arch/arm/mach-exynos/exynos.c | 1 -
> arch/arm/mach-exynos/suspend.c | 1 -
> 3 files changed, 7 deletions(-)
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
[snip]
--
Best Regards,
Chanwoo Choi
S/W Center, Samsung Electronics
^ permalink raw reply
* [PATCH v1 1/3] dt: bindings: add documentation for zx2967 family watchdog controller
From: Baoyou Xie @ 2017-01-16 4:19 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds dt-binding documentation for zx2967 family
watchdog controller.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
.../bindings/watchdog/zte,zx2967-wdt.txt | 29 ++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
diff --git a/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt b/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
new file mode 100644
index 0000000..0fe0d40
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
@@ -0,0 +1,29 @@
+ZTE zx2967 Watchdog timer
+
+Required properties:
+
+- compatible : should be one of the following.
+ * zte,zx296718-wdt
+- reg : Specifies base physical address and size of the registers.
+- clocks : Pairs of phandle and specifier referencing the controller's clocks.
+- clock-names: "wdtclk" for the watchdog clock.
+- resets : Reference to the reset controller controlling the watchdog
+ controller.
+- reset-names : Must include the following entries:
+ * wdtrst
+
+Optional properties:
+
+- reset-mask-config : Mask and configuare value that be wrote to aon-sysctrl.
+
+Example:
+
+wdt_ares: watchdog at 1465000 {
+ compatible = "zte,zx296718-wdt";
+ reg = <0x1465000 0x1000>;
+ clocks = <&topcrm WDT_WCLK>;
+ clock-names = "wdtclk";
+ resets = <&toprst 35>;
+ reset-names = "wdtrst";
+ reset-mask-config = <1 0x115>;
+};
--
2.7.4
^ permalink raw reply related
* [PATCH v1 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-16 4:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484540395-3335-1-git-send-email-baoyou.xie@linaro.org>
Add the zx2967 watchdog controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
MAINTAINERS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 08f8155..77f0290 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1983,11 +1983,13 @@ F: drivers/clk/zte/
F: drivers/reset/reset-zx2967.c
F: drivers/soc/zte/
F: drivers/thermal/zx*
+F: drivers/watchdog/zx2967_wdt.c
F: Documentation/devicetree/bindings/arm/zte.txt
F: Documentation/devicetree/bindings/clock/zx296702-clk.txt
F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
F: Documentation/devicetree/bindings/soc/zte/
F: Documentation/devicetree/bindings/thermal/zx*
+F: Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
F: include/dt-bindings/soc/zx*.h
ARM/ZYNQ ARCHITECTURE
--
2.7.4
^ permalink raw reply related
* [PATCH v1 3/3] watchdog: zx2967: add watchdog controller driver for ZTE's zx2967 family
From: Baoyou Xie @ 2017-01-16 4:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484540395-3335-1-git-send-email-baoyou.xie@linaro.org>
This patch adds watchdog controller driver for ZTE's zx2967 family.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
drivers/watchdog/Kconfig | 10 ++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/zx2967_wdt.c | 405 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 416 insertions(+)
create mode 100644 drivers/watchdog/zx2967_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3eb58cb..79027da 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -714,6 +714,16 @@ config ASPEED_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called aspeed_wdt.
+config ZX2967_WATCHDOG
+ tristate "ZTE zx2967 SoCs watchdog support"
+ depends on ARCH_ZX
+ select WATCHDOG_CORE
+ help
+ Say Y here to include support for the watchdog timer
+ in ZTE zx2967 SoCs.
+ To compile this driver as a module, choose M here: the
+ module will be called zx2967_wdt.
+
# AVR32 Architecture
config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index caa9f4a..ea08925 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o
obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o
obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o
obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o
+obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c
new file mode 100644
index 0000000..8791dd2
--- /dev/null
+++ b/drivers/watchdog/zx2967_wdt.c
@@ -0,0 +1,405 @@
+/*
+ * watchdog driver for ZTE's zx2967 family
+ *
+ * Copyright (C) 2017 ZTE Ltd.
+ *
+ * Author: Baoyou Xie <baoyou.xie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/reset.h>
+#include <linux/watchdog.h>
+
+#define ZX2967_WDT_CFG_REG 0x4
+#define ZX2967_WDT_LOAD_REG 0x8
+#define ZX2967_WDT_REFRESH_REG 0x18
+#define ZX2967_WDT_START_REG 0x1c
+
+#define ZX2967_WDT_REFRESH_MASK 0x3f
+
+#define ZX2967_WDT_CFG_DIV(n) ((((n)&0xff) - 1) << 8)
+#define ZX2967_WDT_START_EN 0x1
+
+#define ZX2967_WDT_WRITEKEY 0x12340000
+
+#define ZX2967_WDT_DIV_DEFAULT 16
+#define ZX2967_WDT_DEFAULT_TIMEOUT 32
+#define ZX2967_WDT_MIN_TIMEOUT 1
+#define ZX2967_WDT_MAX_TIMEOUT 500
+#define ZX2967_WDT_MAX_COUNT 0xffff
+
+#define ZX2967_WDT_FLAG_REBOOT_MON (1 << 0)
+
+#define ZX2967_RESET_MASK_REG 0xb0
+
+#define zx2967_wdt_write_reg(v, r) \
+ writel((v) | ZX2967_WDT_WRITEKEY, r)
+#define zx2967_wdt_read_reg(r) readl(r)
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+static unsigned int timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
+
+struct zx2967_wdt {
+ struct device *dev;
+ struct clk *clock;
+ void __iomem *reg_base;
+ unsigned int conf;
+ unsigned int load;
+ unsigned int flags;
+ spinlock_t lock;
+ struct watchdog_device wdt_device;
+ struct notifier_block restart_handler;
+ struct notifier_block reboot_handler;
+};
+
+static void zx2967_wdt_refresh(struct zx2967_wdt *wdt)
+{
+ unsigned int val;
+
+ spin_lock(&wdt->lock);
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_REFRESH_REG);
+ val ^= ZX2967_WDT_REFRESH_MASK;
+ zx2967_wdt_write_reg(val, wdt->reg_base + ZX2967_WDT_REFRESH_REG);
+
+ spin_unlock(&wdt->lock);
+}
+
+static void __zx2967_wdt_stop(struct zx2967_wdt *wdt)
+{
+ unsigned int val;
+
+ spin_lock(&wdt->lock);
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_START_REG);
+ val &= ~(ZX2967_WDT_START_EN);
+ zx2967_wdt_write_reg(val, wdt->reg_base + ZX2967_WDT_START_REG);
+
+ spin_unlock(&wdt->lock);
+}
+
+static void __zx2967_wdt_start(struct zx2967_wdt *wdt)
+{
+ unsigned int val;
+
+ spin_lock(&wdt->lock);
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_START_REG);
+ val |= ZX2967_WDT_START_EN;
+ zx2967_wdt_write_reg(val, wdt->reg_base + ZX2967_WDT_START_REG);
+
+ spin_unlock(&wdt->lock);
+}
+
+static unsigned int
+__zx2967_wdt_set_timeout(struct zx2967_wdt *wdt, unsigned int timeout)
+{
+ unsigned int freq = clk_get_rate(wdt->clock);
+ unsigned int divisor = ZX2967_WDT_DIV_DEFAULT, count;
+
+ count = timeout * freq;
+ if (count > divisor * ZX2967_WDT_MAX_COUNT)
+ divisor = DIV_ROUND_UP(count, ZX2967_WDT_MAX_COUNT);
+ count = DIV_ROUND_UP(count, divisor);
+ zx2967_wdt_write_reg(ZX2967_WDT_CFG_DIV(divisor),
+ wdt->reg_base + ZX2967_WDT_CFG_REG);
+ zx2967_wdt_write_reg(count, wdt->reg_base + ZX2967_WDT_LOAD_REG);
+ zx2967_wdt_refresh(wdt);
+
+ wdt->load = count;
+ dev_info(wdt->dev, "count=%d, timeout=%d, divisor=%d\n",
+ count, timeout, divisor);
+
+ return (count * divisor) / freq;
+}
+
+static int zx2967_wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int timeout)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ if (watchdog_timeout_invalid(&wdt->wdt_device, timeout)) {
+ dev_err(wdt->dev, "timeout %d is invalid\n", timeout);
+
+ return -EINVAL;
+ }
+
+ wdd->timeout = __zx2967_wdt_set_timeout(wdt, timeout);
+
+ return 0;
+}
+
+static int zx2967_wdt_start(struct watchdog_device *wdd)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ __zx2967_wdt_stop(wdt);
+ zx2967_wdt_set_timeout(wdd, wdd->timeout);
+ __zx2967_wdt_start(wdt);
+
+ return 0;
+}
+
+static int zx2967_wdt_stop(struct watchdog_device *wdd)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ __zx2967_wdt_stop(wdt);
+
+ return 0;
+}
+
+static int zx2967_wdt_keepalive(struct watchdog_device *wdd)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ zx2967_wdt_refresh(wdt);
+
+ return 0;
+}
+
+#define ZX2967_WDT_OPTIONS \
+ (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
+static const struct watchdog_info zx2967_wdt_ident = {
+ .options = ZX2967_WDT_OPTIONS,
+ .firmware_version = 0,
+ .identity = "zx2967 watchdog",
+};
+
+static struct watchdog_ops zx2967_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = zx2967_wdt_start,
+ .stop = zx2967_wdt_stop,
+ .ping = zx2967_wdt_keepalive,
+ .set_timeout = zx2967_wdt_set_timeout,
+};
+
+static void zx2967_wdt_fix_sysdown(struct zx2967_wdt *wdt)
+{
+ __zx2967_wdt_stop(wdt);
+ __zx2967_wdt_set_timeout(wdt, 15);
+ __zx2967_wdt_start(wdt);
+}
+
+static int zx2967_wdt_notify_sys(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ struct zx2967_wdt *wdt = container_of(this, struct zx2967_wdt,
+ reboot_handler);
+
+ wdt->flags |= ZX2967_WDT_FLAG_REBOOT_MON;
+ switch (code) {
+ case SYS_HALT:
+ case SYS_POWER_OFF:
+ case SYS_RESTART:
+ zx2967_wdt_fix_sysdown(wdt);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int zx2967_wdt_restart(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+ struct zx2967_wdt *wdt;
+
+ wdt = container_of(this, struct zx2967_wdt, restart_handler);
+
+ zx2967_wdt_stop(&wdt->wdt_device);
+
+ zx2967_wdt_write_reg(0x80, wdt->reg_base + ZX2967_WDT_LOAD_REG);
+ zx2967_wdt_refresh(wdt);
+ zx2967_wdt_write_reg(ZX2967_WDT_START_EN,
+ wdt->reg_base + ZX2967_WDT_START_REG);
+
+ zx2967_wdt_start(&wdt->wdt_device);
+ /* wait for reset*/
+ mdelay(500);
+
+ return NOTIFY_DONE;
+}
+
+static void zx2967_reset_mask_config(struct device *dev)
+{
+ struct device_node *np = NULL;
+ void __iomem *reg;
+ unsigned int val, mask, config, size;
+ const unsigned int *prop;
+
+ prop = of_get_property(dev->of_node, "reset-mask-config", &size);
+ if (size < (sizeof(*prop) * 2)) {
+ dev_err(dev, "bad data for reset-mask-config");
+ return;
+ }
+ config = be32_to_cpup(prop++);
+ mask = be32_to_cpup(prop);
+ np = of_find_compatible_node(NULL, NULL, "zte,aon-sysctrl");
+ if (!np) {
+ dev_err(dev, "Cannot found pcu device node\n");
+ return;
+ }
+ reg = of_iomap(np, 0) + ZX2967_RESET_MASK_REG;
+ of_node_put(np);
+
+ val = readl(reg);
+ val &= ~mask;
+ val |= config;
+ writel(val, reg);
+}
+
+static int zx2967_wdt_probe(struct platform_device *pdev)
+{
+ struct device *dev;
+ struct zx2967_wdt *wdt;
+ struct resource *base;
+ int err, ret = 0;
+ unsigned int rate, val;
+
+ struct reset_control *rstc;
+
+ dev = &pdev->dev;
+
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ platform_set_drvdata(pdev, wdt);
+
+ wdt->dev = dev;
+ spin_lock_init(&wdt->lock);
+
+ wdt->wdt_device.info = &zx2967_wdt_ident;
+ wdt->wdt_device.ops = &zx2967_wdt_ops;
+ wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
+ wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT;
+ wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT;
+ wdt->wdt_device.parent = &pdev->dev;
+
+ base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ wdt->reg_base = devm_ioremap_resource(dev, base);
+
+ if (of_find_property(dev->of_node, "reset-mask-config", NULL))
+ zx2967_reset_mask_config(dev);
+
+ wdt->reboot_handler.notifier_call = zx2967_wdt_notify_sys;
+ ret = register_reboot_notifier(&wdt->reboot_handler);
+ wdt->clock = devm_clk_get(dev, "wdtclk");
+ if (IS_ERR(wdt->clock)) {
+ dev_err(dev, "failed to find watchdog clock source\n");
+ ret = PTR_ERR(wdt->clock);
+ goto out;
+ }
+ ret = clk_prepare_enable(wdt->clock);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable clock\n");
+ goto out;
+ }
+
+ rate = clk_get_rate(wdt->clock);
+ if (rate == 24000000)
+ ret = clk_set_rate(wdt->clock, 32768);
+ rate = clk_get_rate(wdt->clock);
+
+ rstc = devm_reset_control_get(dev, "wdtrst");
+ if (!rstc) {
+ dev_info(dev, "rstc get failed");
+ } else {
+ reset_control_assert(rstc);
+ mdelay(10);
+ reset_control_deassert(rstc);
+ }
+
+ watchdog_set_drvdata(&wdt->wdt_device, wdt);
+
+ watchdog_init_timeout(&wdt->wdt_device, timeout, &pdev->dev);
+ watchdog_set_nowayout(&wdt->wdt_device, nowayout);
+
+ zx2967_wdt_stop(&wdt->wdt_device);
+
+ err = watchdog_register_device(&wdt->wdt_device);
+ if (unlikely(err)) {
+ ret = err;
+ goto fail_register;
+ }
+
+ wdt->restart_handler.notifier_call = zx2967_wdt_restart;
+ wdt->restart_handler.priority = 128;
+ ret = register_restart_handler(&wdt->restart_handler);
+ if (ret) {
+ pr_err("cannot register restart handler, %d\n", ret);
+ goto fail_restart;
+ }
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_START_REG);
+ dev_info(&pdev->dev, "watchdog enabled (timeout=%d sec, nowayout=%d)",
+ wdt->wdt_device.timeout, nowayout);
+
+ return 0;
+
+fail_restart:
+ watchdog_unregister_device(&wdt->wdt_device);
+fail_register:
+ clk_disable_unprepare(wdt->clock);
+out:
+ return ret;
+}
+
+static int zx2967_wdt_remove(struct platform_device *pdev)
+{
+ struct zx2967_wdt *wdt = platform_get_drvdata(pdev);
+
+ unregister_restart_handler(&wdt->restart_handler);
+ watchdog_unregister_device(&wdt->wdt_device);
+ clk_disable_unprepare(wdt->clock);
+
+ return 0;
+}
+
+static void zx2967_wdt_shutdown(struct platform_device *pdev)
+{
+ struct zx2967_wdt *wdt = platform_get_drvdata(pdev);
+
+ if (!(wdt->flags & ZX2967_WDT_FLAG_REBOOT_MON))
+ zx2967_wdt_stop(&wdt->wdt_device);
+}
+
+static const struct of_device_id zx2967_wdt_match[] = {
+ { .compatible = "zte,zx296718-wdt", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, zx2967_wdt_match);
+
+static const struct platform_device_id zx2967_wdt_ids[] = {
+ { .name = "zx2967-wdt", },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, zx2967_wdt_ids);
+
+static struct platform_driver zx2967_wdt_driver = {
+ .probe = zx2967_wdt_probe,
+ .remove = zx2967_wdt_remove,
+ .shutdown = zx2967_wdt_shutdown,
+ .id_table = zx2967_wdt_ids,
+ .driver = {
+ .name = "zx2967-wdt",
+ .of_match_table = of_match_ptr(zx2967_wdt_match),
+ },
+};
+module_platform_driver(zx2967_wdt_driver);
+
+MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
+MODULE_DESCRIPTION("ZTE zx2967 Watchdog Device Driver");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCH 4/4] clk: rockchip: add rk3288 cif_out clock
From: Jacob Chen @ 2017-01-16 4:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2707876.A5Xp7pLXJo@phil>
2017-01-13 21:53 GMT+08:00 Heiko Stuebner <heiko@sntech.de>:
> Hi Jacob,
>
> Am Dienstag, 10. Januar 2017, 19:59:20 CET schrieb Jacob Chen:
>> Add the clocks for the cif block of the rk3288
>>
>> Signed-off-by: Jacob Chen <jacob-chen@iotwrt.com>
>> ---
>> drivers/clk/rockchip/clk-rk3288.c | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/clk/rockchip/clk-rk3288.c
>> b/drivers/clk/rockchip/clk-rk3288.c index 8047cea..f071c24 100644
>> --- a/drivers/clk/rockchip/clk-rk3288.c
>> +++ b/drivers/clk/rockchip/clk-rk3288.c
>> @@ -192,6 +192,7 @@ PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac",
>> "xin24m" }; PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
>> PNAME(mux_uart3_p) = { "uart3_src", "uart3_frac", "xin24m" };
>> PNAME(mux_uart4_p) = { "uart4_src", "uart4_frac", "xin24m" };
>> +PNAME(mux_cif_out_p) = { "cif_src", "xin24m" };
>> PNAME(mux_vip_out_p) = { "vip_src", "xin24m" };
>> PNAME(mux_mac_p) = { "mac_pll_src", "ext_gmac" };
>> PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
>> @@ -448,6 +449,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[]
>> __initdata = { RK3288_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS,
>> RK3288_CLKGATE_CON(3), 15, GFLAGS),
>>
>> + COMPOSITE_NOGATE(0, "cif_src", mux_pll_src_cpll_gpll_p, 0,
>> + RK3288_CLKSEL_CON(26), 8, 1, MFLAGS, 9, 5, DFLAGS),
>> + COMPOSITE_NODIV(SCLK_CIF_OUT, "sclk_cif_out", mux_cif_out_p, 0,
>> + RK3288_CLKSEL_CON(26), 15, 1, MFLAGS,
>> + RK3288_CLKGATE_CON(3), 7, GFLAGS),
>> +
>
> we already have vip_src and sclk_vip_out defined, which I guess are the clocks
> you are adding here and according to the TRM I have the names are also correct
> (clock diagram 2).
>
> But the clkid is not set yet, so I'd suggest adding SCLK_VIP_OUT and assigning
> to the existing clocks.
>
> Also, according to the clock diagram, the gate needs to be (and already is)
> part of the vip_src clock and not the sclk_vip_out.
>
>
> Heiko
Right, I didn't find that it have already been defined..
^ permalink raw reply
* [PATCH v7 00/15] ACPI platform MSI support and its example mbigen
From: Sinan Kaya @ 2017-01-16 5:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484147199-4267-1-git-send-email-hanjun.guo@linaro.org>
Hi Hanjun,
On 1/11/2017 10:06 AM, Hanjun Guo wrote:
> With platform msi support landed in the kernel, and the introduction
> of IORT for GICv3 ITS (PCI MSI) and SMMU, the framework for platform msi
> is ready, this patch set add few patches to enable the ACPI platform
> msi support.
>
> For platform device connecting to ITS on arm platform, we have IORT
> table with the named componant node to describe the mappings of paltform
> device and ITS, so we can retrieve the dev id and find its parent
> irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).
>
> v6 -> v7:
> - Introduce iort_node_map_platform_id() to retrieve the
> dev id for both NC (named component) -> ITS/SMMU and
> NC -> SMMU -> ITS cases, suggested by Lorenzo;
>
> - Reorder the patches and rewrite some commit message;
>
> - Remove the test tags because it has major changes
> to retrieve the dev id, Sinan, Majun, Xinwei, could
> you please test them again on your platform?
>
> - rebased on top of 4.10-rc3 and Lorenzo's patch
> https://patchwork.kernel.org/patch/9507041/
>
> - Tested against Agustin's patch [1-2/3] "[PATCH V9 0/3] irqchip: qcom:
> Add IRQ combiner driver"
>
> v5 -> v6:
> - Call acpi_configure_pmsi_domain() for platform devices in
> acpi_platform_notify() as it's cleaner (suggested by Rafael)
> - Remove the "u8 type" for iort_id_map() because it's unused
> - Rebase on top of 4.10-rc2
> - Collect test and review tags
>
> v4 -> v5:
> - Add mbigen support back with tested on with Agustin's patchset,
> and it's a good example of how ACPI platform MSI works
> - rebased on top of lastest Linus tree (commit 52bce91 splice: reinstate SIGPIPE/EPIPE handling)
>
> v3 -> v4:
> - Drop mbi-gen patches to just submit platform msi support because
> will rebase mbi-gen patches on top of Agustin's patchset, and discusion
> is going there.
> - Add a patch to support device topology such as NC(named componant, paltform device)
> ->SMMU->ITS which suggested by Lorenzo;
> - rebased on top of Lorenzo's v9 of ACPI IORT ARM SMMU support;
> - rebased on top of 4.9-rc7
>
> v2 -> v3:
> - Drop RFC tag
> - Rebase against v4.9-rc2 and Lorenzo's v6 of ACPI IORT ARM SMMU support [1]
> - Add 3 cleanup patches (patch 1, 2, 3)
> - Drop arch_init call patch from last version
> - Introduce a callback for platform device to set msi domain
> - Introduce a new API to get paltform device's domain instead of
> reusing the PCI one in previous version
> - Add a patch to rework iort_node_get_id()
>
> [1]: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1251993.html
>
> v1 -> v2:
> - Fix the bug of if multi Interrupt() resoures in single _PRS,
> we need to calculate all the irq numbers (I missed it in previous
> version);
> - Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5
> SMMU patches (also Robin's SMMu patches)
> - Add patch irqchip: mbigen: promote mbigen init.
>
>
> Hanjun Guo (13):
> ACPI: IORT: fix the indentation in iort_scan_node()
> ACPI: IORT: add missing comment for iort_dev_find_its_id()
> ACPI: IORT: minor cleanup for iort_match_node_callback()
> irqchip: gic-v3-its: keep the head file include in alphabetic order
> irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
> irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
> for ACPI
> irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
> domain
> ACPI: IORT: rename iort_node_map_rid() to make it generic
> ACPI: platform-msi: retrieve dev id from IORT
> ACPI: IORT: move over to iort_node_map_platform_id()
> ACPI: platform: setup MSI domain for ACPI based platform device
> msi: platform: make platform_msi_create_device_domain() ACPI aware
> irqchip: mbigen: Add ACPI support
>
> Kefeng Wang (2):
> irqchip: mbigen: drop module owner
> irqchip: mbigen: introduce mbigen_of_create_domain()
>
> drivers/acpi/arm64/iort.c | 161 +++++++++++++++++++++-----
> drivers/acpi/glue.c | 6 +
> drivers/base/platform-msi.c | 3 +-
> drivers/irqchip/irq-gic-v3-its-platform-msi.c | 106 +++++++++++++----
> drivers/irqchip/irq-gic-v3-its.c | 3 +-
> drivers/irqchip/irq-mbigen.c | 109 ++++++++++++++---
> include/linux/acpi_iort.h | 11 ++
> 7 files changed, 322 insertions(+), 77 deletions(-)
>
I tested the v7 series along with Lorenzo's patch using HIDMA and MSI interrupts.
Everything checked out OK.
Tested-by: Sinan Kaya <okaya@codeaurora.org>
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH 09/37] PCI: dwc: designware: Parse *num-lanes* property in dw_pcie_setup_rc
From: Kishon Vijay Abraham I @ 2017-01-16 5:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c3c55af3-29d1-dc59-3ae4-9a4132c99092@synopsys.com>
Hi,
On Friday 13 January 2017 10:43 PM, Joao Pinto wrote:
> Hi,
>
> ?s 10:25 AM de 1/12/2017, Kishon Vijay Abraham I escreveu:
>> *num-lanes* dt property is parsed in dw_pcie_host_init. However
>> *num-lanes* property is applicable to both root complex mode and
>> endpoint mode. As a first step, move the parsing of this property
>> outside dw_pcie_host_init. This is in preparation for splitting
>> pcie-designware.c to pcie-designware.c and pcie-designware-host.c
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> drivers/pci/dwc/pcie-designware.c | 18 +++++++++++-------
>> drivers/pci/dwc/pcie-designware.h | 1 -
>> 2 files changed, 11 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
>> index 00a0fdc..89cdb6b 100644
>> --- a/drivers/pci/dwc/pcie-designware.c
>> +++ b/drivers/pci/dwc/pcie-designware.c
>> @@ -551,10 +551,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
>> }
>> }
>>
>> - ret = of_property_read_u32(np, "num-lanes", &pci->lanes);
>> - if (ret)
>> - pci->lanes = 0;
>> -
>> ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
>> if (ret)
>> pci->num_viewport = 2;
>> @@ -751,18 +747,26 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>>
>> void dw_pcie_setup_rc(struct pcie_port *pp)
>> {
>> + int ret;
>> + u32 lanes;
>> u32 val;
>> struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>> + struct device *dev = pci->dev;
>> + struct device_node *np = dev->of_node;
>>
>> /* get iATU unroll support */
>> pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
>> dev_dbg(pci->dev, "iATU unroll: %s\n",
>> pci->iatu_unroll_enabled ? "enabled" : "disabled");
>>
>> + ret = of_property_read_u32(np, "num-lanes", &lanes);
>> + if (ret)
>> + lanes = 0;
>
> You moved from host_init to root complex setup function, which in my opinion did
> not improve (in this scope).
>
> I suggest that instead of making so much intermediary patches, which is nice to
> understand your development sequence, but hard to review. Wouldn't be better to
> condense some of the patches? We would have a cloear vision of the final product :)
I thought the other way. If squashing patches is easier to review, I'll do it.
Btw, thanks for reviewing.
Cheers
Kishon
^ permalink raw reply
* [PATCH 11/37] PCI: dwc: Split pcie-designware.c into host and core files
From: Kishon Vijay Abraham I @ 2017-01-16 5:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4a89fb45-af84-d660-5ef0-12227b141cda@synopsys.com>
Hi Joao,
On Friday 13 January 2017 10:19 PM, Joao Pinto wrote:
> ?s 10:26 AM de 1/12/2017, Kishon Vijay Abraham I escreveu:
>> Split pcie-designware.c into pcie-designware-host.c that contains
>> the host specific parts of the driver and pcie-designware.c that
>> contains the parts used by both host driver and endpoint driver.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> drivers/pci/dwc/Makefile | 2 +-
>> drivers/pci/dwc/pcie-designware-host.c | 619 ++++++++++++++++++++++++++++++++
>> drivers/pci/dwc/pcie-designware.c | 613 +------------------------------
>> drivers/pci/dwc/pcie-designware.h | 8 +
>> 4 files changed, 634 insertions(+), 608 deletions(-)
>> create mode 100644 drivers/pci/dwc/pcie-designware-host.c
>>
>> diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
>> index 7d27c14..3b57e55 100644
>> --- a/drivers/pci/dwc/Makefile
>> +++ b/drivers/pci/dwc/Makefile
>> @@ -1,4 +1,4 @@
>
> (snip...)
>
>> -static void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
>> - int type, u64 cpu_addr, u64 pci_addr,
>> - u32 size)
>> +void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
>> + u64 cpu_addr, u64 pci_addr, u32 size)
>> {
>> u32 retries, val;
>>
>> @@ -186,220 +151,6 @@ static void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
>> dev_err(pci->dev, "iATU is not being enabled\n");
>> }
>
> Kishon, iATU only makes sense in The Root Complex (host), so it should be inside
> the pcie-designware-host.
That is not true. Outbound ATU should be programmed to access host side buffers
and inbound ATU should be programmed for the host to access EP mem space.
Thanks
Kishon
^ permalink raw reply
* [PATCH 12/37] PCI: dwc: Create a new config symbol to enable pci dwc host
From: Kishon Vijay Abraham I @ 2017-01-16 5:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3d34f9c4-7ec4-ac2b-ea7f-18d239dfa554@synopsys.com>
Hi Joao,
On Friday 13 January 2017 11:20 PM, Joao Pinto wrote:
> Hi Kishon,
>
> ?s 10:26 AM de 1/12/2017, Kishon Vijay Abraham I escreveu:
>> Now that pci designware host has a separate file, create a new
>> config symbol to select the host only driver. This is in preparation
>> to enable endpoint support to designware driver.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> drivers/pci/dwc/Kconfig | 26 +++++++++++++++-----------
>> drivers/pci/dwc/Makefile | 3 ++-
>> drivers/pci/dwc/pcie-designware.h | 29 +++++++++++++++++++++++++----
>> 3 files changed, 42 insertions(+), 16 deletions(-)
>>
>
> You are already working in a base where dwc/ already exists. I know you made a
> rename / re-structure patch for pci, but I think it was not yet accepted, right?
> I don't see it in any of Bjorn' dev branches.
He said he'll merge that a little later.
Thanks
Kishon
>
> Thanks.
>
>> diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
>> index 8b08519..d0bdfb5 100644
>> --- a/drivers/pci/dwc/Kconfig
>> +++ b/drivers/pci/dwc/Kconfig
>> @@ -3,13 +3,17 @@ menu "DesignWare PCI Core Support"
>>
>> config PCIE_DW
>> bool
>> +
>> +config PCIE_DW_HOST
>> + bool
>> depends on PCI_MSI_IRQ_DOMAIN
>> + select PCIE_DW
>>
>> config PCI_DRA7XX
>> bool "TI DRA7xx PCIe controller"
>> depends on OF && HAS_IOMEM && TI_PIPE3
>> depends on PCI_MSI_IRQ_DOMAIN
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Enables support for the PCIe controller in the DRA7xx SoC. There
>> are two instances of PCIe controller in DRA7xx. This controller can
>> @@ -18,7 +22,7 @@ config PCI_DRA7XX
>> config PCIE_DW_PLAT
>> bool "Platform bus based DesignWare PCIe Controller"
>> depends on PCI_MSI_IRQ_DOMAIN
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> ---help---
>> This selects the DesignWare PCIe controller support. Select this if
>> you have a PCIe controller on Platform bus.
>> @@ -32,21 +36,21 @@ config PCI_EXYNOS
>> depends on SOC_EXYNOS5440 || COMPILE_TEST
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>>
>> config PCI_IMX6
>> bool "Freescale i.MX6 PCIe controller"
>> depends on SOC_IMX6Q || COMPILE_TEST
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>>
>> config PCIE_SPEAR13XX
>> bool "STMicroelectronics SPEAr PCIe controller"
>> depends on ARCH_SPEAR13XX || COMPILE_TEST
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here if you want PCIe support on SPEAr13XX SoCs.
>>
>> @@ -55,7 +59,7 @@ config PCI_KEYSTONE
>> depends on ARCH_KEYSTONE || COMPILE_TEST
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here if you want to enable PCI controller support on Keystone
>> SoCs. The PCI controller on Keystone is based on Designware hardware
>> @@ -67,7 +71,7 @@ config PCI_LAYERSCAPE
>> depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
>> depends on PCI_MSI_IRQ_DOMAIN
>> select MFD_SYSCON
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here if you want PCIe controller support on Layerscape SoCs.
>>
>> @@ -76,7 +80,7 @@ config PCI_HISI
>> bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers"
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here if you want PCIe controller support on HiSilicon
>> Hip05 and Hip06 SoCs
>> @@ -86,7 +90,7 @@ config PCIE_QCOM
>> depends on (ARCH_QCOM || COMPILE_TEST) && OF
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here to enable PCIe controller support on Qualcomm SoCs. The
>> PCIe controller uses the Designware core plus Qualcomm-specific
>> @@ -97,7 +101,7 @@ config PCIE_ARMADA_8K
>> depends on ARCH_MVEBU || COMPILE_TEST
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here if you want to enable PCIe controller support on
>> Armada-8K SoCs. The PCIe controller on Armada-8K is based on
>> @@ -109,7 +113,7 @@ config PCIE_ARTPEC6
>> depends on MACH_ARTPEC6 || COMPILE_TEST
>> depends on PCI_MSI_IRQ_DOMAIN
>> select PCIEPORTBUS
>> - select PCIE_DW
>> + select PCIE_DW_HOST
>> help
>> Say Y here to enable PCIe controller support on Axis ARTPEC-6
>> SoCs. This PCIe controller uses the DesignWare core.
>> diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
>> index 3b57e55..a2df13c 100644
>> --- a/drivers/pci/dwc/Makefile
>> +++ b/drivers/pci/dwc/Makefile
>> @@ -1,4 +1,5 @@
>> -obj-$(CONFIG_PCIE_DW) += pcie-designware.o pcie-designware-host.o
>> +obj-$(CONFIG_PCIE_DW) += pcie-designware.o
>> +obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
>> obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
>> obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
>> obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
>> diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
>> index 808d17b..8f3dcb2 100644
>> --- a/drivers/pci/dwc/pcie-designware.h
>> +++ b/drivers/pci/dwc/pcie-designware.h
>> @@ -162,10 +162,6 @@ struct dw_pcie {
>>
>> int dw_pcie_read(void __iomem *addr, int size, u32 *val);
>> int dw_pcie_write(void __iomem *addr, int size, u32 val);
>> -irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
>> -void dw_pcie_msi_init(struct pcie_port *pp);
>> -void dw_pcie_setup_rc(struct pcie_port *pp);
>> -int dw_pcie_host_init(struct pcie_port *pp);
>>
>> u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg);
>> void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val);
>> @@ -175,4 +171,29 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
>> int type, u64 cpu_addr, u64 pci_addr,
>> u32 size);
>> void dw_pcie_setup(struct dw_pcie *pci);
>> +
>> +#ifdef CONFIG_PCIE_DW_HOST
>> +irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
>> +void dw_pcie_msi_init(struct pcie_port *pp);
>> +void dw_pcie_setup_rc(struct pcie_port *pp);
>> +int dw_pcie_host_init(struct pcie_port *pp);
>> +#else
>> +static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
>> +{
>> + return IRQ_NONE;
>> +}
>> +
>> +static inline void dw_pcie_msi_init(struct pcie_port *pp)
>> +{
>> +}
>> +
>> +static inline void dw_pcie_setup_rc(struct pcie_port *pp)
>> +{
>> +}
>> +
>> +static inline int dw_pcie_host_init(struct pcie_port *pp)
>> +{
>> + return 0;
>> +}
>> +#endif
>> #endif /* _PCIE_DESIGNWARE_H */
>>
>
^ permalink raw reply
* [PATCH v2 2/7] clk: sunxi-ng: Implement factors offsets
From: Chen-Yu Tsai @ 2017-01-16 5:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2cec4b406a220763208125cde184aee01b27e7e8.1484035021.git-series.maxime.ripard@free-electrons.com>
On Tue, Jan 10, 2017 at 3:57 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The factors we've seen so far all had an offset of one. However, on the
> earlier Allwinner SoCs, some factors could have no offset at all, meaning
> that the value computed to reach the rate we want to use was the one we had
> to program in the registers.
>
> Implement an additional field for the factors that can have such an offset
> (linears, not based on a power of two) to specify that offset.
>
> This offset is not linked to the extremums that can be specified in those
> structures too. The minimum and maximum are representing the range of
> values we can use to try to compute the best rate. The offset comes later
> on when we want to set the best value in the registers.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> drivers/clk/sunxi-ng/ccu_div.h | 10 +++++++++-
> drivers/clk/sunxi-ng/ccu_mp.c | 10 +++++++---
> drivers/clk/sunxi-ng/ccu_mult.c | 4 ++--
> drivers/clk/sunxi-ng/ccu_mult.h | 20 ++++++++++++++------
> drivers/clk/sunxi-ng/ccu_nk.c | 14 ++++++++++----
> drivers/clk/sunxi-ng/ccu_nkm.c | 18 +++++++++++++-----
> drivers/clk/sunxi-ng/ccu_nkmp.c | 17 +++++++++++++----
> drivers/clk/sunxi-ng/ccu_nm.c | 13 ++++++++++---
> 8 files changed, 78 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
> index 06540f7cf41c..08d074451204 100644
> --- a/drivers/clk/sunxi-ng/ccu_div.h
> +++ b/drivers/clk/sunxi-ng/ccu_div.h
> @@ -41,6 +41,7 @@ struct ccu_div_internal {
> u8 width;
>
> u32 max;
> + u32 offset;
>
> u32 flags;
>
> @@ -58,20 +59,27 @@ struct ccu_div_internal {
> #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
> _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
>
> -#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
> +#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
> { \
> .shift = _shift, \
> .width = _width, \
> .flags = _flags, \
> .max = _max, \
> + .offset = _off, \
> }
>
> +#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
> + _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
> +
> #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
> _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
>
> #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
> _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
>
> +#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset) \
> + _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
> +
> #define _SUNXI_CCU_DIV(_shift, _width) \
> _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> index ebb1b31568a5..22c2ca7a2a22 100644
> --- a/drivers/clk/sunxi-ng/ccu_mp.c
> +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> @@ -89,11 +89,14 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
>
> m = reg >> cmp->m.shift;
> m &= (1 << cmp->m.width) - 1;
> + m += cmp->m.offset;
> + if (!m)
> + m++;
>
> p = reg >> cmp->p.shift;
> p &= (1 << cmp->p.width) - 1;
>
> - return (parent_rate >> p) / (m + 1);
> + return (parent_rate >> p) / m;
> }
>
> static int ccu_mp_determine_rate(struct clk_hw *hw,
> @@ -124,9 +127,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
> reg = readl(cmp->common.base + cmp->common.reg);
> reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
> reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
> + reg |= (m - cmp->m.offset) << cmp->m.shift;
> + reg |= ilog2(p) << cmp->p.shift;
>
> - writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift),
> - cmp->common.base + cmp->common.reg);
> + writel(reg, cmp->common.base + cmp->common.reg);
>
> spin_unlock_irqrestore(cmp->common.lock, flags);
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
> index 826302464650..bf5e11c803f9 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.c
> +++ b/drivers/clk/sunxi-ng/ccu_mult.c
> @@ -85,7 +85,7 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
> ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
> &parent_rate);
>
> - return parent_rate * (val + 1);
> + return parent_rate * (val + cm->mult.offset);
> }
>
> static int ccu_mult_determine_rate(struct clk_hw *hw,
> @@ -122,7 +122,7 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
> reg = readl(cm->common.base + cm->common.reg);
> reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
>
> - writel(reg | ((_cm.mult - 1) << cm->mult.shift),
> + writel(reg | ((_cm.mult - cm->mult.offset) << cm->mult.shift),
Nit, might be worth splitting out the "or" to a separate line.
> cm->common.base + cm->common.reg);
>
> spin_unlock_irqrestore(cm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
> index bd2e38b5a32a..84839641dfdf 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.h
> +++ b/drivers/clk/sunxi-ng/ccu_mult.h
> @@ -6,20 +6,28 @@
> #include "ccu_mux.h"
>
> struct ccu_mult_internal {
> + u8 offset;
> u8 shift;
> u8 width;
> u8 min;
> };
>
> -#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \
> - { \
> - .shift = _shift, \
> - .width = _width, \
> - .min = _min, \
> +#define _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, _min) \
> + { \
> + .min = _min, \
> + .offset = _offset, \
> + .shift = _shift, \
> + .width = _width, \
> }
>
> +#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \
> + _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, _min)
> +
> +#define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset) \
> + _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, 1)
> +
> #define _SUNXI_CCU_MULT(_shift, _width) \
> - _SUNXI_CCU_MULT_MIN(_shift, _width, 1)
> + _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, 1)
>
> struct ccu_mult {
> u32 enable;
> diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
> index eaf0fdf78d2b..90117d3ead8c 100644
> --- a/drivers/clk/sunxi-ng/ccu_nk.c
> +++ b/drivers/clk/sunxi-ng/ccu_nk.c
> @@ -76,12 +76,17 @@ static unsigned long ccu_nk_recalc_rate(struct clk_hw *hw,
>
> n = reg >> nk->n.shift;
> n &= (1 << nk->n.width) - 1;
> + n += nk->n.offset;
> + if (!n)
> + n++;
>
> k = reg >> nk->k.shift;
> k &= (1 << nk->k.width) - 1;
> + k += nk->k.offset;
> + if (!k)
> + k++;
>
> - rate = parent_rate * (n + 1) * (k + 1);
> -
> + rate = parent_rate * n * k;
> if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
> rate /= nk->fixed_post_div;
>
> @@ -135,8 +140,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
> reg &= ~GENMASK(nk->n.width + nk->n.shift - 1, nk->n.shift);
> reg &= ~GENMASK(nk->k.width + nk->k.shift - 1, nk->k.shift);
>
> - writel(reg | ((_nk.k - 1) << nk->k.shift) | ((_nk.n - 1) << nk->n.shift),
> - nk->common.base + nk->common.reg);
> + reg |= (_nk.k - nk->k.offset) << nk->k.shift;
> + reg |= (_nk.n - nk->n.offset) << nk->n.shift;
> + writel(reg, nk->common.base + nk->common.reg);
>
> spin_unlock_irqrestore(nk->common.lock, flags);
>
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 9b840a47a94d..3caaf9d603e2 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -82,14 +82,23 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
>
> n = reg >> nkm->n.shift;
> n &= (1 << nkm->n.width) - 1;
> + n += nkm->n.offset;
> + if (!n)
> + n++;
>
> k = reg >> nkm->k.shift;
> k &= (1 << nkm->k.width) - 1;
> + k += nkm->k.offset;
> + if (!k)
> + k++;
>
> m = reg >> nkm->m.shift;
> m &= (1 << nkm->m.width) - 1;
> + m += nkm->m.offset;
> + if (!m)
> + m++;
>
> - return parent_rate * (n + 1) * (k + 1) / (m + 1);
> + return parent_rate * n * k / m;
> }
>
> static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
> @@ -145,10 +154,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
> reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift);
> reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift);
>
> - reg |= (_nkm.n - 1) << nkm->n.shift;
> - reg |= (_nkm.k - 1) << nkm->k.shift;
> - reg |= (_nkm.m - 1) << nkm->m.shift;
> -
> + reg |= (_nkm.n - nkm->n.offset) << nkm->n.shift;
> + reg |= (_nkm.k - nkm->k.offset) << nkm->k.shift;
> + reg |= (_nkm.m - nkm->m.offset) << nkm->m.shift;
> writel(reg, nkm->common.base + nkm->common.reg);
>
> spin_unlock_irqrestore(nkm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
> index 684c42da3ebb..da2bba02b845 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
> @@ -88,17 +88,26 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
>
> n = reg >> nkmp->n.shift;
> n &= (1 << nkmp->n.width) - 1;
> + n += nkmp->n.offset;
> + if (!n)
> + n++;
>
> k = reg >> nkmp->k.shift;
> k &= (1 << nkmp->k.width) - 1;
> + k += nkmp->k.offset;
> + if (!k)
> + k++;
>
> m = reg >> nkmp->m.shift;
> m &= (1 << nkmp->m.width) - 1;
> + m += nkmp->m.offset;
> + if (!m)
> + m++;
>
> p = reg >> nkmp->p.shift;
> p &= (1 << nkmp->p.width) - 1;
>
> - return (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
> + return parent_rate * n * k >> p / m;
> }
>
> static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
> @@ -148,9 +157,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
> reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
> reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
>
> - reg |= (_nkmp.n - 1) << nkmp->n.shift;
> - reg |= (_nkmp.k - 1) << nkmp->k.shift;
> - reg |= (_nkmp.m - 1) << nkmp->m.shift;
> + reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
> + reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
> + reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
> reg |= ilog2(_nkmp.p) << nkmp->p.shift;
>
> writel(reg, nkmp->common.base + nkmp->common.reg);
> diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
> index c9f3b6c982f0..158d74e0215f 100644
> --- a/drivers/clk/sunxi-ng/ccu_nm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nm.c
> @@ -80,11 +80,17 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
>
> n = reg >> nm->n.shift;
> n &= (1 << nm->n.width) - 1;
> + n += nm->n.offset;
> + if (!n)
> + n++;
>
> m = reg >> nm->m.shift;
> m &= (1 << nm->m.width) - 1;
> + m += nm->m.offset;
> + if (!m)
> + m++;
>
> - return parent_rate * (n + 1) / (m + 1);
> + return parent_rate * n / m;
> }
>
> static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
> @@ -129,8 +135,9 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
> reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift);
> reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
>
> - writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift),
> - nm->common.base + nm->common.reg);
> + reg |= (_nm.n - nm->n.offset) << nm->n.shift;
> + reg |= (_nm.m - nm->m.offset) << nm->m.shift;
> + writel(reg, nm->common.base + nm->common.reg);
>
> spin_unlock_irqrestore(nm->common.lock, flags);
>
> --
> git-series 0.8.11
Otherwise,
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* [PATCH v2 3/7] clk: sunxi-ng: Implement multiplier maximum
From: Chen-Yu Tsai @ 2017-01-16 5:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ab8ef79d63fc09c3eaa556d299832ec06e9869cf.1484035021.git-series.maxime.ripard@free-electrons.com>
On Tue, Jan 10, 2017 at 3:57 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> drivers/clk/sunxi-ng/ccu_mult.c | 4 ++--
> drivers/clk/sunxi-ng/ccu_mult.h | 10 ++++++----
> drivers/clk/sunxi-ng/ccu_nk.c | 8 ++++----
> drivers/clk/sunxi-ng/ccu_nkm.c | 8 ++++----
> drivers/clk/sunxi-ng/ccu_nkmp.c | 8 ++++----
> drivers/clk/sunxi-ng/ccu_nm.c | 4 ++--
> 6 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
> index bf5e11c803f9..fccfe1e1961a 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.c
> +++ b/drivers/clk/sunxi-ng/ccu_mult.c
> @@ -41,7 +41,7 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
> struct _ccu_mult _cm;
>
> _cm.min = 1;
> - _cm.max = 1 << cm->mult.width;
> + _cm.max = cm->mult.max ?: 1 << cm->mult.width;
Should you also factor in the offset when providing the default
value for max? Otherwise you might end up with a value that is
actually not progammable?
Say if offset is 1, then max would be 1 << width.
But if offset is 0, then max would have to be (1 << width) - 1,
as (1 << width) is not valid.
ChenYu
> ccu_mult_find_best(parent_rate, rate, &_cm);
>
> return parent_rate * _cm.mult;
> @@ -114,7 +114,7 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
> &parent_rate);
>
> _cm.min = cm->mult.min;
> - _cm.max = 1 << cm->mult.width;
> + _cm.max = cm->mult.max ?: 1 << cm->mult.width;
> ccu_mult_find_best(parent_rate, rate, &_cm);
>
> spin_lock_irqsave(cm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
> index 84839641dfdf..524acddfcb2e 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.h
> +++ b/drivers/clk/sunxi-ng/ccu_mult.h
> @@ -10,24 +10,26 @@ struct ccu_mult_internal {
> u8 shift;
> u8 width;
> u8 min;
> + u8 max;
> };
>
> -#define _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, _min) \
> +#define _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, _min, _max) \
> { \
> .min = _min, \
> + .max = _max, \
> .offset = _offset, \
> .shift = _shift, \
> .width = _width, \
> }
>
> #define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \
> - _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, _min)
> + _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, _min, 0)
>
> #define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset) \
> - _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, 1)
> + _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, 1, 0)
>
> #define _SUNXI_CCU_MULT(_shift, _width) \
> - _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, 1)
> + _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, 1, 0)
>
> struct ccu_mult {
> u32 enable;
> diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
> index 90117d3ead8c..b9e9b8a9d1b4 100644
> --- a/drivers/clk/sunxi-ng/ccu_nk.c
> +++ b/drivers/clk/sunxi-ng/ccu_nk.c
> @@ -103,9 +103,9 @@ static long ccu_nk_round_rate(struct clk_hw *hw, unsigned long rate,
> rate *= nk->fixed_post_div;
>
> _nk.min_n = nk->n.min;
> - _nk.max_n = 1 << nk->n.width;
> + _nk.max_n = nk->n.max ?: 1 << nk->n.width;
> _nk.min_k = nk->k.min;
> - _nk.max_k = 1 << nk->k.width;
> + _nk.max_k = nk->k.max ?: 1 << nk->k.width;
>
> ccu_nk_find_best(*parent_rate, rate, &_nk);
> rate = *parent_rate * _nk.n * _nk.k;
> @@ -128,9 +128,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
> rate = rate * nk->fixed_post_div;
>
> _nk.min_n = nk->n.min;
> - _nk.max_n = 1 << nk->n.width;
> + _nk.max_n = nk->n.max ?: 1 << nk->n.width;
> _nk.min_k = nk->k.min;
> - _nk.max_k = 1 << nk->k.width;
> + _nk.max_k = nk->k.max ?: 1 << nk->k.width;
>
> ccu_nk_find_best(parent_rate, rate, &_nk);
>
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 3caaf9d603e2..71f81e95a061 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -110,9 +110,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
> struct _ccu_nkm _nkm;
>
> _nkm.min_n = nkm->n.min;
> - _nkm.max_n = 1 << nkm->n.width;
> + _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
> _nkm.min_k = nkm->k.min;
> - _nkm.max_k = 1 << nkm->k.width;
> + _nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
> _nkm.min_m = 1;
> _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>
> @@ -139,9 +139,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
> u32 reg;
>
> _nkm.min_n = nkm->n.min;
> - _nkm.max_n = 1 << nkm->n.width;
> + _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
> _nkm.min_k = nkm->k.min;
> - _nkm.max_k = 1 << nkm->k.width;
> + _nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
> _nkm.min_m = 1;
> _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>
> diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
> index da2bba02b845..a2b40a000157 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
> @@ -117,9 +117,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
> struct _ccu_nkmp _nkmp;
>
> _nkmp.min_n = nkmp->n.min;
> - _nkmp.max_n = 1 << nkmp->n.width;
> + _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
> _nkmp.min_k = nkmp->k.min;
> - _nkmp.max_k = 1 << nkmp->k.width;
> + _nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
> _nkmp.min_m = 1;
> _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
> _nkmp.min_p = 1;
> @@ -139,9 +139,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
> u32 reg;
>
> _nkmp.min_n = 1;
> - _nkmp.max_n = 1 << nkmp->n.width;
> + _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
> _nkmp.min_k = 1;
> - _nkmp.max_k = 1 << nkmp->k.width;
> + _nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
> _nkmp.min_m = 1;
> _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
> _nkmp.min_p = 1;
> diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
> index 158d74e0215f..af71b1909cd9 100644
> --- a/drivers/clk/sunxi-ng/ccu_nm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nm.c
> @@ -100,7 +100,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
> struct _ccu_nm _nm;
>
> _nm.min_n = nm->n.min;
> - _nm.max_n = 1 << nm->n.width;
> + _nm.max_n = nm->n.max ?: 1 << nm->n.width;
> _nm.min_m = 1;
> _nm.max_m = nm->m.max ?: 1 << nm->m.width;
>
> @@ -123,7 +123,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
> ccu_frac_helper_disable(&nm->common, &nm->frac);
>
> _nm.min_n = 1;
> - _nm.max_n = 1 << nm->n.width;
> + _nm.max_n = nm->n.max ?: 1 << nm->n.width;
> _nm.min_m = 1;
> _nm.max_m = nm->m.max ?: 1 << nm->m.width;
>
> --
> git-series 0.8.11
^ permalink raw reply
* [PATCH 16/37] PCI: endpoint: Introduce configfs entry for configuring EP functions
From: Kishon Vijay Abraham I @ 2017-01-16 6:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113180602.GA30346@infradead.org>
Hi Christoph,
On Friday 13 January 2017 11:36 PM, Christoph Hellwig wrote:
> Hi Kishon,
>
> a couple comments on the configfs layout based on my experiments with
> your previous drop to implement a NVMe device using it.
Thanks for trying it out!
>
> I don't think most of these configfs files should be present here, as
> they are properties of the implemented PCIe devices. E.g. for my
> NVMe device they will be sort of hardcoded most of the time, as they
> would be for other devices that would always have a fixed vendor/device/
> class ID, cacheline size, etc.
Actually not all devices have hardcoded headers. E.g the platform I'm using
doesn't have hardcoded headers and it can be configured based on the function
the user would like to use. If the devices are hardcoded, then using configfs
can be skipped altogether. In such cases, APIs like pci_epf_create() can
directly be used by the drivers instead of going via configfs.
Thanks
Kishon
^ permalink raw reply
* [PATCH 36/37] ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP
From: Kishon Vijay Abraham I @ 2017-01-16 6:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113171537.GZ2630@atomide.com>
Hi Tony,
On Friday 13 January 2017 10:45 PM, Tony Lindgren wrote:
> * Kishon Vijay Abraham I <kishon@ti.com> [170112 02:35]:
>> The PCIe programming sequence in TRM suggests CLKSTCTRL of PCIe should
>> be set to SW_WKUP. There are no issues when CLKSTCTRL is set to HW_AUTO
>> in RC mode. However in EP mode, the host system is not able to access the
>> MEMSPACE and setting the CLKSTCTRL to SW_WKUP fixes it.
>
> I guess ideally in the long run we would set this dynamically based on
> the selected mode, right?
The programming sequence mentioned in the TRM w.r.t clock programming is same
for both host mode or device mode. Though we never faced any issues in host
mode when HW_AUTO is set, it's better to follow TRM recommended settings IMHO.
Thanks
Kishon
>
> Regards,
>
> Tony
>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> arch/arm/mach-omap2/clockdomains7xx_data.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c
>> index 6c67965..67ebff8 100644
>> --- a/arch/arm/mach-omap2/clockdomains7xx_data.c
>> +++ b/arch/arm/mach-omap2/clockdomains7xx_data.c
>> @@ -524,7 +524,7 @@
>> .dep_bit = DRA7XX_PCIE_STATDEP_SHIFT,
>> .wkdep_srcs = pcie_wkup_sleep_deps,
>> .sleepdep_srcs = pcie_wkup_sleep_deps,
>> - .flags = CLKDM_CAN_HWSUP_SWSUP,
>> + .flags = CLKDM_CAN_SWSUP,
>> };
>>
>> static struct clockdomain atl_7xx_clkdm = {
>> --
>> 1.7.9.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
^ permalink raw reply
* [PATCH v2 4/7] clk: sunxi-ng: Add clocks and resets indices for sun5i
From: Chen-Yu Tsai @ 2017-01-16 6:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b58205e51f84da9a59ca617906b4524d7e976f58.1484035021.git-series.maxime.ripard@free-electrons.com>
Hi,
On Tue, Jan 10, 2017 at 3:57 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The SoCs part of the sun5i family share the DTs, so we need consistant
> indices in order to still share the DTs.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* [PATCH v19 00/15] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
From: Fu Wei @ 2017-01-16 6:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161221064603.11830-1-fu.wei@linaro.org>
Hi Mark,
This v19 (I have mentioned it in my previous email) is the latest
patchset which can be applied on v4.10-rc4 directly.
please review this patchset, thanks! :-)
On 21 December 2016 at 14:45, <fu.wei@linaro.org> wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> This patchset:
> (1)Preparation for adding GTDT support in arm_arch_timer:
> 1. Move some enums and marcos to header file;
> 2. Add a new enum for spi type;
> 3. Improve printk relevant code;
> 4. Rename some enums and defines;
> 5. Rework PPI determination;
> 6. Rework counter frequency detection;
> 7. Refactor arch_timer_needs_probing, move it into DT init call
> 8. Introduce some new structs and refactor the MMIO timer init code
> for reusing some common code.
>
> (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
> Parse all kinds of timer in GTDT table of ACPI:arch timer,
> memory-mapped timer and SBSA Generic Watchdog timer.
> This driver can help to simplify all the relevant timer drivers,
> and separate all the ACPI GTDT knowledge from them.
>
> (3)Simplify ACPI code for arm_arch_timer
>
> (4)Add GTDT support for ARM memory-mapped timer.
>
> This patchset has been tested on the following platforms with ACPI enabled:
> (1)ARM Foundation v8 model
>
> Changelog:
> v19: https://lkml.org/lkml/2016/12/21/
> Fix a '\n' missing in a error message in arch_timer_mem_init.
> Add "request_mem_region" for ioremapping cntbase, according to
> f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
> Rebase to 4.9.0-gfb779ff
>
> v18: https://lkml.org/lkml/2016/12/8/446
> Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
> Rebase to 4.9.0-rc8-g9269898
>
> v17: https://lkml.org/lkml/2016/11/25/140
> Take out some cleanups from 4/15.
> Merge 5/15 and 6/15, improve PPI determination code,
> improve commit message.
> Rework counter frequency detection.
> Move arch_timer_needs_of_probing into DT init call.
> Move Platform Timer scan loop back to timer init call to avoid allocating
> and free memory.
> Improve all the exported functions' comment.
>
> v16: https://lkml.org/lkml/2016/11/16/268
> Fix patchset problem about static enum ppi_nr of 01/13 in v15.
> Refactor arch_timer_detect_rate.
> Refactor arch_timer_needs_probing.
>
> v15: https://lkml.org/lkml/2016/11/15/366
> Re-order patches
> Add arm_arch_timer refactoring patches to prepare for GTDT:
> 1. rename some enums and defines, and some cleanups
> 2. separate out arch_timer_uses_ppi init code and fix a potential bug
> 3. Improve some new structs, refactor the timer init code.
> Since the some structs have been changed, GTDT parser for memory-mapped
> timer and SBSA Generic Watchdog timer have been update.
>
> v14: https://lkml.org/lkml/2016/9/28/573
> Separate memory-mapped timer GTDT support into two patches
> 1. Refactor the timer init code to prepare for GTDT
> 2. Add GTDT support for memory-mapped timer
>
> v13: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1231717.html
> Improve arm_arch_timer code for memory-mapped
> timer GTDT support, refactor original memory-mapped timer
> dt support for reusing some common code.
>
> v12: https://lkml.org/lkml/2016/9/13/250
> Rebase to latest Linux 4.8-rc6
> Delete the confusing "skipping" in the error message.
>
> V11: https://lkml.org/lkml/2016/9/6/354
> Rebase to latest Linux 4.8-rc5
> Delete typedef (suggested by checkpatch.pl)
>
> V10: https://lkml.org/lkml/2016/7/26/215
> Drop the "readq" patch.
> Rebase to latest Linux 4.7.
>
> V9: https://lkml.org/lkml/2016/7/25/345
> Improve pr_err message in acpi gtdt driver.
> Update Commit message for 7/9
> shorten the irq mapping function name
> Improve GTDT driver for memory-mapped timer
>
> v8: https://lkml.org/lkml/2016/7/19/660
> Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
> and also improve printk message.
> Simplify is_timer_block and is_watchdog.
> Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
> Delete __init in include/linux/acpi.h for GTDT API
> Make ARM64 select GTDT.
> Delete "#include <linux/module.h>" from acpi_gtdt.c
> Simplify GT block parse code.
>
> v7: https://lkml.org/lkml/2016/7/13/769
> Move the GTDT driver to drivers/acpi/arm64
> Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
> Merge 3 patches of GTDT parser driver.
> Fix the for_each_platform_timer bug.
>
> v6: https://lkml.org/lkml/2016/6/29/580
> split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
> and SBSA Generic Watchdog timer
> Improve driver by suggestions and example code from Daniel Lezcano
>
> v5: https://lkml.org/lkml/2016/5/24/356
> Sorting out all patches, simplify the API of GTDT driver:
> GTDT driver just fills the data struct for arm_arch_timer driver.
>
> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
> Delete the kvm relevant patches
> Separate two patches for sorting out the code for arm_arch_timer.
> Improve irq info export code to allow missing irq info in GTDT table.
>
> v3: https://lkml.org/lkml/2016/2/1/658
> Improve GTDT driver code:
> (1)improve pr_* by defining pr_fmt(fmt)
> (2)simplify gtdt_sbsa_gwdt_init
> (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
> to get GTDT table.
> Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
> Add arm_arch_timer get ppi from DT and GTDT support for kvm.
>
> v2: https://lkml.org/lkml/2015/12/2/10
> Rebase to latest kernel version(4.4-rc3).
> Fix the bug about the config problem,
> use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
>
> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
>
> Fu Wei (15):
> clocksource/drivers/arm_arch_timer: Move enums and defines to header
> file
> clocksource/drivers/arm_arch_timer: Add a new enum for spi type
> clocksource/drivers/arm_arch_timer: Improve printk relevant code
> clocksource/drivers/arm_arch_timer: rename some enums and defines.
> clocksource/drivers/arm_arch_timer: rework PPI determination
> clocksource/drivers/arm_arch_timer: Rework counter frequency
> detection.
> clocksource/drivers/arm_arch_timer: Refactor arch_timer_needs_probing
> clocksource/drivers/arm_arch_timer: move arch_timer_needs_of_probing
> into DT init call
> clocksource/drivers/arm_arch_timer: Introduce some new structs to
> prepare for GTDT
> clocksource/drivers/arm_arch_timer: Refactor the timer init code to
> prepare for GTDT
> acpi/arm64: Add GTDT table parse driver
> clocksource/drivers/arm_arch_timer: Simplify ACPI support code.
> acpi/arm64: Add memory-mapped timer support in GTDT driver
> clocksource/drivers/arm_arch_timer: Add GTDT support for memory-mapped
> timer
> acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
>
> arch/arm64/Kconfig | 1 +
> drivers/acpi/arm64/Kconfig | 3 +
> drivers/acpi/arm64/Makefile | 1 +
> drivers/acpi/arm64/gtdt.c | 374 +++++++++++++++++++++++++++
> drivers/clocksource/arm_arch_timer.c | 483 ++++++++++++++++++++---------------
> drivers/watchdog/Kconfig | 1 +
> include/clocksource/arm_arch_timer.h | 45 +++-
> include/linux/acpi.h | 7 +
> virt/kvm/arm/hyp/timer-sr.c | 6 +-
> 9 files changed, 712 insertions(+), 209 deletions(-)
> create mode 100644 drivers/acpi/arm64/gtdt.c
>
> --
> 2.9.3
>
--
Best regards,
Fu Wei
Software Engineer
Red Hat
^ permalink raw reply
* [PATCH 00/12] Move pad retention control to Exynos pin controller driver
From: Marek Szyprowski @ 2017-01-16 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CGME20170116064523eucas1p161a8e060b2883c076fc470ce7b522332@eucas1p1.samsung.com>
Hello,
This patchset is a follow-up of my work on adding runtime PM support
to Exynos pin controller driver:
http://www.spinics.net/lists/arm-kernel/msg550161.html
Runtime PM support itself needs a bit more discussion, so lets first focus on
the prerequisites.
In case of Exynos pin controller driver it is a pad retention control. In
current code it was handled by machine and PMU code and had no relation to
what pin controller driver does. This patch series moves pad retention
control to pin controller driver. While implmenting it, I also did a little
cleanup of both Exynos PMU and pin controller drivers.
Patches are based on linux-next from 2017.01.16 with Exynos4415 support
removal patch applied: https://lkml.org/lkml/2017/1/14/137
Changelog:
v1:
- removed the need to add PMU phandles to all pin controller nodes, so old DTBs
are properly supported. This has been achieved by getting PMU regmap from
the "exynos-pmu" device of fixed name.
- more cleanup in Exynos pin controller driver: added missing entries in DT
documentation, removed "memory allocation failed" messages and added
initconst annotations.
- added support for s5pv210.
- reworked retention control code to be simpler and ready for adding Exynos5433
support.
v0: http://www.spinics.net/lists/arm-kernel/msg550161.html
- initial version
- part of "Runtime PM for Exynos pin controller driver" patchset
Patch summary:
Marek Szyprowski (12):
soc: samsung: pmu: Use common device name to let others to find it
easily
soc: samsung: pmu: Use of_device_get_match_data helper
soc: samsung: pmu: Remove messages for failed memory allocation
pinctrl: samsung: Document Exynos3250 SoC support
pinctrl: samsung: Remove messages for failed memory allocation
pinctrl: samsung: Add missing initconst annotation
pinctrl: samsung: Remove dead code
pinctrl: samsung: Use generic of_device_get_match_data helper
pinctrl: samsung: Add infrastructure for pin-bank retention control
pinctrl: samsung: Move retention control from mach-exynos to the
pinctrl driver
pinctrl: samsung: Move retention control from mach-s5pv210 to the
pinctrl driver
pinctrl: samsung: Replace syscore ops with standard platform device
pm_ops
.../bindings/pinctrl/samsung-pinctrl.txt | 1 +
arch/arm/mach-exynos/suspend.c | 64 ------
arch/arm/mach-s5pv210/pm.c | 7 -
arch/arm/mach-s5pv210/regs-clock.h | 4 -
drivers/pinctrl/samsung/pinctrl-exynos.c | 235 +++++++++++++++++++--
drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 12 +-
drivers/pinctrl/samsung/pinctrl-samsung.c | 122 +++--------
drivers/pinctrl/samsung/pinctrl-samsung.h | 42 ++++
drivers/soc/samsung/exynos-pmu.c | 12 +-
include/linux/soc/samsung/exynos-pmu.h | 19 ++
10 files changed, 321 insertions(+), 197 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 01/12] soc: samsung: pmu: Use common device name to let others to find it easily
From: Marek Szyprowski @ 2017-01-16 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
This patch always set device name to "exynos-pmu" to let other drivers to
find PMU device easily. This is done mainly to get regmap to access PMU
registers from other drivers. This way it can be avoided to add phandle to
the PMU node to almost all drivers in the SoC just to get a regmap access
in the drivers. PMU is something like a SoC wide service, so there is no
point modeling it as hardware dependency for all devices in device tree.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/soc/samsung/exynos-pmu.c | 1 +
include/linux/soc/samsung/exynos-pmu.h | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 0acdfd82e751..63bb471845cb 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -120,6 +120,7 @@ static int exynos_pmu_probe(struct platform_device *pdev)
pmu_context->pmu_data->pmu_init();
platform_set_drvdata(pdev, pmu_context);
+ dev_set_name(dev, EXYNOS_PMU_DEV_NAME);
dev_dbg(dev, "Exynos PMU Driver probe done\n");
return 0;
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index e2e9de1acc5b..90d9205805ea 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -12,6 +12,10 @@
#ifndef __LINUX_SOC_EXYNOS_PMU_H
#define __LINUX_SOC_EXYNOS_PMU_H
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
enum sys_powerdown {
SYS_AFTR,
SYS_LPA,
@@ -21,4 +25,19 @@ enum sys_powerdown {
extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
+#define EXYNOS_PMU_DEV_NAME "exynos-pmu"
+
+static inline struct regmap *exynos_get_pmu_regs(void)
+{
+ struct device *dev = bus_find_device_by_name(&platform_bus_type, NULL,
+ EXYNOS_PMU_DEV_NAME);
+ if (dev) {
+ struct regmap *regs = syscon_node_to_regmap(dev->of_node);
+ put_device(dev);
+ if (!IS_ERR(regs))
+ return regs;
+ }
+ return NULL;
+}
+
#endif /* __LINUX_SOC_EXYNOS_PMU_H */
--
1.9.1
^ permalink raw reply related
* [PATCH 02/12] soc: samsung: pmu: Use of_device_get_match_data helper
From: Marek Szyprowski @ 2017-01-16 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
Replace custom code with generic helper to retrieve driver data.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/soc/samsung/exynos-pmu.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 63bb471845cb..0f4b4fce9d90 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -11,6 +11,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
@@ -94,7 +95,6 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
static int exynos_pmu_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
struct device *dev = &pdev->dev;
struct resource *res;
@@ -111,10 +111,7 @@ static int exynos_pmu_probe(struct platform_device *pdev)
return -ENOMEM;
}
pmu_context->dev = dev;
-
- match = of_match_node(exynos_pmu_of_device_ids, dev->of_node);
-
- pmu_context->pmu_data = match->data;
+ pmu_context->pmu_data = of_device_get_match_data(dev);
if (pmu_context->pmu_data->pmu_init)
pmu_context->pmu_data->pmu_init();
--
1.9.1
^ permalink raw reply related
* [PATCH 03/12] soc: samsung: pmu: Remove messages for failed memory allocation
From: Marek Szyprowski @ 2017-01-16 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
Memory subsystem already prints message about failed memory
allocation, there is no need to do it in the driver.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/soc/samsung/exynos-pmu.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 0f4b4fce9d90..43937a3aea28 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -106,10 +106,8 @@ static int exynos_pmu_probe(struct platform_device *pdev)
pmu_context = devm_kzalloc(&pdev->dev,
sizeof(struct exynos_pmu_context),
GFP_KERNEL);
- if (!pmu_context) {
- dev_err(dev, "Cannot allocate memory.\n");
+ if (!pmu_context)
return -ENOMEM;
- }
pmu_context->dev = dev;
pmu_context->pmu_data = of_device_get_match_data(dev);
--
1.9.1
^ permalink raw reply related
* [PATCH 04/12] pinctrl: samsung: Document Exynos3250 SoC support
From: Marek Szyprowski @ 2017-01-16 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
Add missing compatible id for Exynos3250 SoC to device tree docs.
Exynos pin control driver supports it since commit d97f5b9804bfcdc1
("pinctrl: exynos: Add driver data for Exynos3250").
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 1baf19eecabf..5e00a21de2bf 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -13,6 +13,7 @@ Required Properties:
- "samsung,s3c2450-pinctrl": for S3C2450-compatible pin-controller,
- "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
- "samsung,s5pv210-pinctrl": for S5PV210-compatible pin-controller,
+ - "samsung,exynos3250-pinctrl": for Exynos3250 compatible pin-controller.
- "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
- "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
- "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
--
1.9.1
^ permalink raw reply related
* [PATCH 05/12] pinctrl: samsung: Remove messages for failed memory allocation
From: Marek Szyprowski @ 2017-01-16 6:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
Memory subsystem already prints message about failed memory
allocation, there is no need to do it in the drivers.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/pinctrl/samsung/pinctrl-exynos.c | 8 ++------
drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 12 +++---------
drivers/pinctrl/samsung/pinctrl-samsung.c | 24 ++++++------------------
3 files changed, 11 insertions(+), 33 deletions(-)
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 24814db251a7..bf753a596209 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -528,10 +528,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
weint_data = devm_kzalloc(dev, bank->nr_pins
* sizeof(*weint_data), GFP_KERNEL);
- if (!weint_data) {
- dev_err(dev, "could not allocate memory for weint_data\n");
+ if (!weint_data)
return -ENOMEM;
- }
for (idx = 0; idx < bank->nr_pins; ++idx) {
irq = irq_of_parse_and_map(bank->of_node, idx);
@@ -559,10 +557,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+ muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
- if (!muxed_data) {
- dev_err(dev, "could not allocate memory for muxed_data\n");
+ if (!muxed_data)
return -ENOMEM;
- }
irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31,
muxed_data);
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index 4c632812ccff..f17890aa6e25 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
@@ -489,10 +489,8 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
data = devm_kzalloc(dev, sizeof(*data)
+ nr_domains * sizeof(*data->domains), GFP_KERNEL);
- if (!data) {
- dev_err(dev, "failed to allocate handler data\n");
+ if (!data)
return -ENOMEM;
- }
data->drvdata = d;
bank = d->pin_banks;
@@ -715,10 +713,8 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
return -ENODEV;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data) {
- dev_err(dev, "could not allocate memory for wkup eint data\n");
+ if (!data)
return -ENOMEM;
- }
data->drvdata = d;
for (i = 0; i < NUM_EINT0_IRQ; ++i) {
@@ -751,10 +747,8 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
ddata = devm_kzalloc(dev,
sizeof(*ddata) + nr_eints, GFP_KERNEL);
- if (!ddata) {
- dev_err(dev, "failed to allocate domain data\n");
+ if (!ddata)
return -ENOMEM;
- }
ddata->bank = bank;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 3bc925f61b71..b11e67e85460 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -93,10 +93,8 @@ static int reserve_map(struct device *dev, struct pinctrl_map **map,
return 0;
new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
- if (!new_map) {
- dev_err(dev, "krealloc(map) failed\n");
+ if (!new_map)
return -ENOMEM;
- }
memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
@@ -133,10 +131,8 @@ static int add_map_configs(struct device *dev, struct pinctrl_map **map,
dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
GFP_KERNEL);
- if (!dup_configs) {
- dev_err(dev, "kmemdup(configs) failed\n");
+ if (!dup_configs)
return -ENOMEM;
- }
(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
(*map)[*num_maps].data.configs.group_or_pin = group;
@@ -156,10 +152,8 @@ static int add_config(struct device *dev, unsigned long **configs,
new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
GFP_KERNEL);
- if (!new_configs) {
- dev_err(dev, "krealloc(configs) failed\n");
+ if (!new_configs)
return -ENOMEM;
- }
new_configs[old_num] = config;
@@ -756,10 +750,8 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
functions = devm_kzalloc(dev, func_cnt * sizeof(*functions),
GFP_KERNEL);
- if (!functions) {
- dev_err(dev, "failed to allocate memory for function list\n");
+ if (!functions)
return ERR_PTR(-EINVAL);
- }
func = functions;
/*
@@ -850,10 +842,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
drvdata->nr_pins, GFP_KERNEL);
- if (!pindesc) {
- dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
+ if (!pindesc)
return -ENOMEM;
- }
ctrldesc->pins = pindesc;
ctrldesc->npins = drvdata->nr_pins;
@@ -867,10 +857,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
*/
pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
drvdata->nr_pins, GFP_KERNEL);
- if (!pin_names) {
- dev_err(&pdev->dev, "mem alloc for pin names failed\n");
+ if (!pin_names)
return -ENOMEM;
- }
/* for each pin, the name of the pin is pin-bank name + pin number */
for (bank = 0; bank < drvdata->nr_banks; bank++) {
--
1.9.1
^ permalink raw reply related
* [PATCH 06/12] pinctrl: samsung: Add missing initconst annotation
From: Marek Szyprowski @ 2017-01-16 6:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
Exynos5433 support has been added in parallel to adding initconst
annotation to most of the init data structures, so add those
annotations also to Exynos5433 structures.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/pinctrl/samsung/pinctrl-exynos.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index bf753a596209..70b94ad10cc1 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -1266,7 +1266,7 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
};
/* pin banks of exynos5433 pin-controller - ALIVE */
-static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks0[] __initconst = {
EXYNOS5433_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
EXYNOS5433_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
EXYNOS5433_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
@@ -1279,28 +1279,28 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
};
/* pin banks of exynos5433 pin-controller - AUD */
-static const struct samsung_pin_bank_data exynos5433_pin_banks1[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks1[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS5433_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
/* pin banks of exynos5433 pin-controller - CPIF */
-static const struct samsung_pin_bank_data exynos5433_pin_banks2[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks2[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00),
};
/* pin banks of exynos5433 pin-controller - eSE */
-static const struct samsung_pin_bank_data exynos5433_pin_banks3[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks3[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00),
};
/* pin banks of exynos5433 pin-controller - FINGER */
-static const struct samsung_pin_bank_data exynos5433_pin_banks4[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks4[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00),
};
/* pin banks of exynos5433 pin-controller - FSYS */
-static const struct samsung_pin_bank_data exynos5433_pin_banks5[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks5[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00),
EXYNOS5433_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04),
EXYNOS5433_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08),
@@ -1310,17 +1310,17 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
};
/* pin banks of exynos5433 pin-controller - IMEM */
-static const struct samsung_pin_bank_data exynos5433_pin_banks6[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks6[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00),
};
/* pin banks of exynos5433 pin-controller - NFC */
-static const struct samsung_pin_bank_data exynos5433_pin_banks7[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks7[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
};
/* pin banks of exynos5433 pin-controller - PERIC */
-static const struct samsung_pin_bank_data exynos5433_pin_banks8[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks8[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00),
EXYNOS5433_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04),
EXYNOS5433_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08),
@@ -1341,7 +1341,7 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
};
/* pin banks of exynos5433 pin-controller - TOUCH */
-static const struct samsung_pin_bank_data exynos5433_pin_banks9[] = {
+static const struct samsung_pin_bank_data exynos5433_pin_banks9[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
@@ -1349,7 +1349,7 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
* Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes
* ten gpio/pin-mux/pinconfig controllers.
*/
-const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = {
+const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5433_pin_banks0,
--
1.9.1
^ permalink raw reply related
* [PATCH 07/12] pinctrl: samsung: Remove dead code
From: Marek Szyprowski @ 2017-01-16 6:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484549107-5957-1-git-send-email-m.szyprowski@samsung.com>
'enable' parameter has been removed a while ago, so all code for handling
it can be simply removed.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Acked-by: Tomasz Figa <tomasz.figa@gmail.com>
---
drivers/pinctrl/samsung/pinctrl-samsung.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index b11e67e85460..7648a280c0f4 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -350,7 +350,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
/* enable or disable a pinmux function */
static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group, bool enable)
+ unsigned group)
{
struct samsung_pinctrl_drv_data *drvdata;
const struct samsung_pin_bank_type *type;
@@ -380,8 +380,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
data &= ~(mask << shift);
- if (enable)
- data |= func->val << shift;
+ data |= func->val << shift;
writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
spin_unlock_irqrestore(&bank->slock, flags);
@@ -392,7 +391,7 @@ static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned selector,
unsigned group)
{
- samsung_pinmux_setup(pctldev, selector, group, true);
+ samsung_pinmux_setup(pctldev, selector, group);
return 0;
}
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox