From patchwork Wed Nov 1 02:11:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "\(Exiting\) Baolin Wang" X-Patchwork-Id: 117667 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp307129qgn; Tue, 31 Oct 2017 19:13:01 -0700 (PDT) X-Google-Smtp-Source: ABhQp+SqckVOGTEaEtlCsMcBAhP1oqWLWbUX+s4QIZmfl9f/tLH/G+NR4iIJLN6leYfDZkFLAKAK X-Received: by 10.101.71.197 with SMTP id f5mr3967610pgs.266.1509502380937; Tue, 31 Oct 2017 19:13:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509502380; cv=none; d=google.com; s=arc-20160816; b=g+ihN9/+3Q1si9LNmqeKAQu3bUSzMaDuyO3Q4lMwfkYccSlFfossplmrmBcvH3eDT8 bcMnFAHk8j9PNvq6ja/4qqIVyBf3DkY/bZrPIS0vwTP167c4crCcPV9tlChG7KVZS0wd /pjqtoGkNn9xLdDhlgQ3omHolnST9bOLwl/c35Ylvkg/UysqWsKRx+KxA2cxGyq1ZBLQ vwl+E3ujWHsQGScwsT5oUf9+lDCLyyzdeTSsRXYJfpnwPGXOyTqHTRWS9Vrd3sP7EpYX eCX+SzMaoXqLpS07yZintV9aJA4vsCV2fRLjpXi6qZht4j5gd7SwPfPdS/hdwjLYWy2z jpoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=y9mrcMpGeVrTvkb6BP/arlYzzqpeJhM6YYSqRlvanNw=; b=c8G4aV2zT6v5OmpEzd9hK6X+F14qsmXtn4fpFIymvokX4KhkaNdWHTd1y8N8aUObw2 v5Eia2ysl0TFms/I7m3pxA/0boIztzQP1i669sBtZ9Uj5myTYBkqvUhdDYlk0Oyo/9pC nT89mFRVHKNVdWIMLCDMCLB2s9mRBqBr1kHa3aN1ckTZtdUHu6GasTvmoSZDwaA8FOTT YC4i70/O9dmRzPIK6Dqc03VCV7pCOosgm03A+17NYf0fMYci0Rd0v+Et1f6SUhXblFaW fjjlBNoXgN56CfJQwD1LVX7YRbW0+373VtNtl4EmINT1cTxI7ID4CRb+Ur4qGTT1hLMX yhMg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Fx4iaDsb; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 63si2946514pgi.654.2017.10.31.19.13.00; Tue, 31 Oct 2017 19:13:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Fx4iaDsb; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932912AbdKACM7 (ORCPT + 6 others); Tue, 31 Oct 2017 22:12:59 -0400 Received: from mail-pg0-f66.google.com ([74.125.83.66]:54518 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932877AbdKACM6 (ORCPT ); Tue, 31 Oct 2017 22:12:58 -0400 Received: by mail-pg0-f66.google.com with SMTP id l24so822075pgu.11 for ; Tue, 31 Oct 2017 19:12:58 -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; bh=U7xLdGEioPvNy4cnBnxxnurzCe8EpMZYeGUZOKMsP+I=; b=Fx4iaDsb7G9mJXeJLshdlwctirzhYW7IvLrJxtrAAzE8aSioDFo0QaGdZdaD4uU/Kp HHtgVCXxuGFGTAVd0OIxsXXfL2Qv3P8D+fuyJqveTYYyfxpOqOwg+vzwxVGfL5BO1uaN r2W1L5VRIXcHJQxTkF6zfNxxYSQzMuR13qUNE= 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; bh=U7xLdGEioPvNy4cnBnxxnurzCe8EpMZYeGUZOKMsP+I=; b=YAhetxFqafmHlno62aUfLRBiGU/OIv9KbnOwtUvxf2/5kzb14dMHelJ/CMHEmg+Ukx +AvxCAGfTyi8ZQoCA3CSGHixoSgh4WU02i+QKfjElfVQtJXa/m26PCqaOsX7AshFXK8K zizg/bU2gi8EuOmvEhM9VmuRP+nWChAmTL/7O0/o5XUo2tG4lPZnpJAMDW/8u4RYN8NJ 7IoYIj2nTtutzryv+R0r9nt+g3Yi3KhKkT/SVDqwftYHTuYBASXMHXXGCm8acjfRe7AV 4Y/H0vWe/r8nq05OTDSITHO3YU9IlxJ1WqCiDWIOtZCluCh+GOPtqOqV5Ffs1wrKNa7Q bc2w== X-Gm-Message-State: AMCzsaXiifIjCUIU7LgUDHjBboU6aVk9IUD2muSWtTq5yMxdRe5NPG45 L/jgUt35tiA5cAUahNNYZ4rObQ== X-Received: by 10.98.15.22 with SMTP id x22mr4423384pfi.13.1509502377898; Tue, 31 Oct 2017 19:12:57 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id x87sm5108406pfi.10.2017.10.31.19.12.54 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 31 Oct 2017 19:12:57 -0700 (PDT) From: Baolin Wang To: broonie@kernel.org, gregkh@linuxfoundation.org, lee.jones@linaro.org, arnd@arndb.de, robh+dt@kernel.org, mark.rutland@arm.com Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, baolin.wang@linaro.org Subject: [PATCH v2 1/2] regmap: Add hardware spinlock support Date: Wed, 1 Nov 2017 10:11:55 +0800 Message-Id: <00b91de822135699da81f70c4d2b8fecbc113ab1.1509501110.git.baolin.wang@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org On some platforms, when reading or writing some special registers through regmap, we should acquire one hardware spinlock to synchronize between the multiple subsystems. Thus this patch adds the hardware spinlock support for regmap. Signed-off-by: Baolin Wang --- Changes since v1: - Move hwspinlock.h including to regmap.c file. - Remove hwspin_trylock_xxx() functions. - We always set the timeout as maximum values to avoid getting lock failed. - Coding style fixes. --- drivers/base/regmap/internal.h | 2 + drivers/base/regmap/regmap.c | 101 +++++++++++++++++++++++++++++++++------- include/linux/regmap.h | 6 +++ 3 files changed, 93 insertions(+), 16 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Acked-by: Rob Herring diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 2a4435d..8641183 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -157,6 +157,8 @@ struct regmap { struct rb_root range_tree; void *selector_work_buf; /* Scratch buffer used for selector */ + + struct hwspinlock *hwlock; }; struct regcache_ops { diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index b9a779a..999e981 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -20,6 +20,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include "trace.h" @@ -413,6 +414,49 @@ static unsigned int regmap_parse_64_native(const void *buf) } #endif +static void regmap_lock_hwlock(void *__map) +{ + struct regmap *map = __map; + + hwspin_lock_timeout(map->hwlock, UINT_MAX); +} + +static void regmap_lock_hwlock_irq(void *__map) +{ + struct regmap *map = __map; + + hwspin_lock_timeout_irq(map->hwlock, UINT_MAX); +} + +static void regmap_lock_hwlock_irqsave(void *__map) +{ + struct regmap *map = __map; + + hwspin_lock_timeout_irqsave(map->hwlock, UINT_MAX, + &map->spinlock_flags); +} + +static void regmap_unlock_hwlock(void *__map) +{ + struct regmap *map = __map; + + hwspin_unlock(map->hwlock); +} + +static void regmap_unlock_hwlock_irq(void *__map) +{ + struct regmap *map = __map; + + hwspin_unlock_irq(map->hwlock); +} + +static void regmap_unlock_hwlock_irqrestore(void *__map) +{ + struct regmap *map = __map; + + hwspin_unlock_irqrestore(map->hwlock, &map->spinlock_flags); +} + static void regmap_lock_mutex(void *__map) { struct regmap *map = __map; @@ -627,6 +671,29 @@ struct regmap *__regmap_init(struct device *dev, map->lock = config->lock; map->unlock = config->unlock; map->lock_arg = config->lock_arg; + } else if (config->hwlock_id) { + map->hwlock = hwspin_lock_request_specific(config->hwlock_id); + if (!map->hwlock) { + ret = -ENXIO; + goto err_map; + } + + switch (config->hwlock_mode) { + case HWLOCK_IRQSTATE: + map->lock = regmap_lock_hwlock_irqsave; + map->unlock = regmap_unlock_hwlock_irqrestore; + break; + case HWLOCK_IRQ: + map->lock = regmap_lock_hwlock_irq; + map->unlock = regmap_unlock_hwlock_irq; + break; + default: + map->lock = regmap_lock_hwlock; + map->unlock = regmap_unlock_hwlock; + break; + } + + map->lock_arg = map; } else { if ((bus && bus->fast_io) || config->fast_io) { @@ -729,7 +796,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_2_6_write; break; default: - goto err_map; + goto err_hwlock; } break; @@ -739,7 +806,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_4_12_write; break; default: - goto err_map; + goto err_hwlock; } break; @@ -749,7 +816,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_7_9_write; break; default: - goto err_map; + goto err_hwlock; } break; @@ -759,7 +826,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_10_14_write; break; default: - goto err_map; + goto err_hwlock; } break; @@ -779,13 +846,13 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_16_native; break; default: - goto err_map; + goto err_hwlock; } break; case 24: if (reg_endian != REGMAP_ENDIAN_BIG) - goto err_map; + goto err_hwlock; map->format.format_reg = regmap_format_24; break; @@ -801,7 +868,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_32_native; break; default: - goto err_map; + goto err_hwlock; } break; @@ -818,13 +885,13 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_64_native; break; default: - goto err_map; + goto err_hwlock; } break; #endif default: - goto err_map; + goto err_hwlock; } if (val_endian == REGMAP_ENDIAN_NATIVE) @@ -853,12 +920,12 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_16_native; break; default: - goto err_map; + goto err_hwlock; } break; case 24: if (val_endian != REGMAP_ENDIAN_BIG) - goto err_map; + goto err_hwlock; map->format.format_val = regmap_format_24; map->format.parse_val = regmap_parse_24; break; @@ -879,7 +946,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_32_native; break; default: - goto err_map; + goto err_hwlock; } break; #ifdef CONFIG_64BIT @@ -900,7 +967,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_64_native; break; default: - goto err_map; + goto err_hwlock; } break; #endif @@ -909,18 +976,18 @@ struct regmap *__regmap_init(struct device *dev, if (map->format.format_write) { if ((reg_endian != REGMAP_ENDIAN_BIG) || (val_endian != REGMAP_ENDIAN_BIG)) - goto err_map; + goto err_hwlock; map->use_single_write = true; } if (!map->format.format_write && !(map->format.format_reg && map->format.format_val)) - goto err_map; + goto err_hwlock; map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL); if (map->work_buf == NULL) { ret = -ENOMEM; - goto err_map; + goto err_hwlock; } if (map->format.format_write) { @@ -1041,6 +1108,8 @@ struct regmap *__regmap_init(struct device *dev, err_range: regmap_range_exit(map); kfree(map->work_buf); +err_hwlock: + hwspin_lock_free(map->hwlock); err_map: kfree(map); err: diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 978abfb..edc32aa 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -273,6 +273,9 @@ struct regmap_access_table { * * @ranges: Array of configuration entries for virtual address ranges. * @num_ranges: Number of range configuration entries. + * @hwlock_id: Specify the hardware spinlock id. + * @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE, + * HWLOCK_IRQ or 0. */ struct regmap_config { const char *name; @@ -317,6 +320,9 @@ struct regmap_config { const struct regmap_range_cfg *ranges; unsigned int num_ranges; + + unsigned int hwlock_id; + unsigned int hwlock_mode; }; /**