diff options
Diffstat (limited to 'target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch')
-rw-r--r-- | target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch b/target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch new file mode 100644 index 0000000..bb6f64b --- /dev/null +++ b/target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch @@ -0,0 +1,155 @@ +From c91e8490e45c68ea517f70f24568034b7735e8b9 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Thu, 23 Apr 2015 10:35:40 +0200 +Subject: [PATCH 03/76] clk: mediatek: Add reset controller support + +The pericfg and infracfg units also provide reset lines to several +other SoC internal units. This adds a function which can be called +from the pericfg and infracfg initialization functions which will +register the reset controller using reset_controller_register. The +reset controller will provide support for resetting the units +connected to the pericfg and infracfg controller. The units resetted +by this controller can use the standard reset device tree binding +to gain access to the reset lines. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Acked-by: Philipp Zabel <p.zabel@pengutronix.de> +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mtk.h | 10 +++++ + drivers/clk/mediatek/reset.c | 97 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 108 insertions(+) + create mode 100644 drivers/clk/mediatek/reset.c + +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +index c384e97..0b6f1c3 100644 +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -1 +1,2 @@ + obj-y += clk-mtk.o clk-pll.o clk-gate.o ++obj-$(CONFIG_RESET_CONTROLLER) += reset.o +diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h +index 694fc39..61035b9 100644 +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -156,4 +156,14 @@ void __init mtk_clk_register_plls(struct device_node *node, + const struct mtk_pll_data *plls, int num_plls, + struct clk_onecell_data *clk_data); + ++#ifdef CONFIG_RESET_CONTROLLER ++void mtk_register_reset_controller(struct device_node *np, ++ unsigned int num_regs, int regofs); ++#else ++static inline void mtk_register_reset_controller(struct device_node *np, ++ unsigned int num_regs, int regofs) ++{ ++} ++#endif ++ + #endif /* __DRV_CLK_MTK_H */ +diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c +new file mode 100644 +index 0000000..9e9fe4b +--- /dev/null ++++ b/drivers/clk/mediatek/reset.c +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/mfd/syscon.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/platform_device.h> ++#include <linux/regmap.h> ++#include <linux/reset-controller.h> ++#include <linux/slab.h> ++ ++#include "clk-mtk.h" ++ ++struct mtk_reset { ++ struct regmap *regmap; ++ int regofs; ++ struct reset_controller_dev rcdev; ++}; ++ ++static int mtk_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); ++ ++ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2), ++ BIT(id % 32), ~0); ++} ++ ++static int mtk_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); ++ ++ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2), ++ BIT(id % 32), 0); ++} ++ ++static int mtk_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = mtk_reset_assert(rcdev, id); ++ if (ret) ++ return ret; ++ ++ return mtk_reset_deassert(rcdev, id); ++} ++ ++static struct reset_control_ops mtk_reset_ops = { ++ .assert = mtk_reset_assert, ++ .deassert = mtk_reset_deassert, ++ .reset = mtk_reset, ++}; ++ ++void mtk_register_reset_controller(struct device_node *np, ++ unsigned int num_regs, int regofs) ++{ ++ struct mtk_reset *data; ++ int ret; ++ struct regmap *regmap; ++ ++ regmap = syscon_node_to_regmap(np); ++ if (IS_ERR(regmap)) { ++ pr_err("Cannot find regmap for %s: %ld\n", np->full_name, ++ PTR_ERR(regmap)); ++ return; ++ } ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return; ++ ++ data->regmap = regmap; ++ data->regofs = regofs; ++ data->rcdev.owner = THIS_MODULE; ++ data->rcdev.nr_resets = num_regs * 32; ++ data->rcdev.ops = &mtk_reset_ops; ++ data->rcdev.of_node = np; ++ ++ ret = reset_controller_register(&data->rcdev); ++ if (ret) { ++ pr_err("could not register reset controller: %d\n", ret); ++ kfree(data); ++ return; ++ } ++} +-- +1.7.10.4 + |