From patchwork Mon Feb 22 02:45:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Feng X-Patchwork-Id: 62465 Delivered-To: patch@linaro.org Received: by 10.112.43.199 with SMTP id y7csp981782lbl; Sun, 21 Feb 2016 18:45:43 -0800 (PST) X-Received: by 10.98.72.77 with SMTP id v74mr34934516pfa.33.1456109143137; Sun, 21 Feb 2016 18:45:43 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h6si36328566pfd.5.2016.02.21.18.45.42; Sun, 21 Feb 2016 18:45:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752919AbcBVCpl (ORCPT + 30 others); Sun, 21 Feb 2016 21:45:41 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:29988 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752582AbcBVCpj (ORCPT ); Sun, 21 Feb 2016 21:45:39 -0500 Received: from 172.24.1.49 (EHLO szxeml428-hub.china.huawei.com) ([172.24.1.49]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BWL16267; Mon, 22 Feb 2016 10:45:25 +0800 (CST) Received: from vm163-62.huawei.com (10.184.163.62) by szxeml428-hub.china.huawei.com (10.82.67.183) with Microsoft SMTP Server id 14.3.235.1; Mon, 22 Feb 2016 10:45:15 +0800 From: Chen Feng To: , , , , CC: , Subject: [PATCH 1/2] reset: hisilicon: Add hi6220 media part of reset Date: Mon, 22 Feb 2016 10:45:13 +0800 Message-ID: <1456109114-93675-1-git-send-email-puck.chen@hisilicon.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-Originating-IP: [10.184.163.62] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020201.56CA7646.00F1, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: a38e5d761058eabc1eaa634c559d6f1d Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Chen Feng Signed-off-by: Xinliang Liu --- drivers/reset/hisilicon/hi6220_reset.c | 122 ++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 32 deletions(-) -- 1.9.1 diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 7787a9b..a671390 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -1,7 +1,7 @@ /* * Hisilicon Hi6220 reset controller driver * - * Copyright (c) 2015 Hisilicon Limited. + * Copyright (c) 2015-2016 Hisilicon Limited. * * Author: Feng Chen * @@ -15,46 +15,88 @@ #include #include #include +#include +#include +#include #include #include #include -#define ASSERT_OFFSET 0x300 -#define DEASSERT_OFFSET 0x304 -#define MAX_INDEX 0x509 +/* peritheral ctrl regs + */ +#define PERITH_ASSERT_OFFSET 0x300 +#define PERITH_DEASSERT_OFFSET 0x304 +#define PERITH_MAX_INDEX 0x509 + +/* media ctrl regs + */ +#define SC_MEDIA_RSTEN 0x052C +#define SC_MEDIA_RSTDIS 0x0530 +#define MEDIA_MAX_INDEX 8 + +enum hi6220_reset_ctrl_type { + PERITHERAL, + MEDIA, +}; #define to_reset_data(x) container_of(x, struct hi6220_reset_data, rc_dev) struct hi6220_reset_data { - void __iomem *assert_base; - void __iomem *deassert_base; - struct reset_controller_dev rc_dev; + struct reset_controller_dev rc_dev; + enum hi6220_reset_ctrl_type type; + struct regmap *regmap; }; +static int hi6220_media_assert(struct regmap *regmap, unsigned long idx) +{ + return regmap_write(regmap, SC_MEDIA_RSTEN, BIT(idx)); +} + +static int hi6220_media_deassert(struct regmap *regmap, unsigned long idx) +{ + return regmap_write(regmap, SC_MEDIA_RSTDIS, BIT(idx)); +} + +static int hi6220_peritheral_assert(struct regmap *regmap, unsigned long idx) +{ + u32 bank = idx >> 8; + u32 offset = idx & 0xff; + u32 reg = PERITH_ASSERT_OFFSET + bank * 0x10; + + return regmap_write(regmap, reg, BIT(offset)); +} + +static int hi6220_peritheral_deassert(struct regmap *regmap, unsigned long idx) +{ + u32 bank = idx >> 8; + u32 offset = idx & 0xff; + u32 reg = PERITH_DEASSERT_OFFSET + bank * 0x10; + + return regmap_write(regmap, reg, BIT(offset)); +} + static int hi6220_reset_assert(struct reset_controller_dev *rc_dev, unsigned long idx) { struct hi6220_reset_data *data = to_reset_data(rc_dev); + struct regmap *regmap = data->regmap; - int bank = idx >> 8; - int offset = idx & 0xff; - - writel(BIT(offset), data->assert_base + (bank * 0x10)); - - return 0; + if (data->type == MEDIA) + return hi6220_media_assert(regmap, idx); + else + return hi6220_peritheral_assert(regmap, idx); } static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev, unsigned long idx) { struct hi6220_reset_data *data = to_reset_data(rc_dev); + struct regmap *regmap = data->regmap; - int bank = idx >> 8; - int offset = idx & 0xff; - - writel(BIT(offset), data->deassert_base + (bank * 0x10)); - - return 0; + if (data->type == MEDIA) + return hi6220_media_deassert(regmap, idx); + else + return hi6220_peritheral_deassert(regmap, idx); } static struct reset_control_ops hi6220_reset_ops = { @@ -64,24 +106,32 @@ static struct reset_control_ops hi6220_reset_ops = { static int hi6220_reset_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + enum hi6220_reset_ctrl_type type; struct hi6220_reset_data *data; - struct resource *res; - void __iomem *src_base; + struct regmap *regmap; - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - src_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(src_base)) - return PTR_ERR(src_base); + type = (enum hi6220_reset_ctrl_type)of_device_get_match_data(dev); - data->assert_base = src_base + ASSERT_OFFSET; - data->deassert_base = src_base + DEASSERT_OFFSET; - data->rc_dev.nr_resets = MAX_INDEX; + regmap = syscon_node_to_regmap(np); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get reset controller regmap\n"); + return PTR_ERR(regmap); + } + + data->type = type; + data->regmap = regmap; data->rc_dev.ops = &hi6220_reset_ops; - data->rc_dev.of_node = pdev->dev.of_node; + data->rc_dev.of_node = np; + if (type == MEDIA) + data->rc_dev.nr_resets = MEDIA_MAX_INDEX; + else + data->rc_dev.nr_resets = PERITH_MAX_INDEX; reset_controller_register(&data->rc_dev); @@ -89,9 +139,17 @@ static int hi6220_reset_probe(struct platform_device *pdev) } static const struct of_device_id hi6220_reset_match[] = { - { .compatible = "hisilicon,hi6220-sysctrl" }, - { }, + { + .compatible = "hisilicon,hi6220-sysctrl", + .data = (void *)PERITHERAL, + }, + { + .compatible = "hisilicon,hi6220-mediactrl", + .data = (void *)MEDIA, + }, + { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, hi6220_reset_match); static struct platform_driver hi6220_reset_driver = { .probe = hi6220_reset_probe,