Skip to content

Commit f8e8755

Browse files
committed
Merge tag 'qcom-drivers-for-5.10' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers
Qualcomm driver updates for v5.10 Replace the busy wait for free tcs slots in the RPMh driver with a sleeping wait and use memory barriers when writing the command registers. Add a bunch of SoC ids to the socinfo driver, fix an erro printin the apr driver and migrate llcc to devm_platform_ioremap_resource_byname(). * tag 'qcom-drivers-for-5.10' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: soc: qcom: llcc: use devm_platform_ioremap_resource_byname() soc: qcom: apr: Fixup the error displayed on lookup failure soc: qcom: socinfo: Add msm8992/4 and apq8094 SoC IDs soc: qcom: rpmh-rsc: Sleep waiting for tcs slots to be free soc: qcom-geni-se: Don't use relaxed writes when writing commands soc: qcom: socinfo: add SC7180 entry to soc_id array soc: qcom: socinfo: add soc id for IPQ6018 Link: https://lore.kernel.org/r/20200924040504.179708-1-bjorn.andersson@linaro.org Signed-off-by: Olof Johansson <olof@lixom.net>
2 parents c78c6e1 + 2899347 commit f8e8755

6 files changed

Lines changed: 67 additions & 70 deletions

File tree

drivers/soc/qcom/apr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static int of_apr_add_pd_lookups(struct device *dev)
328328

329329
pds = pdr_add_lookup(apr->pdr, service_name, service_path);
330330
if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) {
331-
dev_err(dev, "pdr add lookup failed: %d\n", ret);
331+
dev_err(dev, "pdr add lookup failed: %ld\n", PTR_ERR(pds));
332332
return PTR_ERR(pds);
333333
}
334334
}

drivers/soc/qcom/llcc-qcom.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,6 @@ static int qcom_llcc_remove(struct platform_device *pdev)
387387
static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
388388
const char *name)
389389
{
390-
struct resource *res;
391390
void __iomem *base;
392391
struct regmap_config llcc_regmap_config = {
393392
.reg_bits = 32,
@@ -396,11 +395,7 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
396395
.fast_io = true,
397396
};
398397

399-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
400-
if (!res)
401-
return ERR_PTR(-ENODEV);
402-
403-
base = devm_ioremap_resource(&pdev->dev, res);
398+
base = devm_platform_ioremap_resource_byname(pdev, name);
404399
if (IS_ERR(base))
405400
return ERR_CAST(base);
406401

drivers/soc/qcom/rpmh-internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define __RPM_INTERNAL_H__
99

1010
#include <linux/bitmap.h>
11+
#include <linux/wait.h>
1112
#include <soc/qcom/tcs.h>
1213

1314
#define TCS_TYPE_NR 4
@@ -106,6 +107,8 @@ struct rpmh_ctrlr {
106107
* @lock: Synchronize state of the controller. If RPMH's cache
107108
* lock will also be held, the order is: drv->lock then
108109
* cache_lock.
110+
* @tcs_wait: Wait queue used to wait for @tcs_in_use to free up a
111+
* slot
109112
* @client: Handle to the DRV's client.
110113
*/
111114
struct rsc_drv {
@@ -118,6 +121,7 @@ struct rsc_drv {
118121
struct tcs_group tcs[TCS_TYPE_NR];
119122
DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR);
120123
spinlock_t lock;
124+
wait_queue_head_t tcs_wait;
121125
struct rpmh_ctrlr client;
122126
};
123127

drivers/soc/qcom/rpmh-rsc.c

Lines changed: 54 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/platform_device.h>
2020
#include <linux/slab.h>
2121
#include <linux/spinlock.h>
22+
#include <linux/wait.h>
2223

2324
#include <soc/qcom/cmd-db.h>
2425
#include <soc/qcom/tcs.h>
@@ -453,6 +454,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
453454
if (!drv->tcs[ACTIVE_TCS].num_tcs)
454455
enable_tcs_irq(drv, i, false);
455456
spin_unlock(&drv->lock);
457+
wake_up(&drv->tcs_wait);
456458
if (req)
457459
rpmh_tx_done(req, err);
458460
}
@@ -571,73 +573,34 @@ static int find_free_tcs(struct tcs_group *tcs)
571573
}
572574

