From 7708f7471ab45039e08237b42121d0372f9216a7 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Jun 2021 23:42:19 -0500 Subject: [PATCH 043/117] hwspinlock: sun6i: Clarify bank counting logic In some of the most recent datasheets, the register definition was updated in a way that resolves the conflict here: the field is only two bits wide, and a value of "4" really means a bit pattern of "0". Correct the code to reflect this, but leave an updated comment because some datasheets still have incorrect information in them. Fixes: 3c881e05c814 ("hwspinlock: add sun6i hardware spinlock support") Signed-off-by: Samuel Holland --- drivers/hwspinlock/sun6i_hwspinlock.c | 36 +++++++++++---------------- 1 file changed, 14 insertions(+), 22 deletions(-) --- a/drivers/hwspinlock/sun6i_hwspinlock.c +++ b/drivers/hwspinlock/sun6i_hwspinlock.c @@ -129,30 +129,22 @@ static int sun6i_hwspinlock_probe(struct } /* - * bit 28 and 29 represents the hwspinlock setup + * Bits 28 and 29 represent the number of available locks. * - * every datasheet (A64, A80, A83T, H3, H5, H6 ...) says the default value is 0x1 and 0x1 - * to 0x4 represent 32, 64, 128 and 256 locks - * but later datasheets (H5, H6) say 00, 01, 10, 11 represent 32, 64, 128 and 256 locks, - * but that would mean H5 and H6 have 64 locks, while their datasheets talk about 32 locks - * all the time, not a single mentioning of 64 locks - * the 0x4 value is also not representable by 2 bits alone, so some datasheets are not - * correct - * one thing have all in common, default value of the sysstatus register is 0x10000000, - * which results in bit 28 being set - * this is the reason 0x1 is considered being 32 locks and bit 30 is taken into account - * verified on H2+ (datasheet 0x1 = 32 locks) and H5 (datasheet 01 = 64 locks) + * The datasheets have two conflicting interpretations for these bits: + * | 00 | 01 | 10 | 11 | + * +-----+----+-----+-----+ + * | 256 | 32 | 64 | 128 | A80, A83T, H3, A64, A50, D1 + * | 32 | 64 | 128 | 256 | H5, H6, R329 + * where some datasheets use "4" instead of "0" for the first column. + * + * Experiments shows that the first interpretation is correct, as all + * known implementations report the value "1" and have 32 spinlocks. */ - num_banks = readl(io_base + SPINLOCK_SYSSTATUS_REG) >> 28; - switch (num_banks) { - case 1 ... 4: - priv->nlocks = 1 << (4 + num_banks); - break; - default: - err = -EINVAL; - dev_err(&pdev->dev, "unsupported hwspinlock setup (%d)\n", num_banks); - goto bank_fail; - } + num_banks = readl(io_base + SPINLOCK_SYSSTATUS_REG) >> 28 & 0x3; + if (!num_banks) + num_banks = 4; + priv->nlocks = 1 << (4 + num_banks); priv->bank = devm_kzalloc(&pdev->dev, struct_size(priv->bank, lock, priv->nlocks), GFP_KERNEL);