diff options
Diffstat (limited to 'drivers/soc/qcom/smp2p.c')
-rw-r--r-- | drivers/soc/qcom/smp2p.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 914b2246148f..a3e88ced328a 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/pm_wakeirq.h> #include <linux/regmap.h> +#include <linux/seq_file.h> #include <linux/soc/qcom/smem.h> #include <linux/soc/qcom/smem_state.h> #include <linux/spinlock.h> @@ -58,8 +59,8 @@ * @valid_entries: number of allocated entries * @flags: * @entries: individual communication entries - * @name: name of the entry - * @value: content of the entry + * @entries.name: name of the entry + * @entries.value: content of the entry */ struct smp2p_smem_item { u32 magic; @@ -160,6 +161,9 @@ struct qcom_smp2p { struct list_head outbound; }; +#define CREATE_TRACE_POINTS +#include "trace-smp2p.h" + static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) { /* Make sure any updated data is written before the kick */ @@ -191,6 +195,7 @@ static void qcom_smp2p_do_ssr_ack(struct qcom_smp2p *smp2p) struct smp2p_smem_item *out = smp2p->out; u32 val; + trace_smp2p_ssr_ack(smp2p->dev); smp2p->ssr_ack = !smp2p->ssr_ack; val = out->flags & ~BIT(SMP2P_FLAGS_RESTART_ACK_BIT); @@ -213,6 +218,7 @@ static void qcom_smp2p_negotiate(struct qcom_smp2p *smp2p) smp2p->ssr_ack_enabled = true; smp2p->negotiation_done = true; + trace_smp2p_negotiate(smp2p->dev, out->features); } } @@ -251,6 +257,8 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) status = val ^ entry->last_value; entry->last_value = val; + trace_smp2p_notify_in(entry, status, val); + /* No changes of this entry? */ if (!status) continue; @@ -275,6 +283,8 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) * * Handle notifications from the remote side to handle newly allocated entries * or any changes to the state bits of existing entries. + * + * Return: %IRQ_HANDLED */ static irqreturn_t qcom_smp2p_intr(int irq, void *data) { @@ -351,11 +361,19 @@ static int smp2p_set_irq_type(struct irq_data *irqd, unsigned int type) return 0; } +static void smp2p_irq_print_chip(struct irq_data *irqd, struct seq_file *p) +{ + struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd); + + seq_printf(p, "%8s", dev_name(entry->smp2p->dev)); +} + static struct irq_chip smp2p_irq_chip = { .name = "smp2p", .irq_mask = smp2p_mask_irq, .irq_unmask = smp2p_unmask_irq, .irq_set_type = smp2p_set_irq_type, + .irq_print_chip = smp2p_irq_print_chip, }; static int smp2p_irq_map(struct irq_domain *d, @@ -404,6 +422,8 @@ static int smp2p_update_bits(void *data, u32 mask, u32 value) writel(val, entry->value); spin_unlock_irqrestore(&entry->lock, flags); + trace_smp2p_update_bits(entry, orig, val); + if (val != orig) qcom_smp2p_kick(entry->smp2p); @@ -447,12 +467,9 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p) int ret; ret = qcom_smem_alloc(pid, smem_id, sizeof(*out)); - if (ret < 0 && ret != -EEXIST) { - if (ret != -EPROBE_DEFER) - dev_err(smp2p->dev, - "unable to allocate local smp2p item\n"); - return ret; - } + if (ret < 0 && ret != -EEXIST) + return dev_err_probe(smp2p->dev, ret, + "unable to allocate local smp2p item\n"); out = qcom_smem_get(pid, smem_id, NULL); if (IS_ERR(out)) { @@ -519,7 +536,6 @@ static int smp2p_parse_ipc(struct qcom_smp2p *smp2p) static int qcom_smp2p_probe(struct platform_device *pdev) { struct smp2p_entry *entry; - struct device_node *node; struct qcom_smp2p *smp2p; const char *key; int irq; @@ -573,11 +589,10 @@ static int qcom_smp2p_probe(struct platform_device *pdev) if (ret < 0) goto release_mbox; - for_each_available_child_of_node(pdev->dev.of_node, node) { + for_each_available_child_of_node_scoped(pdev->dev.of_node, node) { entry = devm_kzalloc(&pdev->dev, sizeof(*entry), GFP_KERNEL); if (!entry) { ret = -ENOMEM; - of_node_put(node); goto unwind_interfaces; } @@ -585,25 +600,19 @@ static int qcom_smp2p_probe(struct platform_device *pdev) spin_lock_init(&entry->lock); ret = of_property_read_string(node, "qcom,entry-name", &entry->name); - if (ret < 0) { - of_node_put(node); + if (ret < 0) goto unwind_interfaces; - } if (of_property_read_bool(node, "interrupt-controller")) { ret = qcom_smp2p_inbound_entry(smp2p, entry, node); - if (ret < 0) { - of_node_put(node); + if (ret < 0) goto unwind_interfaces; - } list_add(&entry->node, &smp2p->inbound); } else { ret = qcom_smp2p_outbound_entry(smp2p, entry, node); - if (ret < 0) { - of_node_put(node); + if (ret < 0) goto unwind_interfaces; - } list_add(&entry->node, &smp2p->outbound); } @@ -615,7 +624,7 @@ static int qcom_smp2p_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qcom_smp2p_intr, IRQF_ONESHOT, - "smp2p", (void *)smp2p); + NULL, (void *)smp2p); if (ret) { dev_err(&pdev->dev, "failed to request interrupt\n"); goto unwind_interfaces; @@ -686,7 +695,7 @@ MODULE_DEVICE_TABLE(of, qcom_smp2p_of_match); static struct platform_driver qcom_smp2p_driver = { .probe = qcom_smp2p_probe, - .remove_new = qcom_smp2p_remove, + .remove = qcom_smp2p_remove, .driver = { .name = "qcom_smp2p", .of_match_table = qcom_smp2p_of_match, |