From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752917AbcBVCpl (ORCPT ); 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 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 Content-Type: text/plain 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 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(-) 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, -- 1.9.1