573575
/**
574-
* tcs_write() - Store messages into a TCS right now, or return -EBUSY.
576+
* claim_tcs_for_req() - Claim a tcs in the given tcs_group; only for active.
575577
* @drv: The controller.
578+
* @tcs: The tcs_group used for ACTIVE_ONLY transfers.
576579
* @msg: The data to be sent.
577580
*
578-
* Grabs a TCS for ACTIVE_ONLY transfers and writes the messages to it.
581+
* Claims a tcs in the given tcs_group while making sure that no existing cmd
582+
* is in flight that would conflict with the one in @msg.
579583
*
580-
* If there are no free TCSes for ACTIVE_ONLY transfers or if a command for
581-
* the same address is already transferring returns -EBUSY which means the
582-
* client should retry shortly.
584+
* Context: Must be called with the drv->lock held since that protects
585+
* tcs_in_use.
583586
*
584-
* Return: 0 on success, -EBUSY if client should retry, or an error.
585-
* Client should have interrupts enabled for a bit before retrying.
587+
* Return: The id of the claimed tcs or -EBUSY if a matching msg is in flight
588+
* or the tcs_group is full.
586589
*/
587-
static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
590+
static int claim_tcs_for_req(struct rsc_drv *drv, struct tcs_group *tcs,
591+
const struct tcs_request *msg)
588592
{
589-
struct tcs_group *tcs;
590-
int tcs_id;
591-
unsigned long flags;
592593
int ret;
593594

594-
tcs = get_tcs_for_msg(drv, msg);
595-
if (IS_ERR(tcs))
596-
return PTR_ERR(tcs);
597-
598-
spin_lock_irqsave(&drv->lock, flags);
599595
/*
600596
* The h/w does not like if we send a request to the same address,
601597
* when one is already in-flight or being processed.
602598
*/
603599
ret = check_for_req_inflight(drv, tcs, msg);
604600
if (ret)
605-
goto unlock;
606-
607-
ret = find_free_tcs(tcs);
608-
if (ret < 0)
609-
goto unlock;
610-
tcs_id = ret;
611-
612-
tcs->req[tcs_id - tcs->offset] = msg;
613-
set_bit(tcs_id, drv->tcs_in_use);
614-
if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
615-
/*
616-
* Clear previously programmed WAKE commands in selected
617-
* repurposed TCS to avoid triggering them. tcs->slots will be
618-
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
619-
*/
620-
write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
621-
write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0);
622-
enable_tcs_irq(drv, tcs_id, true);
623-
}
624-
spin_unlock_irqrestore(&drv->lock, flags);
625-
626-
/*
627-
* These two can be done after the lock is released because:
628-
* - We marked "tcs_in_use" under lock.
629-
* - Once "tcs_in_use" has been marked nobody else could be writing
630-
* to these registers until the interrupt goes off.
631-
* - The interrupt can't go off until we trigger w/ the last line
632-
* of __tcs_set_trigger() below.
633-
*/
634-
__tcs_buffer_write(drv, tcs_id, 0, msg);
635-
__tcs_set_trigger(drv, tcs_id, true);
601+
return ret;
636602

637-
return 0;
638-
unlock:
639-
spin_unlock_irqrestore(&drv->lock, flags);
640-
return ret;
603+
return find_free_tcs(tcs);
641604
}
642605

