From patchwork Thu Jun 16 10:30:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xinliang Liu X-Patchwork-Id: 70172 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp185993qgy; Thu, 16 Jun 2016 03:31:25 -0700 (PDT) X-Received: by 10.98.99.132 with SMTP id x126mr4362593pfb.48.1466073083380; Thu, 16 Jun 2016 03:31:23 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ix8si22687494pac.124.2016.06.16.03.31.23; Thu, 16 Jun 2016 03:31:23 -0700 (PDT) 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; dkim=pass header.i=@linaro.org; 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; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754227AbcFPKbQ (ORCPT + 30 others); Thu, 16 Jun 2016 06:31:16 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:33482 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751681AbcFPKbI (ORCPT ); Thu, 16 Jun 2016 06:31:08 -0400 Received: by mail-pf0-f181.google.com with SMTP id i123so15118734pfg.0 for ; Thu, 16 Jun 2016 03:31:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dTJ5xgSadcstBFT6ADFTSV7p62m+96clqkhNzdMu08A=; b=g/dvZy5o0TUtXrFSbGIhTV+29Wqw5Lw6/oyUirNTdcYIc4/1k2OJ+sskXT2uEnahp1 tRlaWt+45e1194C1+Q15P5w/p0CgxNFOoBiwCN/DAErmoXAldeIp4KP5vQFwooAWCTkj 0Em+SZ0h1q9skn3/i1MARgY966q8WMsI3QozQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dTJ5xgSadcstBFT6ADFTSV7p62m+96clqkhNzdMu08A=; b=Ygyn97SqjwQxoYXfJN5P3bGnlwF3kVXKddb5r/OagkrAx9qO40yZon8JzuIqIkAfFv eqcL5nFQTaHl5KyjYzWZ8JuXPOefgv8BW7S73y+llqUpv6cRxQElCUNfc1DSdxhnAIKr rTLDTcqHB0oh252imZvaeDC3WKYuDp5Cg5JfMIjxLqIxZAn1AnbJhS/vdiyL6uz1APa8 ONe5UP5LCRSTzKqisAcsEfQ82tD08r3iMFZBsD4Ycxpa1BxgktP3XtPD16C8QN9KS9VB zNPkXfvsag5tcOlLnPlI/fhm4CDKa/nSDaUiDS17XMmAgr8bmOcACYD+AdLJTCQdq241 aGbA== X-Gm-Message-State: ALyK8tJYAi0oH3aHYheZ2jVs++7qnr8ART/TVBQA/b+2wkvtmZvnT7niCw8oahYgC1jLZb56 X-Received: by 10.98.69.199 with SMTP id n68mr4333202pfi.160.1466073067572; Thu, 16 Jun 2016 03:31:07 -0700 (PDT) Received: from HTSAT-OPENLAB-SERVER.localdomain ([116.25.56.103]) by smtp.gmail.com with ESMTPSA id i8sm59522305pao.26.2016.06.16.03.31.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 16 Jun 2016 03:31:07 -0700 (PDT) From: Xinliang Liu To: p.zabel@pengutronix.de Cc: linux-kernel@vger.kernel.org, robh+dt@kernel.org, xuwei5@hisilicon.com, puck.chen@hisilicon.com, saberlily.xia@hisilicon.com, kong.kongxinwei@hisilicon.com, guodong.xu@linaro.org, Xinliang Liu Subject: [PATCH v2 3/3] reset: hisilicon: Add hi6220 media subsystem reset support Date: Thu, 16 Jun 2016 18:30:00 +0800 Message-Id: <20160616103000.239669-4-xinliang.liu@linaro.org> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160616103000.239669-1-xinliang.liu@linaro.org> References: <20160616103000.239669-1-xinliang.liu@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chen Feng Add media subsystem reset support for hi6220. Signed-off-by: Chen Feng Signed-off-by: Xia Qing Signed-off-by: Xinliang Liu --- drivers/reset/hisilicon/hi6220_reset.c | 122 +++++++++++++++++++++++---------- 1 file changed, 86 insertions(+), 36 deletions(-) -- 2.8.3 diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 8f55fd4a2630..35ce53edabf9 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -1,7 +1,8 @@ /* * Hisilicon Hi6220 reset controller driver * - * Copyright (c) 2015 Hisilicon Limited. + * Copyright (c) 2016 Linaro Limited. + * Copyright (c) 2015-2016 Hisilicon Limited. * * Author: Feng Chen * @@ -15,81 +16,130 @@ #include #include #include +#include +#include +#include #include #include #include -#define ASSERT_OFFSET 0x300 -#define DEASSERT_OFFSET 0x304 -#define MAX_INDEX 0x509 +#define PERIPH_ASSERT_OFFSET 0x300 +#define PERIPH_DEASSERT_OFFSET 0x304 +#define PERIPH_MAX_INDEX 0x509 + +#define SC_MEDIA_RSTEN 0x052C +#define SC_MEDIA_RSTDIS 0x0530 +#define MEDIA_MAX_INDEX 8 #define to_reset_data(x) container_of(x, struct hi6220_reset_data, rc_dev) +enum hi6220_reset_ctrl_type { + PERIPHERAL, + MEDIA, +}; + struct hi6220_reset_data { - void __iomem *assert_base; - void __iomem *deassert_base; - struct reset_controller_dev rc_dev; + struct reset_controller_dev rc_dev; + struct regmap *regmap; }; -static int hi6220_reset_assert(struct reset_controller_dev *rc_dev, - unsigned long idx) +static int hi6220_peripheral_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; + u32 bank = idx >> 8; + u32 offset = idx & 0xff; + u32 reg = PERIPH_ASSERT_OFFSET + bank * 0x10; - int bank = idx >> 8; - int offset = idx & 0xff; + return regmap_write(regmap, reg, BIT(offset)); +} - writel(BIT(offset), data->assert_base + (bank * 0x10)); +static int hi6220_peripheral_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; + u32 bank = idx >> 8; + u32 offset = idx & 0xff; + u32 reg = PERIPH_DEASSERT_OFFSET + bank * 0x10; - return 0; + return regmap_write(regmap, reg, BIT(offset)); } -static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev, - unsigned long idx) +static const struct reset_control_ops hi6220_peripheral_reset_ops = { + .assert = hi6220_peripheral_assert, + .deassert = hi6220_peripheral_deassert, +}; + +static int hi6220_media_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; + return regmap_write(regmap, SC_MEDIA_RSTEN, BIT(idx)); +} - writel(BIT(offset), data->deassert_base + (bank * 0x10)); +static int hi6220_media_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; - return 0; + return regmap_write(regmap, SC_MEDIA_RSTDIS, BIT(idx)); } -static const struct reset_control_ops hi6220_reset_ops = { - .assert = hi6220_reset_assert, - .deassert = hi6220_reset_deassert, +static const struct reset_control_ops hi6220_media_reset_ops = { + .assert = hi6220_media_assert, + .deassert = hi6220_media_deassert, }; 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); + + 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->assert_base = src_base + ASSERT_OFFSET; - data->deassert_base = src_base + DEASSERT_OFFSET; - data->rc_dev.nr_resets = MAX_INDEX; - data->rc_dev.ops = &hi6220_reset_ops; - data->rc_dev.of_node = pdev->dev.of_node; + data->regmap = regmap; + data->rc_dev.of_node = np; + if (type == MEDIA) { + data->rc_dev.ops = &hi6220_media_reset_ops; + data->rc_dev.nr_resets = MEDIA_MAX_INDEX; + } else { + data->rc_dev.ops = &hi6220_peripheral_reset_ops; + data->rc_dev.nr_resets = PERIPH_MAX_INDEX; + } return reset_controller_register(&data->rc_dev); } static const struct of_device_id hi6220_reset_match[] = { - { .compatible = "hisilicon,hi6220-sysctrl" }, - { }, + { + .compatible = "hisilicon,hi6220-sysctrl", + .data = (void *)PERIPHERAL, + }, + { + .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,