From patchwork Thu Sep 24 14:26:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 54097 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by patches.linaro.org (Postfix) with ESMTPS id F14D322DC2 for ; Thu, 24 Sep 2015 14:27:29 +0000 (UTC) Received: by wicgb1 with SMTP id gb1sf42159436wic.3 for ; Thu, 24 Sep 2015 07:27:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe; bh=FXgqG+E0w4KEpPK+BROsx788pV0i8gkfiCj/IbacJ10=; b=aqNBmqhOBGqqCa3fvgiI2iWwFViTB07aChfwA2LMbFpDDM0JSjUIk/emaDxGL5gItg ondimQixQqhzABTlyfBQ9m47+f0aH0Plq8y2l7AYxEatnlOvtDXjPJOlNsPCYnMR69PT GtrnxSj2AASwFxPlRVIlom3EVbrDQ+BKMt8tOzgep/7TuOaB2lZfkinpEHbvLT8kG54h nTJuLt5H+DJzQaZNx7aOFzN1+09+GzrHm41sSxwUcPU1B0XwWE+0dBZJf/iz8qbp4ZWR VddSYi362b7uFwJvlHExppoxn25U+xwnXCNfxkfIekMDBH7pHNxkvmPnlk5hisqw/jNQ y0Ow== X-Gm-Message-State: ALoCoQnOYp/nYxT3BbykymCJ7qt3fz95HZ8B3QvgNtbWOLCc1Wji0GqageU1OCtsDxKuWEd8KbIN X-Received: by 10.152.21.42 with SMTP id s10mr6159582lae.9.1443104849236; Thu, 24 Sep 2015 07:27:29 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.19.233 with SMTP id i9ls51864lae.4.gmail; Thu, 24 Sep 2015 07:27:29 -0700 (PDT) X-Received: by 10.152.219.4 with SMTP id pk4mr3573456lac.94.1443104849100; Thu, 24 Sep 2015 07:27:29 -0700 (PDT) Received: from mail-la0-f42.google.com (mail-la0-f42.google.com. [209.85.215.42]) by mx.google.com with ESMTPS id vn6si4839475lbb.74.2015.09.24.07.27.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 Sep 2015 07:27:28 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) client-ip=209.85.215.42; Received: by lacdq2 with SMTP id dq2so10414326lac.1 for ; Thu, 24 Sep 2015 07:27:28 -0700 (PDT) X-Received: by 10.152.18.167 with SMTP id x7mr2962546lad.29.1443104848810; Thu, 24 Sep 2015 07:27:28 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp378596lbq; Thu, 24 Sep 2015 07:27:27 -0700 (PDT) X-Received: by 10.68.69.8 with SMTP id a8mr42820734pbu.144.1443104845724; Thu, 24 Sep 2015 07:27:25 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ou3si18845730pbb.11.2015.09.24.07.27.25; Thu, 24 Sep 2015 07:27:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-omap-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752545AbbIXO1X (ORCPT + 5 others); Thu, 24 Sep 2015 10:27:23 -0400 Received: from arroyo.ext.ti.com ([192.94.94.40]:46748 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752363AbbIXO1V (ORCPT ); Thu, 24 Sep 2015 10:27:21 -0400 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id t8OEQqu5013065; Thu, 24 Sep 2015 09:26:52 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id t8OEQqT6011508; Thu, 24 Sep 2015 09:26:52 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.3.224.2; Thu, 24 Sep 2015 09:26:52 -0500 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id t8OEQjRQ012528; Thu, 24 Sep 2015 09:26:50 -0500 From: Tero Kristo To: , , , CC: Subject: [PATCH 01/17] ARM: OMAP2+: PRM: add support for reset controller Date: Thu, 24 Sep 2015 17:26:42 +0300 Message-ID: <1443104818-993-2-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1443104818-993-1-git-send-email-t-kristo@ti.com> References: <1443104818-993-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: t-kristo@ti.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , PRM driver now supports reset controller for the defined reset lines. Reset configurations are provided through device tree. Later, functionality like hwmod and system reboot will be changed to use the generic framework. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/Kconfig | 1 + arch/arm/mach-omap2/prm_common.c | 167 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 07d2e10..ac3ef43 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -92,6 +92,7 @@ config ARCH_OMAP2PLUS select SOC_BUS select TI_PRIV_EDMA select OMAP_IRQCHIP + select RESET_CONTROLLER help Systems based on OMAP2, OMAP3, OMAP4 or OMAP5 diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 3fc2cbe..161d8ab 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "soc.h" #include "prm2xxx_3xxx.h" @@ -51,6 +53,11 @@ #define OMAP_PRCM_MAX_NR_PENDING_REG 2 /* + * Default partition for OMAP resets, maps to PRM + */ +#define OMAP_RESET_DEFAULT_PARTITION 1 + +/* * prcm_irq_chips: an array of all of the "generic IRQ chips" in use * by the PRCM interrupt handler code. There will be one 'chip' per * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have @@ -737,6 +744,162 @@ static const struct of_device_id const omap_prcm_dt_match_table[] __initconst = { } }; +struct ti_reset_data { + s16 module; + u16 offset; + u16 st_offset; + u8 shift; + u8 st_shift; + u8 part; +}; + +struct ti_reset_ctrl { + struct reset_controller_dev rcdev; + struct ti_reset_data **resets; + int num_resets; + int max_resets; + s16 offset; +}; + +#define to_ti_reset_ctrl(_rcdev) container_of(_rcdev, struct ti_reset_ctrl, \ + rcdev) + +static struct ti_reset_data *_get_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ti_reset_ctrl *ctrl = to_ti_reset_ctrl(rcdev); + + return ctrl->resets[id]; +} + +static int ti_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ti_reset_data *reset = _get_reset(rcdev, id); + + return omap_prm_assert_hardreset(reset->shift, reset->part, + reset->module, reset->offset); +} + +static int ti_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ti_reset_data *reset = _get_reset(rcdev, id); + + return omap_prm_deassert_hardreset(reset->shift, reset->st_shift, + reset->part, reset->module, + reset->offset, reset->st_offset); +} + +static int ti_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ti_reset_data *reset = _get_reset(rcdev, id); + + return omap_prm_is_hardreset_asserted(reset->shift, reset->part, + reset->module, reset->offset); +} + +static struct reset_control_ops ti_reset_ops = { + .assert = ti_reset_assert, + .deassert = ti_reset_deassert, + .status = ti_reset_status, +}; + +static int ti_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct ti_reset_ctrl *ctrl = to_ti_reset_ctrl(rcdev); + s16 module; + u16 offset, st_offset; + u8 shift, st_shift; + int index = 0; + struct ti_reset_data *reset; + + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) + return -EINVAL; + + module = reset_spec->args[0] - ctrl->offset; + offset = reset_spec->args[1]; + shift = reset_spec->args[2]; + st_offset = reset_spec->args[3]; + st_shift = reset_spec->args[4]; + + for (index = 0; index < ctrl->num_resets; index++) { + reset = ctrl->resets[index]; + + if (module == reset->module && offset == reset->offset && + st_offset == reset->st_offset && shift == reset->shift && + st_shift == reset->st_shift) + return index; + } + + reset = kzalloc(sizeof(*reset), GFP_KERNEL); + + reset->module = module; + reset->offset = offset; + reset->st_offset = st_offset; + reset->shift = shift; + reset->st_shift = st_shift; + reset->part = OMAP_RESET_DEFAULT_PARTITION; + + if (ctrl->num_resets + 1 > ctrl->max_resets) { + struct ti_reset_data **arr; + int num; + + num = ctrl->num_resets; + num *= 2; + if (!num) + num = 1; + + arr = kcalloc(num, sizeof(*arr), GFP_KERNEL); + ctrl->max_resets = num; + if (ctrl->num_resets) + memcpy(arr, ctrl->resets, + sizeof(*arr) * ctrl->num_resets); + + kfree(ctrl->resets); + ctrl->resets = arr; + } + + ctrl->resets[index] = reset; + ctrl->num_resets++; + + return index; +} + +/** + * omap2_prm_reset_controller_register - register reset controller for a node + * @node: device node to register reset controller for + * @data: PRM init data for the node + * + * Registers a reset controller for the PRM node if applicable. Return 0 + * in success, negative error value in failure. + */ +int __init +omap2_prm_reset_controller_register(struct device_node *np, + const struct omap_prcm_init_data *data) +{ + struct ti_reset_ctrl *ctrl; + + /* Reset controllers available only for PRM nodes */ + if (data->index != TI_CLKM_PRM) + return 0; + + ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + + ctrl->rcdev.of_node = np; + ctrl->rcdev.of_reset_n_cells = 5; + ctrl->rcdev.ops = &ti_reset_ops; + ctrl->rcdev.of_xlate = &ti_reset_xlate; + + ctrl->offset = data->offset; + + reset_controller_register(&ctrl->rcdev); + + return 0; +} + /** * omap2_prm_base_init - initialize iomappings for the PRM driver * @@ -802,6 +965,10 @@ int __init omap_prcm_init(void) ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; + + ret = omap2_prm_reset_controller_register(np, data); + if (ret) + return ret; } omap_cm_init();