643606
/**
@@ -664,18 +627,47 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
664627
*/
665628
int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
666629
{
667-
int ret;
630+
struct tcs_group *tcs;
631+
int tcs_id;
632+
unsigned long flags;
668633

669-
do {
670-
ret = tcs_write(drv, msg);
671-
if (ret == -EBUSY) {
672-
pr_info_ratelimited("TCS Busy, retrying RPMH message send: addr=%#x\n",
673-
msg->cmds[0].addr);
674-
udelay(10);
675-
}
676-
} while (ret == -EBUSY);
634+
tcs = get_tcs_for_msg(drv, msg);
635+
if (IS_ERR(tcs))
636+
return PTR_ERR(tcs);
677637

678-
return ret;
638+
spin_lock_irqsave(&drv->lock, flags);
639+
640+
/* Wait forever for a free tcs. It better be there eventually! */
641+
wait_event_lock_irq(drv->tcs_wait,
642+
(tcs_id = claim_tcs_for_req(drv, tcs, msg)) >= 0,
643+
drv->lock);
644+
645+
tcs->req[tcs_id - tcs->offset] = msg;
646+
set_bit(tcs_id, drv->tcs_in_use);
647+
if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
648+
/*
649+
* Clear previously programmed WAKE commands in selected
650+
* repurposed TCS to avoid triggering them. tcs->slots will be
651+
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
652+
*/
653+
write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
654+
write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0);
655+
enable_tcs_irq(drv, tcs_id, true);
656+
}
657+
spin_unlock_irqrestore(&drv->lock, flags);
658+
659+
/*
660+
* These two can be done after the lock is released because:
661+
* - We marked "tcs_in_use" under lock.
662+
* - Once "tcs_in_use" has been marked nobody else could be writing
663+
* to these registers until the interrupt goes off.
664+
* - The interrupt can't go off until we trigger w/ the last line
665+
* of __tcs_set_trigger() below.
666+
*/
667+
__tcs_buffer_write(drv, tcs_id, 0, msg);
668+
__tcs_set_trigger(drv, tcs_id, true);
669+
670+
return 0;
679671
}
680672

681673
/**
@@ -983,6 +975,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
983975
return ret;
984976

985977
spin_lock_init(&drv->lock);
978+
init_waitqueue_head(&drv->tcs_wait);
986979
bitmap_zero(drv->tcs_in_use, MAX_TCS_NR);
987980

988981
irq = platform_get_irq(pdev, drv->id);

drivers/soc/qcom/socinfo.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ static const struct soc_id soc_id[] = {
194194
{ 186, "MSM8674" },
195195
{ 194, "MSM8974PRO" },
196196
{ 206, "MSM8916" },
197+
{ 207, "MSM8994" },
197198
{ 208, "APQ8074-AA" },
198199
{ 209, "APQ8074-AB" },
199200
{ 210, "APQ8074PRO" },
@@ -214,6 +215,8 @@ static const struct soc_id soc_id[] = {
214215
{ 248, "MSM8216" },
215216
{ 249, "MSM8116" },
216217
{ 250, "MSM8616" },
218+
{ 251, "MSM8992" },
219+
{ 253, "APQ8094" },
217220
{ 291, "APQ8096" },
218221
{ 305, "MSM8996SG" },
219222
{ 310, "MSM8996AU" },
@@ -223,6 +226,8 @@ static const struct soc_id soc_id[] = {
223226
{ 321, "SDM845" },
224227
{ 341, "SDA845" },
225228
{ 356, "SM8250" },
229+
{ 402, "IPQ6018" },
230+
{ 425, "SC7180" },
226231
};
227232

228233
static const char *socinfo_machine(struct device *dev, unsigned int id)

include/linux/qcom-geni-se.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ static inline void geni_se_setup_m_cmd(struct geni_se *se, u32 cmd, u32 params)
296296
u32 m_cmd;
297297

298298
m_cmd = (cmd << M_OPCODE_SHFT) | (params & M_PARAMS_MSK);
299-
writel_relaxed(m_cmd, se->base + SE_GENI_M_CMD0);
299+
writel(m_cmd, se->base + SE_GENI_M_CMD0);
300300
}
301301

302302
/**
@@ -316,7 +316,7 @@ static inline void geni_se_setup_s_cmd(struct geni_se *se, u32 cmd, u32 params)
316316
s_cmd &= ~(S_OPCODE_MSK | S_PARAMS_MSK);
317317
s_cmd |= (cmd << S_OPCODE_SHFT);
318318
s_cmd |= (params & S_PARAMS_MSK);
319-
writel_relaxed(s_cmd, se->base + SE_GENI_S_CMD0);
319+
writel(s_cmd, se->base + SE_GENI_S_CMD0);
320320
}
321321

322322
/**

0 commit comments

Comments
 (0)