From patchwork Mon Mar 28 04:09:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 8677801 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C218BC0553 for ; Mon, 28 Mar 2016 04:10:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C1D7320220 for ; Mon, 28 Mar 2016 04:10:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AE9E520154 for ; Mon, 28 Mar 2016 04:10:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752924AbcC1EKR (ORCPT ); Mon, 28 Mar 2016 00:10:17 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:45529 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751168AbcC1EKQ (ORCPT ); Mon, 28 Mar 2016 00:10:16 -0400 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O4Q00BT6E8ZAM70@mailout3.w1.samsung.com>; Mon, 28 Mar 2016 05:10:11 +0100 (BST) X-AuditID: cbfec7f4-f796c6d000001486-98-56f8aea29ef3 Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 36.20.05254.2AEA8F65; Mon, 28 Mar 2016 05:10:10 +0100 (BST) Received: from localhost.localdomain ([10.113.63.52]) by eusync4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O4Q0094JE8RFH00@eusync4.samsung.com>; Mon, 28 Mar 2016 05:10:10 +0100 (BST) From: Krzysztof Kozlowski To: Sangbeom Kim , Krzysztof Kozlowski , Liam Girdwood , Mark Brown , Lee Jones , linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: linux-mmc@vger.kernel.org, Javier Martinez Canillas , Ivaylo Dimitrov , stable@vger.kernel.org Subject: [PATCH v2] regulator: s2mps11: Fix invalid selector mask and voltages for buck9 Date: Mon, 28 Mar 2016 13:09:56 +0900 Message-id: <1459138196-13672-1-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 2.5.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprCLMWRmVeSWpSXmKPExsVy+t/xa7qL1v0IM5i7Ut9i6sMnbBZLrhxi t3jzdg2TxesXhhb3vx5ltPh2pYPJ4vKuOWwWR/73M1rMOL+PyeLiii9MFgs2PmJ04PbYOesu u8emVZ1sHneu7WHz2NIP5PZtWcXo8XmTXABbFJdNSmpOZllqkb5dAldG7/t9rAUv1So+f7/J 2MB4TaGLkZNDQsBE4snpJkYIW0ziwr31bF2MXBxCAksZJY7MOMoMkhAS+M8osWhJMYjNJmAs sXn5ErAiEYE2JomJfQcYQRxmgdmMEldud7KAVAkLRElsPXYMrJtFQFXi5Yt7YHFeAXeJncf+ AsU5gNbJSSy4kD6BkXsBI8MqRtHU0uSC4qT0XEO94sTc4tK8dL3k/NxNjJCw+rKDcfExq0OM AhyMSjy8GZY/woRYE8uKK3MPMUpwMCuJ8P5YAxTiTUmsrEotyo8vKs1JLT7EKM3BoiTOO3fX +xAhgfTEktTs1NSC1CKYLBMHp1QDY92Lx3EF0/c3PjslcqXg8YkJga03ukIkUlWq82xEf789 9J7XeULkwqqwDU/V9y/jzmaRXvaaX+FGfO5WwXNvrjv+85vhH3rRJvnL1vnZT294Xfj6SeCZ k02CzM8f023jvHR2aaku7ZrULabO6/3VLPv+n/9LXKKZ1L5tjC+8p5yd8YnvdVNgohJLcUai oRZzUXEiAEAukFAnAgAA Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The buck9 regulator of S2MPS11 PMIC had incorrect vsel_mask (0xff instead of 0x1f) thus reading entire register as buck9's voltage. This effectively caused regulator core to interpret values as higher voltages than they were and then to set real voltage much lower than intended. The buck9 provides power to other regulators, including LDO13 and LDO19 which supply the MMC2 (SD card). On Odroid XU3/XU4 the lower voltage caused SD card detection errors on Odroid XU3/XU4: mmc1: card never left busy state mmc1: error -110 whilst initialising SD card During driver probe the regulator core was checking whether initial voltage matches the constraints. With incorrect vsel_mask of 0xff and default value of 0x50, the core interpreted this as 5 V which is outside of constraints (3-3.775 V). Then the regulator core was adjusting the voltage to match the constraints. With incorrect vsel_mask this new voltage mapped to a vere low voltage in the driver. Fixes: cb74685ecb39 ("regulator: s2mps11: Add samsung s2mps11 regulator driver") Cc: Signed-off-by: Krzysztof Kozlowski Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas --- Changes since v1: 1. The driver did not lack minimal linear selector but the selector mask was wrong. The effect was exactly the same - writing values corresponding to a lower voltage in reality. Instead of setting '.linear_min_sel', set the '.vsel_mask' to a proper value. 2. Rewrite title/commit. 3. Minor changes after Javier's review. 4. Add Javier's review/tested by. The issue can be reproduced on next-20160324 with bae4fdc88d7f7dda1 (regulator: core: Ensure we are at least in bounds for our constraints). --- drivers/regulator/s2mps11.c | 28 ++++++++++++++++++++++------ include/linux/mfd/samsung/s2mps11.h | 2 ++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d24e2c783dc5..6dfa3502e1f1 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -308,7 +308,7 @@ static struct regulator_ops s2mps11_buck_ops = { .enable_mask = S2MPS11_ENABLE_MASK \ } -#define regulator_desc_s2mps11_buck6_10(num, min, step) { \ +#define regulator_desc_s2mps11_buck67810(num, min, step) { \ .name = "BUCK"#num, \ .id = S2MPS11_BUCK##num, \ .ops = &s2mps11_buck_ops, \ @@ -324,6 +324,22 @@ static struct regulator_ops s2mps11_buck_ops = { .enable_mask = S2MPS11_ENABLE_MASK \ } +#define regulator_desc_s2mps11_buck9 { \ + .name = "BUCK9", \ + .id = S2MPS11_BUCK9, \ + .ops = &s2mps11_buck_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MIN_3000_MV, \ + .uV_step = STEP_25_MV, \ + .n_voltages = S2MPS11_BUCK9_N_VOLTAGES, \ + .ramp_delay = S2MPS11_RAMP_DELAY, \ + .vsel_reg = S2MPS11_REG_B9CTRL2, \ + .vsel_mask = S2MPS11_BUCK9_VSEL_MASK, \ + .enable_reg = S2MPS11_REG_B9CTRL1, \ + .enable_mask = S2MPS11_ENABLE_MASK \ +} + static const struct regulator_desc s2mps11_regulators[] = { regulator_desc_s2mps11_ldo(1, STEP_25_MV), regulator_desc_s2mps11_ldo(2, STEP_50_MV), @@ -368,11 +384,11 @@ static const struct regulator_desc s2mps11_regulators[] = { regulator_desc_s2mps11_buck1_4(3), regulator_desc_s2mps11_buck1_4(4), regulator_desc_s2mps11_buck5, - regulator_desc_s2mps11_buck6_10(6, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps11_buck6_10(7, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps11_buck6_10(8, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps11_buck6_10(9, MIN_3000_MV, STEP_25_MV), - regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV), + regulator_desc_s2mps11_buck67810(6, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck67810(7, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck67810(8, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck9, + regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV), }; static struct regulator_ops s2mps14_reg_ops; diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h index b288965e8101..2c14eeca46f0 100644 --- a/include/linux/mfd/samsung/s2mps11.h +++ b/include/linux/mfd/samsung/s2mps11.h @@ -173,10 +173,12 @@ enum s2mps11_regulators { #define S2MPS11_LDO_VSEL_MASK 0x3F #define S2MPS11_BUCK_VSEL_MASK 0xFF +#define S2MPS11_BUCK9_VSEL_MASK 0x1F #define S2MPS11_ENABLE_MASK (0x03 << S2MPS11_ENABLE_SHIFT) #define S2MPS11_ENABLE_SHIFT 0x06 #define S2MPS11_LDO_N_VOLTAGES (S2MPS11_LDO_VSEL_MASK + 1) #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1) +#define S2MPS11_BUCK9_N_VOLTAGES (S2MPS11_BUCK9_VSEL_MASK + 1) #define S2MPS11_RAMP_DELAY 25000 /* uV/us */ #define S2MPS11_CTRL1_PWRHOLD_MASK BIT(4)