From patchwork Mon May 31 12:51:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Marko X-Patchwork-Id: 450613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58319C47080 for ; Mon, 31 May 2021 12:52:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A41A61370 for ; Mon, 31 May 2021 12:52:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231640AbhEaMxn (ORCPT ); Mon, 31 May 2021 08:53:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231570AbhEaMxi (ORCPT ); Mon, 31 May 2021 08:53:38 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A6D2C0613ED for ; Mon, 31 May 2021 05:51:57 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id r11so13314129edt.13 for ; Mon, 31 May 2021 05:51:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sartura-hr.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XjEzASVU9scj5dmW62IH9zeguW+sgaX7MMoFAXfUjpU=; b=guk4WPwpu5SGv+uNceXgQOjWrU7Rh+igRQOz8BNAR5jzojJ27z7n0UNnaSuQe6151P nUwCbzMYQKb120vJAlzlxi8H6wF1+pb7umGm53nWVHtOq98EV5bbiaeEwP0TbYrh7ydR 9Zqa8y0WZboq1y5N8suO38FVdSuz1qdHaWjEjqkH7nT/e9RnNlUt/ZKMsgAWGxHoC1SW 3x5MJrLEmJJNoRhM0m31puR5+FKXn3sK/P8CDqkrJ38AAsyZ+ndbt1Vl6FeO3SyPQH98 bnMVy5+EJVqgRCrYH5WnidmQpqeQp9wgxv2JrHivOq3G//RwCIkiQWYQEPoM24FeVl59 Ghlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XjEzASVU9scj5dmW62IH9zeguW+sgaX7MMoFAXfUjpU=; b=E9mcngnIZ6038kqwgiYwLvU1+p2+m7Li2TJfSuX1Kmj0tF9mwXL1xyugIgjdhX1Hou pTu0pvbMzq1D/qjIavckqEnS0O7Moz6oNDFPs5Uh3tAYUWgAyvA1LQfgYf6dfzM7UDqe Pp/yjTfUiLEHN7X3Y3hljOFPf3r/mk4lkKmCbPpWotNK+HsdCf3YVIJg8A8TtvjgDhUw 1GWt27VlVjxmUk3E/jMLojnTLotKOQJyGp6TqZJAVCL6kNk59qiCGfyuLuzM1/XU/kcG rfoOmPD0XJPTk+jkNdwH55vnSdyvxOsyEzS01TWEBGKi7A7kr/o7KR3w8mn31gXBqam0 WNGw== X-Gm-Message-State: AOAM5325D1HzsiGSAqG+puaXvW2lls2oIfvcwC4eYj7t3XHjb6ea+jFl BT+OlQ5gYMXxiUC1fzf3FR2tkA== X-Google-Smtp-Source: ABdhPJy+WuaUMmZEBAIE8oalDaV2lIAeG1z++Ha4OTpOqtdE5BcAn5W4MLuwDY7VWq+U/18eXWQX1A== X-Received: by 2002:a50:eb08:: with SMTP id y8mr25490650edp.89.1622465515858; Mon, 31 May 2021 05:51:55 -0700 (PDT) Received: from localhost.localdomain ([188.252.220.231]) by smtp.googlemail.com with ESMTPSA id zb2sm5886898ejb.52.2021.05.31.05.51.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 May 2021 05:51:55 -0700 (PDT) From: Robert Marko To: lee.jones@linaro.org, linux-kernel@vger.kernel.org, linus.walleij@linaro.org, bgolaszewski@baylibre.com, linux-gpio@vger.kernel.org, p.zabel@pengutronix.de, robh+dt@kernel.org, devicetree@vger.kernel.org Cc: luka.perkov@sartura.hr, jmp@epiphyte.org, pmenzel@molgen.mpg.de, buczek@molgen.mpg.de, Robert Marko Subject: [PATCH v3 4/6] reset: Add Delta TN48M CPLD reset controller Date: Mon, 31 May 2021 14:51:41 +0200 Message-Id: <20210531125143.257622-4-robert.marko@sartura.hr> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531125143.257622-1-robert.marko@sartura.hr> References: <20210531125143.257622-1-robert.marko@sartura.hr> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Delta TN48M CPLD exposes resets for the following: * 88F7040 SoC * 88F6820 SoC * 98DX3265 switch MAC-s * 88E1680 PHY-s * 88E1512 PHY * PoE PSE controller Signed-off-by: Robert Marko --- drivers/reset/Kconfig | 9 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-tn48m.c | 128 ++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 drivers/reset/reset-tn48m.c diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 4171c6f76385..e3ff4b020c96 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -64,6 +64,15 @@ config RESET_BRCMSTB_RESCAL This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on BCM7216. +config RESET_TN48M_CPLD + tristate "Delta Networks TN48M switch CPLD reset controller" + depends on MFD_TN48M_CPLD + help + This enables the reset controller driver for the Delta TN48M CPLD. + It provides reset signals for Armada 7040 and 385 SoC-s, Alleycat 3X + switch MAC-s, Alaska OOB ethernet PHY, Quad Alaska ethernet PHY-s and + Microchip PD69200 PoE PSE controller. + config RESET_HSDK bool "Synopsys HSDK Reset Driver" depends on HAS_IOMEM diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 65a118a91b27..6d6945638b76 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o +obj-$(CONFIG_RESET_TN48M_CPLD) += reset-tn48m.o obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o diff --git a/drivers/reset/reset-tn48m.c b/drivers/reset/reset-tn48m.c new file mode 100644 index 000000000000..960ee5f4eb40 --- /dev/null +++ b/drivers/reset/reset-tn48m.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Delta TN48M CPLD reset driver + * + * Copyright 2021 Sartura Ltd + * + * Author: Robert Marko + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define TN48M_RESET_REG 0x10 + +struct tn48_reset_map { + u8 bit; +}; + +struct tn48_reset_data { + struct reset_controller_dev rcdev; + struct regmap *regmap; +}; + +static const struct tn48_reset_map tn48m_resets[] = { + [CPU_88F7040_RESET] = {0}, + [CPU_88F6820_RESET] = {1}, + [MAC_98DX3265_RESET] = {2}, + [PHY_88E1680_RESET] = {4}, + [PHY_88E1512_RESET] = {6}, + [POE_RESET] = {7}, +}; + +static inline struct tn48_reset_data *to_tn48_reset_data( + struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct tn48_reset_data, rcdev); +} + +static int tn48m_control_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct tn48_reset_data *data = to_tn48_reset_data(rcdev); + + return regmap_update_bits(data->regmap, TN48M_RESET_REG, + BIT(tn48m_resets[id].bit), 0); +} + +static int tn48m_control_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return tn48m_control_assert(rcdev, id); +} + +static int tn48m_control_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct tn48_reset_data *data = to_tn48_reset_data(rcdev); + unsigned int regval; + int ret; + + ret = regmap_read(data->regmap, TN48M_RESET_REG, ®val); + if (ret < 0) + return ret; + + if (BIT(tn48m_resets[id].bit) & regval) + return 0; + else + return 1; +} + +static const struct reset_control_ops tn48_reset_ops = { + .reset = tn48m_control_reset, + .assert = tn48m_control_assert, + .status = tn48m_control_status, +}; + +static int tn48m_reset_probe(struct platform_device *pdev) +{ + struct tn48_reset_data *data; + struct regmap *regmap; + + if (!pdev->dev.parent) + return -ENODEV; + + regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!regmap) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->regmap = regmap; + + data->rcdev.owner = THIS_MODULE; + data->rcdev.ops = &tn48_reset_ops; + data->rcdev.nr_resets = ARRAY_SIZE(tn48m_resets); + data->rcdev.of_node = pdev->dev.of_node; + + return devm_reset_controller_register(&pdev->dev, &data->rcdev); +} + +static const struct of_device_id tn48m_reset_of_match[] = { + { .compatible = "delta,tn48m-reset", }, + { } +}; +MODULE_DEVICE_TABLE(of, tn48m_reset_of_match); + +static struct platform_driver tn48m_reset_driver = { + .driver = { + .name = "delta-tn48m-reset", + .of_match_table = tn48m_reset_of_match, + }, + .probe = tn48m_reset_probe, +}; +module_platform_driver(tn48m_reset_driver); + +MODULE_AUTHOR("Robert Marko "); +MODULE_DESCRIPTION("Delta TN48M CPLD reset driver"); +MODULE_LICENSE("GPL");