mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 17:53:56 +08:00
spi: sprd: adi: Change hwlock to be optional
Now Spreadtrum ADI controller supplies multiple master accessing channel to support multiple subsystems accessing, instead of using a hardware spinlock to synchronize between the multiple subsystems. To keep backward compatibility, we should change the hardware spinlock to be optional. Moreover change to use of_hwspin_lock_get_id() function which return -ENOENT error number to indicate no hwlock support. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Link: https://lore.kernel.org/r/2abe7dcf210e4197f8c5ece7fc6d6cc1eda8c655.1564125131.git.baolin.wang@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
e6d722ca09
commit
f9adf61e98
@ -165,14 +165,16 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
|
||||
int read_timeout = ADI_READ_TIMEOUT;
|
||||
unsigned long flags;
|
||||
u32 val, rd_addr;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
|
||||
ADI_HWSPINLOCK_TIMEOUT,
|
||||
&flags);
|
||||
if (ret) {
|
||||
dev_err(sadi->dev, "get the hw lock failed\n");
|
||||
return ret;
|
||||
if (sadi->hwlock) {
|
||||
ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
|
||||
ADI_HWSPINLOCK_TIMEOUT,
|
||||
&flags);
|
||||
if (ret) {
|
||||
dev_err(sadi->dev, "get the hw lock failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -219,7 +221,8 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
|
||||
*read_val = val & RD_VALUE_MASK;
|
||||
|
||||
out:
|
||||
hwspin_unlock_irqrestore(sadi->hwlock, &flags);
|
||||
if (sadi->hwlock)
|
||||
hwspin_unlock_irqrestore(sadi->hwlock, &flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -230,12 +233,14 @@ static int sprd_adi_write(struct sprd_adi *sadi, u32 reg_paddr, u32 val)
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
|
||||
ADI_HWSPINLOCK_TIMEOUT,
|
||||
&flags);
|
||||
if (ret) {
|
||||
dev_err(sadi->dev, "get the hw lock failed\n");
|
||||
return ret;
|
||||
if (sadi->hwlock) {
|
||||
ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
|
||||
ADI_HWSPINLOCK_TIMEOUT,
|
||||
&flags);
|
||||
if (ret) {
|
||||
dev_err(sadi->dev, "get the hw lock failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = sprd_adi_drain_fifo(sadi);
|
||||
@ -261,7 +266,8 @@ static int sprd_adi_write(struct sprd_adi *sadi, u32 reg_paddr, u32 val)
|
||||
}
|
||||
|
||||
out:
|
||||
hwspin_unlock_irqrestore(sadi->hwlock, &flags);
|
||||
if (sadi->hwlock)
|
||||
hwspin_unlock_irqrestore(sadi->hwlock, &flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -476,16 +482,26 @@ static int sprd_adi_probe(struct platform_device *pdev)
|
||||
sadi->slave_pbase = res->start + ADI_SLAVE_OFFSET;
|
||||
sadi->ctlr = ctlr;
|
||||
sadi->dev = &pdev->dev;
|
||||
ret = of_hwspin_lock_get_id_byname(np, "adi");
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "can not get the hardware spinlock\n");
|
||||
goto put_ctlr;
|
||||
}
|
||||
|
||||
sadi->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, ret);
|
||||
if (!sadi->hwlock) {
|
||||
ret = -ENXIO;
|
||||
goto put_ctlr;
|
||||
ret = of_hwspin_lock_get_id(np, 0);
|
||||
if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) {
|
||||
sadi->hwlock =
|
||||
devm_hwspin_lock_request_specific(&pdev->dev, ret);
|
||||
if (!sadi->hwlock) {
|
||||
ret = -ENXIO;
|
||||
goto put_ctlr;
|
||||
}
|
||||
} else {
|
||||
switch (ret) {
|
||||
case -ENOENT:
|
||||
dev_info(&pdev->dev, "no hardware spinlock supplied\n");
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev,
|
||||
"failed to find hwlock id, %d\n", ret);
|
||||
/* fall-through */
|
||||
case -EPROBE_DEFER:
|
||||
goto put_ctlr;
|
||||
}
|
||||
}
|
||||
|
||||
sprd_adi_hw_init(sadi);
|
||||
|
Loading…
Reference in New Issue
Block a user