Skip to content

Commit d2de70d

Browse files
committed
Merge remote-tracking branch tech/mproc/all into qcom-next
2 parents 67a672b + 2cf1030 commit d2de70d

2 files changed

Lines changed: 101 additions & 3 deletions

File tree

Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ properties:
2525
compatible:
2626
items:
2727
- enum:
28+
- qcom,glymur-aoss-qmp
29+
- qcom,kaanapali-aoss-qmp
2830
- qcom,milos-aoss-qmp
2931
- qcom,qcs615-aoss-qmp
3032
- qcom,qcs8300-aoss-qmp

drivers/soc/qcom/smp2p.c

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
* The driver uses the Linux GPIO and interrupt framework to expose a virtual
3737
* GPIO for each outbound entry and a virtual interrupt controller for each
3838
* inbound entry.
39+
*
40+
* Driver supports two versions:
41+
* V1 - For processor that start after local host
42+
* V2 - For processor that start in early boot sequence
3943
*/
4044

4145
#define SMP2P_MAX_ENTRY 16
@@ -48,10 +52,14 @@
4852
#define SMP2P_MAGIC 0x504d5324
4953
#define SMP2P_ALL_FEATURES SMP2P_FEATURE_SSR_ACK
5054

55+
#define ONE 1
56+
#define TWO 2
57+
#define MAX_VERSION TWO
58+
5159
/**
5260
* struct smp2p_smem_item - in memory communication structure
5361
* @magic: magic number
54-
* @version: version - must be 1
62+
* @version: version
5563
* @features: features flag - currently unused
5664
* @local_pid: processor id of sending end
5765
* @remote_pid: processor id of receiving end
@@ -180,14 +188,23 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
180188
static bool qcom_smp2p_check_ssr(struct qcom_smp2p *smp2p)
181189
{
182190
struct smp2p_smem_item *in = smp2p->in;
191+
struct smp2p_entry *entry;
183192
bool restart;
184193

185194
if (!smp2p->ssr_ack_enabled)
186195
return false;
187196

188197
restart = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT);
198+
restart = restart != smp2p->ssr_ack;
199+
if (restart && in->version > ONE) {
200+
list_for_each_entry(entry, &smp2p->inbound, node) {
201+
if (!entry->value)
202+
continue;
203+
entry->last_value = 0;
204+
}
205+
}
189206

190-
return restart != smp2p->ssr_ack;
207+
return restart;
191208
}
192209

193210
static void qcom_smp2p_do_ssr_ack(struct qcom_smp2p *smp2p)
@@ -222,6 +239,56 @@ static void qcom_smp2p_negotiate(struct qcom_smp2p *smp2p)
222239
}
223240
}
224241

242+
static int qcom_smp2p_in_version(struct qcom_smp2p *smp2p)
243+
{
244+
unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND];
245+
unsigned int pid = smp2p->remote_pid;
246+
struct smp2p_smem_item *in;
247+
size_t size;
248+
249+
in = qcom_smem_get(pid, smem_id, &size);
250+
if (IS_ERR(in))
251+
return 0;
252+
253+
return in->version;
254+
}
255+
256+
static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p)
257+
{
258+
unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND];
259+
unsigned int pid = smp2p->remote_pid;
260+
char buf[SMP2P_MAX_ENTRY_NAME];
261+
struct smp2p_smem_item *in;
262+
struct smp2p_entry *entry;
263+
size_t size;
264+
int i;
265+
266+
in = qcom_smem_get(pid, smem_id, &size);
267+
if (IS_ERR(in))
268+
return;
269+
270+
smp2p->in = in;
271+
272+
/* Check if version is initialized and set to v2.
273+
* Early enumeration of inbound entries is required only
274+
* for early boot processors which have smp2p version 2.
275+
*/
276+
if (in->version != TWO)
277+
return;
278+
279+
for (i = smp2p->valid_entries; i < in->valid_entries; i++) {
280+
list_for_each_entry(entry, &smp2p->inbound, node) {
281+
memcpy(buf, in->entries[i].name, sizeof(buf));
282+
if (!strcmp(buf, entry->name)) {
283+
entry->value = &in->entries[i].value;
284+
entry->last_value = readl(entry->value);
285+
break;
286+
}
287+
}
288+
}
289+
smp2p->valid_entries = i;
290+
}
291+
225292
static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p)
226293
{
227294
struct smp2p_smem_item *in;
@@ -368,12 +435,31 @@ static void smp2p_irq_print_chip(struct irq_data *irqd, struct seq_file *p)
368435
seq_printf(p, "%8s", dev_name(entry->smp2p->dev));
369436
}
370437

438+
static int smp2p_irq_get_irqchip_state(struct irq_data *irqd, enum irqchip_irq_state which,
439+
bool *state)
440+
{
441+
struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd);
442+
u32 val;
443+
444+
if (which != IRQCHIP_STATE_LINE_LEVEL)
445+
return -EINVAL;
446+
447+
if (!entry->value)
448+
return -ENODEV;
449+
450+
val = readl(entry->value);
451+
*state = !!(val & BIT(irqd_to_hwirq(irqd)));
452+
453+
return 0;
454+
}
455+
371456
static struct irq_chip smp2p_irq_chip = {
372457
.name = "smp2p",
373458
.irq_mask = smp2p_mask_irq,
374459
.irq_unmask = smp2p_unmask_irq,
375460
.irq_set_type = smp2p_set_irq_type,
376461
.irq_print_chip = smp2p_irq_print_chip,
462+
.irq_get_irqchip_state = smp2p_irq_get_irqchip_state,
377463
};
378464

379465
static int smp2p_irq_map(struct irq_domain *d,
@@ -464,6 +550,7 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p)
464550
struct smp2p_smem_item *out;
465551
unsigned smem_id = smp2p->smem_items[SMP2P_OUTBOUND];
466552
unsigned pid = smp2p->remote_pid;
553+
u8 in_version;
467554
int ret;
468555

469556
ret = qcom_smem_alloc(pid, smem_id, sizeof(*out));
@@ -485,12 +572,18 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p)
485572
out->valid_entries = 0;
486573
out->features = SMP2P_ALL_FEATURES;
487574

575+
in_version = qcom_smp2p_in_version(smp2p);
576+
if (in_version > MAX_VERSION) {
577+
dev_err(smp2p->dev, "Unsupported smp2p version\n");
578+
return -EINVAL;
579+
}
580+
488581
/*
489582
* Make sure the rest of the header is written before we validate the
490583
* item by writing a valid version number.
491584
*/
492585
wmb();
493-
out->version = 1;
586+
out->version = (in_version) ? in_version : 1;
494587

495588
qcom_smp2p_kick(smp2p);
496589

@@ -618,6 +711,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
618711
}
619712
}
620713

714+
/* Check inbound entries in the case of early boot processor */
715+
qcom_smp2p_start_in(smp2p);
716+
621717
/* Kick the outgoing edge after allocating entries */
622718
qcom_smp2p_kick(smp2p);
623719

0 commit comments

Comments
 (0)