Loading Documentation/devicetree/bindings/interrupt-controller/qti,mpm.txt +41 −14 Original line number Diff line number Diff line Loading @@ -8,13 +8,16 @@ replays it to the subsystem interrupt controller after it becomes operational. Platform interrupt controller MPM is next in hierarchy, followed by others. This defines 2 interrupt controllers to monitor the interrupts when the system is asleep: One for to monitor the wakeup capable gic interrupts called wakegic. Properties: - compatible: Usage: required Value type: <string> Definition: Should contain "qcom,mpm" for mpm pin data and the respective target compatible flag. Definition: Should contain "qcom,mpm-gic" and the respective target compatible flag. - interrupts: Usage: required Loading Loading @@ -48,18 +51,42 @@ Properties: Example: mpm: mpm@7781b8 { compatible = "qcom,mpm"; wakegic: wake-gic@7781b8 { compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8953"; interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>; reg = <0x7781b8 0x1000>, <0x17911008 0x4>; /* MSM_APCS_GCC_BASE 4K */ reg = <0x601d4 0x1000>, <0xb011008 0x4>; /* MSM_APCS_GCC_BASE 4K */ reg-names = "vmpm", "ipc"; qcom,num-mpm-irqs = <96>; wakegic: wake-gic { compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8953"; interrupt-controller; #interrupt-cells = <3>; interrupt-parent = <&intc>; #interrupt-cells = <3>; }; One for to monitor the wakeup capable gpio interrupts called wakegpio. properties: - compatible: Usage: required Value type: <string> Definition: Should contain "qcom,mpm-gpio" and the respective target compatible flag. - interrupt-parent: Usage: required Value type: <phandle> Definition: Specifies the interrupt parent necessary for hierarchical domain to operate. - interrupt-controller: Usage: required Value type: <bool> Definition: Identifies the node as an interrupt controller. Example: wakegpio: wake-gpio { compatible = "qcom,mpm-gpio", "qcom,mpm-gpio-msm8953"; interrupt-controller; interrupt-parent = <&tlmm>; #interrupt-cells = <2>; }; drivers/irqchip/qcom/mpm-8953.c +57 −0 Original line number Diff line number Diff line Loading @@ -22,3 +22,60 @@ const struct mpm_pin mpm_msm8953_gic_chip_data[] = { {88, 222}, /* ee0_krait_hlos_spmi_periph_irq */ {-1}, }; const struct mpm_pin mpm_msm8953_gpio_chip_data[] = { {3, 38}, {4, 1}, {5, 5}, {6, 9}, {8, 37}, {9, 36}, {10, 13}, {11, 35}, {12, 17}, {13, 21}, {14, 54}, {15, 34}, {16, 31}, {17, 58}, {18, 28}, {19, 42}, {20, 25}, {21, 12}, {22, 43}, {23, 44}, {24, 45}, {25, 46}, {26, 48}, {27, 65}, {28, 93}, {29, 97}, {30, 63}, {31, 70}, {32, 71}, {33, 72}, {34, 81}, {35, 85}, {36, 90}, {50, 67}, {51, 73}, {52, 74}, {53, 62}, {59, 59}, {60, 60}, {61, 61}, {62, 86}, {63, 87}, {64, 91}, {65, 129}, {66, 130}, {67, 131}, {68, 132}, {69, 133}, {70, 137}, {71, 138}, {72, 139}, {73, 140}, {74, 141}, {-1}, }; drivers/irqchip/qcom/mpm.c +156 −22 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ struct msm_mpm_device_data { void __iomem *mpm_ipc_reg; irq_hw_number_t ipc_irq; struct irq_domain *gic_chip_domain; struct irq_domain *gpio_chip_domain; }; static int msm_pm_sleep_time_override; Loading Loading @@ -200,19 +201,19 @@ static inline void msm_mpm_set_type(struct irq_data *d, } } static void msm_mpm_gic_chip_mask(struct irq_data *d) static void msm_mpm_chip_mask(struct irq_data *d) { msm_mpm_enable_irq(d, false); irq_chip_mask_parent(d); } static void msm_mpm_gic_chip_unmask(struct irq_data *d) static void msm_mpm_chip_unmask(struct irq_data *d) { msm_mpm_enable_irq(d, true); irq_chip_unmask_parent(d); } static int msm_mpm_gic_chip_set_type(struct irq_data *d, unsigned int type) static int msm_mpm_chip_set_type(struct irq_data *d, unsigned int type) { msm_mpm_set_type(d, type); return irq_chip_set_type_parent(d, type); Loading @@ -221,15 +222,70 @@ static int msm_mpm_gic_chip_set_type(struct irq_data *d, unsigned int type) static struct irq_chip msm_mpm_gic_chip = { .name = "mpm-gic", .irq_eoi = irq_chip_eoi_parent, .irq_mask = msm_mpm_gic_chip_mask, .irq_disable = msm_mpm_gic_chip_mask, .irq_unmask = msm_mpm_gic_chip_unmask, .irq_mask = msm_mpm_chip_mask, .irq_disable = msm_mpm_chip_mask, .irq_unmask = msm_mpm_chip_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_type = msm_mpm_gic_chip_set_type, .irq_set_type = msm_mpm_chip_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif }; static struct irq_chip msm_mpm_gpio_chip = { .name = "mpm-gpio", .irq_mask = msm_mpm_chip_mask, .irq_disable = msm_mpm_chip_mask, .irq_unmask = msm_mpm_chip_unmask, .irq_set_type = msm_mpm_chip_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent, .irq_eoi = irq_chip_eoi_parent, .irq_set_affinity = irq_chip_set_affinity_parent, }; static int msm_mpm_gpio_chip_translate(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *hwirq, unsigned int *type) { if (is_of_node(fwspec->fwnode)) { if (fwspec->param_count != 2) return -EINVAL; *hwirq = fwspec->param[0]; *type = fwspec->param[1]; return 0; } return -EINVAL; } static int msm_mpm_gpio_chip_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *data) { int ret = 0; struct irq_fwspec *fwspec = data; struct irq_fwspec parent_fwspec; irq_hw_number_t hwirq; unsigned int type = IRQ_TYPE_NONE; ret = msm_mpm_gpio_chip_translate(domain, fwspec, &hwirq, &type); if (ret) return ret; irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &msm_mpm_gpio_chip, NULL); parent_fwspec = *fwspec; parent_fwspec.fwnode = domain->parent->fwnode; return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_fwspec); } static const struct irq_domain_ops msm_mpm_gpio_chip_domain_ops = { .translate = msm_mpm_gpio_chip_translate, .alloc = msm_mpm_gpio_chip_alloc, .free = irq_domain_free_irqs_common, }; static int msm_mpm_gic_chip_translate(struct irq_domain *d, Loading Loading @@ -296,16 +352,21 @@ static void msm_mpm_enter_sleep(struct cpumask *cpumask) irq_set_affinity(msm_mpm_dev_data.ipc_irq, cpumask); } static int msm_get_mpm_pin_map(unsigned int mpm_irq) static int msm_get_apps_irq(unsigned int mpm_irq) { struct mpm_pin *mpm_gic_pin_map = NULL; struct mpm_pin *mpm_pin = NULL; int apps_irq; mpm_gic_pin_map = (struct mpm_pin *) mpm_pin = (struct mpm_pin *) msm_mpm_dev_data.gic_chip_domain->host_data; apps_irq = msm_get_irq_pin(mpm_irq, mpm_gic_pin_map); apps_irq = msm_get_irq_pin(mpm_irq, mpm_pin); if (apps_irq >= 0) return apps_irq; mpm_pin = (struct mpm_pin *) msm_mpm_dev_data.gpio_chip_domain->host_data; return msm_get_irq_pin(mpm_irq, mpm_pin); } static void system_pm_exit_sleep(void) Loading Loading @@ -407,7 +468,7 @@ static irqreturn_t msm_mpm_irq(int irq, void *dev_id) trace_mpm_wakeup_pending_irqs(i, pending); for_each_set_bit(k, &pending, 32) { mpm_irq = 32 * i + k; apps_irq = msm_get_mpm_pin_map(mpm_irq); apps_irq = msm_get_apps_irq(mpm_irq); desc = apps_irq ? irq_to_desc(apps_irq) : NULL; Loading @@ -420,7 +481,7 @@ static irqreturn_t msm_mpm_irq(int irq, void *dev_id) return IRQ_HANDLED; } static int msm_mpm_probe(struct device_node *node) static int msm_mpm_init(struct device_node *node) { struct msm_mpm_device_data *dev = &msm_mpm_dev_data; int ret = 0; Loading Loading @@ -485,12 +546,22 @@ static const struct of_device_id mpm_gic_chip_data_table[] = { MODULE_DEVICE_TABLE(of, mpm_gic_chip_data_table); static const struct of_device_id mpm_gpio_chip_data_table[] = { { .compatible = "qcom,mpm-gpio-msm8953", .data = mpm_msm8953_gpio_chip_data, }, {} }; MODULE_DEVICE_TABLE(of, mpm_gpio_chip_data_table); static int __init mpm_gic_chip_init(struct device_node *node, struct device_node *parent) { struct irq_domain *parent_domain; const struct of_device_id *id; struct device_node *parent_node; int ret; if (!parent) { pr_err("%s(): no parent for mpm-gic\n", node->full_name); Loading @@ -512,7 +583,8 @@ static int __init mpm_gic_chip_init(struct device_node *node, id = of_match_node(mpm_gic_chip_data_table, node); if (!id) { pr_err("can not find mpm_gic_data_table of_node\n"); return -ENODEV; ret = -ENODEV; goto mpm_map_err; } msm_mpm_dev_data.gic_chip_domain = irq_domain_add_hierarchy( Loading @@ -520,13 +592,75 @@ static int __init mpm_gic_chip_init(struct device_node *node, &msm_mpm_gic_chip_domain_ops, (void *)id->data); if (!msm_mpm_dev_data.gic_chip_domain) { pr_err("gic domain add failed\n"); return -ENOMEM; ret = -ENOMEM; goto mpm_map_err; } msm_mpm_dev_data.gic_chip_domain->name = "qcom,mpm-gic"; parent_node = of_get_parent(node); return msm_mpm_probe(parent_node); ret = msm_mpm_init(node); if (!ret) return ret; irq_domain_remove(msm_mpm_dev_data.gic_chip_domain); mpm_map_err: kfree(mpm_to_irq); return ret; } IRQCHIP_DECLARE(mpm_gic_chip, "qcom,mpm-gic", mpm_gic_chip_init); static int mpm_gpio_chip_probe(struct platform_device *pdev) { struct device_node *node, *parent; struct irq_domain *parent_domain; const struct of_device_id *id; node = pdev->dev.of_node; parent = of_irq_find_parent(node); if (!parent) { pr_err("%s(): no parent for mpm-gpio\n", node->full_name); return -ENXIO; } parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("unable to obtain gpio parent domain defer probe\n"); return -EPROBE_DEFER; } id = of_match_node(mpm_gpio_chip_data_table, node); if (!id) { pr_err("match_table not found for mpm-gpio\n"); return -ENODEV; } msm_mpm_dev_data.gpio_chip_domain = irq_domain_add_hierarchy( parent_domain, 0, num_mpm_irqs, node, &msm_mpm_gpio_chip_domain_ops, (void *)id->data); if (!msm_mpm_dev_data.gpio_chip_domain) return -ENOMEM; msm_mpm_dev_data.gpio_chip_domain->name = "qcom,mpm-gpio"; return 0; } static const struct of_device_id msm_mpm_dt_match[] = { { .compatible = "qcom,mpm-gpio"}, { }, }; static struct platform_driver msm_mpm_driver = { .probe = mpm_gpio_chip_probe, .driver = { .name = "qcom,mpm-gpio", .of_match_table = msm_mpm_dt_match, }, }; static int __init msm_mpm_gpio_init(void) { return platform_driver_register(&msm_mpm_driver); } arch_initcall(msm_mpm_gpio_init) drivers/irqchip/qcom/mpm.h +1 −0 Original line number Diff line number Diff line Loading @@ -22,5 +22,6 @@ struct mpm_pin { }; extern const struct mpm_pin mpm_msm8953_gic_chip_data[]; extern const struct mpm_pin mpm_msm8953_gpio_chip_data[]; #endif /* __QCOM_MPM_H__ */ Loading
Documentation/devicetree/bindings/interrupt-controller/qti,mpm.txt +41 −14 Original line number Diff line number Diff line Loading @@ -8,13 +8,16 @@ replays it to the subsystem interrupt controller after it becomes operational. Platform interrupt controller MPM is next in hierarchy, followed by others. This defines 2 interrupt controllers to monitor the interrupts when the system is asleep: One for to monitor the wakeup capable gic interrupts called wakegic. Properties: - compatible: Usage: required Value type: <string> Definition: Should contain "qcom,mpm" for mpm pin data and the respective target compatible flag. Definition: Should contain "qcom,mpm-gic" and the respective target compatible flag. - interrupts: Usage: required Loading Loading @@ -48,18 +51,42 @@ Properties: Example: mpm: mpm@7781b8 { compatible = "qcom,mpm"; wakegic: wake-gic@7781b8 { compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8953"; interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>; reg = <0x7781b8 0x1000>, <0x17911008 0x4>; /* MSM_APCS_GCC_BASE 4K */ reg = <0x601d4 0x1000>, <0xb011008 0x4>; /* MSM_APCS_GCC_BASE 4K */ reg-names = "vmpm", "ipc"; qcom,num-mpm-irqs = <96>; wakegic: wake-gic { compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8953"; interrupt-controller; #interrupt-cells = <3>; interrupt-parent = <&intc>; #interrupt-cells = <3>; }; One for to monitor the wakeup capable gpio interrupts called wakegpio. properties: - compatible: Usage: required Value type: <string> Definition: Should contain "qcom,mpm-gpio" and the respective target compatible flag. - interrupt-parent: Usage: required Value type: <phandle> Definition: Specifies the interrupt parent necessary for hierarchical domain to operate. - interrupt-controller: Usage: required Value type: <bool> Definition: Identifies the node as an interrupt controller. Example: wakegpio: wake-gpio { compatible = "qcom,mpm-gpio", "qcom,mpm-gpio-msm8953"; interrupt-controller; interrupt-parent = <&tlmm>; #interrupt-cells = <2>; };
drivers/irqchip/qcom/mpm-8953.c +57 −0 Original line number Diff line number Diff line Loading @@ -22,3 +22,60 @@ const struct mpm_pin mpm_msm8953_gic_chip_data[] = { {88, 222}, /* ee0_krait_hlos_spmi_periph_irq */ {-1}, }; const struct mpm_pin mpm_msm8953_gpio_chip_data[] = { {3, 38}, {4, 1}, {5, 5}, {6, 9}, {8, 37}, {9, 36}, {10, 13}, {11, 35}, {12, 17}, {13, 21}, {14, 54}, {15, 34}, {16, 31}, {17, 58}, {18, 28}, {19, 42}, {20, 25}, {21, 12}, {22, 43}, {23, 44}, {24, 45}, {25, 46}, {26, 48}, {27, 65}, {28, 93}, {29, 97}, {30, 63}, {31, 70}, {32, 71}, {33, 72}, {34, 81}, {35, 85}, {36, 90}, {50, 67}, {51, 73}, {52, 74}, {53, 62}, {59, 59}, {60, 60}, {61, 61}, {62, 86}, {63, 87}, {64, 91}, {65, 129}, {66, 130}, {67, 131}, {68, 132}, {69, 133}, {70, 137}, {71, 138}, {72, 139}, {73, 140}, {74, 141}, {-1}, };
drivers/irqchip/qcom/mpm.c +156 −22 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ struct msm_mpm_device_data { void __iomem *mpm_ipc_reg; irq_hw_number_t ipc_irq; struct irq_domain *gic_chip_domain; struct irq_domain *gpio_chip_domain; }; static int msm_pm_sleep_time_override; Loading Loading @@ -200,19 +201,19 @@ static inline void msm_mpm_set_type(struct irq_data *d, } } static void msm_mpm_gic_chip_mask(struct irq_data *d) static void msm_mpm_chip_mask(struct irq_data *d) { msm_mpm_enable_irq(d, false); irq_chip_mask_parent(d); } static void msm_mpm_gic_chip_unmask(struct irq_data *d) static void msm_mpm_chip_unmask(struct irq_data *d) { msm_mpm_enable_irq(d, true); irq_chip_unmask_parent(d); } static int msm_mpm_gic_chip_set_type(struct irq_data *d, unsigned int type) static int msm_mpm_chip_set_type(struct irq_data *d, unsigned int type) { msm_mpm_set_type(d, type); return irq_chip_set_type_parent(d, type); Loading @@ -221,15 +222,70 @@ static int msm_mpm_gic_chip_set_type(struct irq_data *d, unsigned int type) static struct irq_chip msm_mpm_gic_chip = { .name = "mpm-gic", .irq_eoi = irq_chip_eoi_parent, .irq_mask = msm_mpm_gic_chip_mask, .irq_disable = msm_mpm_gic_chip_mask, .irq_unmask = msm_mpm_gic_chip_unmask, .irq_mask = msm_mpm_chip_mask, .irq_disable = msm_mpm_chip_mask, .irq_unmask = msm_mpm_chip_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_type = msm_mpm_gic_chip_set_type, .irq_set_type = msm_mpm_chip_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif }; static struct irq_chip msm_mpm_gpio_chip = { .name = "mpm-gpio", .irq_mask = msm_mpm_chip_mask, .irq_disable = msm_mpm_chip_mask, .irq_unmask = msm_mpm_chip_unmask, .irq_set_type = msm_mpm_chip_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent, .irq_eoi = irq_chip_eoi_parent, .irq_set_affinity = irq_chip_set_affinity_parent, }; static int msm_mpm_gpio_chip_translate(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *hwirq, unsigned int *type) { if (is_of_node(fwspec->fwnode)) { if (fwspec->param_count != 2) return -EINVAL; *hwirq = fwspec->param[0]; *type = fwspec->param[1]; return 0; } return -EINVAL; } static int msm_mpm_gpio_chip_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *data) { int ret = 0; struct irq_fwspec *fwspec = data; struct irq_fwspec parent_fwspec; irq_hw_number_t hwirq; unsigned int type = IRQ_TYPE_NONE; ret = msm_mpm_gpio_chip_translate(domain, fwspec, &hwirq, &type); if (ret) return ret; irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &msm_mpm_gpio_chip, NULL); parent_fwspec = *fwspec; parent_fwspec.fwnode = domain->parent->fwnode; return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_fwspec); } static const struct irq_domain_ops msm_mpm_gpio_chip_domain_ops = { .translate = msm_mpm_gpio_chip_translate, .alloc = msm_mpm_gpio_chip_alloc, .free = irq_domain_free_irqs_common, }; static int msm_mpm_gic_chip_translate(struct irq_domain *d, Loading Loading @@ -296,16 +352,21 @@ static void msm_mpm_enter_sleep(struct cpumask *cpumask) irq_set_affinity(msm_mpm_dev_data.ipc_irq, cpumask); } static int msm_get_mpm_pin_map(unsigned int mpm_irq) static int msm_get_apps_irq(unsigned int mpm_irq) { struct mpm_pin *mpm_gic_pin_map = NULL; struct mpm_pin *mpm_pin = NULL; int apps_irq; mpm_gic_pin_map = (struct mpm_pin *) mpm_pin = (struct mpm_pin *) msm_mpm_dev_data.gic_chip_domain->host_data; apps_irq = msm_get_irq_pin(mpm_irq, mpm_gic_pin_map); apps_irq = msm_get_irq_pin(mpm_irq, mpm_pin); if (apps_irq >= 0) return apps_irq; mpm_pin = (struct mpm_pin *) msm_mpm_dev_data.gpio_chip_domain->host_data; return msm_get_irq_pin(mpm_irq, mpm_pin); } static void system_pm_exit_sleep(void) Loading Loading @@ -407,7 +468,7 @@ static irqreturn_t msm_mpm_irq(int irq, void *dev_id) trace_mpm_wakeup_pending_irqs(i, pending); for_each_set_bit(k, &pending, 32) { mpm_irq = 32 * i + k; apps_irq = msm_get_mpm_pin_map(mpm_irq); apps_irq = msm_get_apps_irq(mpm_irq); desc = apps_irq ? irq_to_desc(apps_irq) : NULL; Loading @@ -420,7 +481,7 @@ static irqreturn_t msm_mpm_irq(int irq, void *dev_id) return IRQ_HANDLED; } static int msm_mpm_probe(struct device_node *node) static int msm_mpm_init(struct device_node *node) { struct msm_mpm_device_data *dev = &msm_mpm_dev_data; int ret = 0; Loading Loading @@ -485,12 +546,22 @@ static const struct of_device_id mpm_gic_chip_data_table[] = { MODULE_DEVICE_TABLE(of, mpm_gic_chip_data_table); static const struct of_device_id mpm_gpio_chip_data_table[] = { { .compatible = "qcom,mpm-gpio-msm8953", .data = mpm_msm8953_gpio_chip_data, }, {} }; MODULE_DEVICE_TABLE(of, mpm_gpio_chip_data_table); static int __init mpm_gic_chip_init(struct device_node *node, struct device_node *parent) { struct irq_domain *parent_domain; const struct of_device_id *id; struct device_node *parent_node; int ret; if (!parent) { pr_err("%s(): no parent for mpm-gic\n", node->full_name); Loading @@ -512,7 +583,8 @@ static int __init mpm_gic_chip_init(struct device_node *node, id = of_match_node(mpm_gic_chip_data_table, node); if (!id) { pr_err("can not find mpm_gic_data_table of_node\n"); return -ENODEV; ret = -ENODEV; goto mpm_map_err; } msm_mpm_dev_data.gic_chip_domain = irq_domain_add_hierarchy( Loading @@ -520,13 +592,75 @@ static int __init mpm_gic_chip_init(struct device_node *node, &msm_mpm_gic_chip_domain_ops, (void *)id->data); if (!msm_mpm_dev_data.gic_chip_domain) { pr_err("gic domain add failed\n"); return -ENOMEM; ret = -ENOMEM; goto mpm_map_err; } msm_mpm_dev_data.gic_chip_domain->name = "qcom,mpm-gic"; parent_node = of_get_parent(node); return msm_mpm_probe(parent_node); ret = msm_mpm_init(node); if (!ret) return ret; irq_domain_remove(msm_mpm_dev_data.gic_chip_domain); mpm_map_err: kfree(mpm_to_irq); return ret; } IRQCHIP_DECLARE(mpm_gic_chip, "qcom,mpm-gic", mpm_gic_chip_init); static int mpm_gpio_chip_probe(struct platform_device *pdev) { struct device_node *node, *parent; struct irq_domain *parent_domain; const struct of_device_id *id; node = pdev->dev.of_node; parent = of_irq_find_parent(node); if (!parent) { pr_err("%s(): no parent for mpm-gpio\n", node->full_name); return -ENXIO; } parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("unable to obtain gpio parent domain defer probe\n"); return -EPROBE_DEFER; } id = of_match_node(mpm_gpio_chip_data_table, node); if (!id) { pr_err("match_table not found for mpm-gpio\n"); return -ENODEV; } msm_mpm_dev_data.gpio_chip_domain = irq_domain_add_hierarchy( parent_domain, 0, num_mpm_irqs, node, &msm_mpm_gpio_chip_domain_ops, (void *)id->data); if (!msm_mpm_dev_data.gpio_chip_domain) return -ENOMEM; msm_mpm_dev_data.gpio_chip_domain->name = "qcom,mpm-gpio"; return 0; } static const struct of_device_id msm_mpm_dt_match[] = { { .compatible = "qcom,mpm-gpio"}, { }, }; static struct platform_driver msm_mpm_driver = { .probe = mpm_gpio_chip_probe, .driver = { .name = "qcom,mpm-gpio", .of_match_table = msm_mpm_dt_match, }, }; static int __init msm_mpm_gpio_init(void) { return platform_driver_register(&msm_mpm_driver); } arch_initcall(msm_mpm_gpio_init)
drivers/irqchip/qcom/mpm.h +1 −0 Original line number Diff line number Diff line Loading @@ -22,5 +22,6 @@ struct mpm_pin { }; extern const struct mpm_pin mpm_msm8953_gic_chip_data[]; extern const struct mpm_pin mpm_msm8953_gpio_chip_data[]; #endif /* __QCOM_MPM_H__ */