diff options
Diffstat (limited to 'drivers/spmi')
-rw-r--r-- | drivers/spmi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/spmi/spmi-pmic-arb.c | 32 | ||||
-rw-r--r-- | drivers/spmi/spmi.c | 22 |
3 files changed, 43 insertions, 13 deletions
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig index 982580af1..0d3b70b3b 100644 --- a/drivers/spmi/Kconfig +++ b/drivers/spmi/Kconfig @@ -12,7 +12,7 @@ if SPMI config SPMI_MSM_PMIC_ARB tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)" - depends on IRQ_DOMAIN + select IRQ_DOMAIN depends on ARCH_QCOM || COMPILE_TEST depends on HAS_IOMEM default ARCH_QCOM diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index d7119db49..4a3cf9ba1 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -451,10 +451,10 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) } } -static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) +static void pmic_arb_chained_irq(struct irq_desc *desc) { - struct spmi_pmic_arb_dev *pa = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + struct spmi_pmic_arb_dev *pa = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); void __iomem *intr = pa->intr; int first = pa->min_apid >> 5; int last = pa->max_apid >> 5; @@ -575,6 +575,22 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type) return 0; } +static int qpnpint_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *state) +{ + u8 irq = d->hwirq >> 8; + u8 status = 0; + + if (which != IRQCHIP_STATE_LINE_LEVEL) + return -EINVAL; + + qpnpint_spmi_read(d, QPNPINT_REG_RT_STS, &status, 1); + *state = !!(status & BIT(irq)); + + return 0; +} + static struct irq_chip pmic_arb_irqchip = { .name = "pmic_arb", .irq_enable = qpnpint_irq_enable, @@ -582,6 +598,7 @@ static struct irq_chip pmic_arb_irqchip = { .irq_mask = qpnpint_irq_mask, .irq_unmask = qpnpint_irq_unmask, .irq_set_type = qpnpint_irq_set_type, + .irq_get_irqchip_state = qpnpint_get_irqchip_state, .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, }; @@ -928,8 +945,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) goto err_put_ctrl; } - irq_set_handler_data(pa->irq, pa); - irq_set_chained_handler(pa->irq, pmic_arb_chained_irq); + irq_set_chained_handler_and_data(pa->irq, pmic_arb_chained_irq, pa); err = spmi_controller_add(ctrl); if (err) @@ -938,8 +954,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) return 0; err_domain_remove: - irq_set_chained_handler(pa->irq, NULL); - irq_set_handler_data(pa->irq, NULL); + irq_set_chained_handler_and_data(pa->irq, NULL, NULL); irq_domain_remove(pa->domain); err_put_ctrl: spmi_controller_put(ctrl); @@ -951,8 +966,7 @@ static int spmi_pmic_arb_remove(struct platform_device *pdev) struct spmi_controller *ctrl = platform_get_drvdata(pdev); struct spmi_pmic_arb_dev *pa = spmi_controller_get_drvdata(ctrl); spmi_controller_remove(ctrl); - irq_set_chained_handler(pa->irq, NULL); - irq_set_handler_data(pa->irq, NULL); + irq_set_chained_handler_and_data(pa->irq, NULL, NULL); irq_domain_remove(pa->domain); spmi_controller_put(ctrl); return 0; diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 94938436a..11467e17b 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -22,6 +22,8 @@ #include <linux/pm_runtime.h> #include <dt-bindings/spmi/spmi.h> +#define CREATE_TRACE_POINTS +#include <trace/events/spmi.h> static DEFINE_IDA(ctrl_ida); @@ -96,28 +98,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove); static inline int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) { + int ret; + if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type) return -EINVAL; - return ctrl->cmd(ctrl, opcode, sid); + ret = ctrl->cmd(ctrl, opcode, sid); + trace_spmi_cmd(opcode, sid, ret); + return ret; } static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type) return -EINVAL; - return ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_begin(opcode, sid, addr); + ret = ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_end(opcode, sid, addr, ret, len, buf); + return ret; } static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, const u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type) return -EINVAL; - return ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_begin(opcode, sid, addr, len, buf); + ret = ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_end(opcode, sid, addr, ret); + return ret; } /** |