Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip: Convert all alloc/xlate users from of_node to fwnode

Since we now have a generic data structure to express an
interrupt specifier, convert all hierarchical irqchips that
are OF based to use a fwnode_handle as part of their alloc
and xlate (which becomes translate) callbacks.

As most of these drivers have dependencies (they exchange IRQ
specifiers), change them all in a single, massive patch...

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-and-tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: <linux-arm-kernel@lists.infradead.org>
Cc: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Cc: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Cc: Graeme Gregory <graeme@xora.org.uk>
Cc: Jake Oshins <jakeo@microsoft.com>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Link: http://lkml.kernel.org/r/1444737105-31573-6-git-send-email-marc.zyngier@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Marc Zyngier and committed by
Thomas Gleixner
f833f57f 11e4438e

+322 -251
+29 -26
arch/arm/mach-exynos/suspend.c
··· 177 177 #endif 178 178 }; 179 179 180 - static int exynos_pmu_domain_xlate(struct irq_domain *domain, 181 - struct device_node *controller, 182 - const u32 *intspec, 183 - unsigned int intsize, 184 - unsigned long *out_hwirq, 185 - unsigned int *out_type) 180 + static int exynos_pmu_domain_translate(struct irq_domain *d, 181 + struct irq_fwspec *fwspec, 182 + unsigned long *hwirq, 183 + unsigned int *type) 186 184 { 187 - if (irq_domain_get_of_node(domain) != controller) 188 - return -EINVAL; /* Shouldn't happen, really... */ 189 - if (intsize != 3) 190 - return -EINVAL; /* Not GIC compliant */ 191 - if (intspec[0] != 0) 192 - return -EINVAL; /* No PPI should point to this domain */ 185 + if (is_of_node(fwspec->fwnode)) { 186 + if (fwspec->param_count != 3) 187 + return -EINVAL; 193 188 194 - *out_hwirq = intspec[1]; 195 - *out_type = intspec[2]; 196 - return 0; 189 + /* No PPI should point to this domain */ 190 + if (fwspec->param[0] != 0) 191 + return -EINVAL; 192 + 193 + *hwirq = fwspec->param[1]; 194 + *type = fwspec->param[2]; 195 + return 0; 196 + } 197 + 198 + return -EINVAL; 197 199 } 198 200 199 201 static int exynos_pmu_domain_alloc(struct irq_domain *domain, 200 202 unsigned int virq, 201 203 unsigned int nr_irqs, void *data) 202 204 { 203 - struct of_phandle_args *args = data; 204 - struct of_phandle_args parent_args; 205 + struct irq_fwspec *fwspec = data; 206 + struct irq_fwspec parent_fwspec; 205 207 irq_hw_number_t hwirq; 206 208 int i; 207 209 208 - if (args->args_count != 3) 210 + if (fwspec->param_count != 3) 209 211 return -EINVAL; /* Not GIC compliant */ 210 - if (args->args[0] != 0) 212 + if (fwspec->param[0] != 0) 211 213 return -EINVAL; /* No PPI should point to this domain */ 212 214 213 - hwirq = args->args[1]; 215 + hwirq = fwspec->param[1]; 214 216 215 217 for (i = 0; i < nr_irqs; i++) 216 218 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, 217 219 &exynos_pmu_chip, NULL); 218 220 219 - parent_args = *args; 220 - parent_args.np = irq_domain_get_of_node(domain->parent); 221 - return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); 221 + parent_fwspec = *fwspec; 222 + parent_fwspec.fwnode = domain->parent->fwnode; 223 + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, 224 + &parent_fwspec); 222 225 } 223 226 224 227 static const struct irq_domain_ops exynos_pmu_domain_ops = { 225 - .xlate = exynos_pmu_domain_xlate, 226 - .alloc = exynos_pmu_domain_alloc, 227 - .free = irq_domain_free_irqs_common, 228 + .translate = exynos_pmu_domain_translate, 229 + .alloc = exynos_pmu_domain_alloc, 230 + .free = irq_domain_free_irqs_common, 228 231 }; 229 232 230 233 static int __init exynos_pmu_irq_init(struct device_node *node,
+29 -26
arch/arm/mach-imx/gpc.c
··· 181 181 #endif 182 182 }; 183 183 184 - static int imx_gpc_domain_xlate(struct irq_domain *domain, 185 - struct device_node *controller, 186 - const u32 *intspec, 187 - unsigned int intsize, 188 - unsigned long *out_hwirq, 189 - unsigned int *out_type) 184 + static int imx_gpc_domain_translate(struct irq_domain *d, 185 + struct irq_fwspec *fwspec, 186 + unsigned long *hwirq, 187 + unsigned int *type) 190 188 { 191 - if (irq_domain_get_of_node(domain) != controller) 192 - return -EINVAL; /* Shouldn't happen, really... */ 193 - if (intsize != 3) 194 - return -EINVAL; /* Not GIC compliant */ 195 - if (intspec[0] != 0) 196 - return -EINVAL; /* No PPI should point to this domain */ 189 + if (is_of_node(fwspec->fwnode)) { 190 + if (fwspec->param_count != 3) 191 + return -EINVAL; 197 192 198 - *out_hwirq = intspec[1]; 199 - *out_type = intspec[2]; 200 - return 0; 193 + /* No PPI should point to this domain */ 194 + if (fwspec->param[0] != 0) 195 + return -EINVAL; 196 + 197 + *hwirq = fwspec->param[1]; 198 + *type = fwspec->param[2]; 199 + return 0; 200 + } 201 + 202 + return -EINVAL; 201 203 } 202 204 203 205 static int imx_gpc_domain_alloc(struct irq_domain *domain, 204 206 unsigned int irq, 205 207 unsigned int nr_irqs, void *data) 206 208 { 207 - struct of_phandle_args *args = data; 208 - struct of_phandle_args parent_args; 209 + struct irq_fwspec *fwspec = data; 210 + struct irq_fwspec parent_fwspec; 209 211 irq_hw_number_t hwirq; 210 212 int i; 211 213 212 - if (args->args_count != 3) 214 + if (fwspec->param_count != 3) 213 215 return -EINVAL; /* Not GIC compliant */ 214 - if (args->args[0] != 0) 216 + if (fwspec->param[0] != 0) 215 217 return -EINVAL; /* No PPI should point to this domain */ 216 218 217 - hwirq = args->args[1]; 219 + hwirq = fwspec->param[1]; 218 220 if (hwirq >= GPC_MAX_IRQS) 219 221 return -EINVAL; /* Can't deal with this */ 220 222 ··· 224 222 irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i, 225 223 &imx_gpc_chip, NULL); 226 224 227 - parent_args = *args; 228 - parent_args.np = irq_domain_get_of_node(domain->parent); 229 - return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); 225 + parent_fwspec = *fwspec; 226 + parent_fwspec.fwnode = domain->parent->fwnode; 227 + return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, 228 + &parent_fwspec); 230 229 } 231 230 232 231 static const struct irq_domain_ops imx_gpc_domain_ops = { 233 - .xlate = imx_gpc_domain_xlate, 234 - .alloc = imx_gpc_domain_alloc, 235 - .free = irq_domain_free_irqs_common, 232 + .translate = imx_gpc_domain_translate, 233 + .alloc = imx_gpc_domain_alloc, 234 + .free = irq_domain_free_irqs_common, 236 235 }; 237 236 238 237 static int __init imx_gpc_init(struct device_node *node,
+29 -26
arch/arm/mach-omap2/omap-wakeupgen.c
··· 399 399 #endif 400 400 }; 401 401 402 - static int wakeupgen_domain_xlate(struct irq_domain *domain, 403 - struct device_node *controller, 404 - const u32 *intspec, 405 - unsigned int intsize, 406 - unsigned long *out_hwirq, 407 - unsigned int *out_type) 402 + static int wakeupgen_domain_translate(struct irq_domain *d, 403 + struct irq_fwspec *fwspec, 404 + unsigned long *hwirq, 405 + unsigned int *type) 408 406 { 409 - if (irq_domain_get_of_node(domain) != controller) 410 - return -EINVAL; /* Shouldn't happen, really... */ 411 - if (intsize != 3) 412 - return -EINVAL; /* Not GIC compliant */ 413 - if (intspec[0] != 0) 414 - return -EINVAL; /* No PPI should point to this domain */ 407 + if (is_of_node(fwspec->fwnode)) { 408 + if (fwspec->param_count != 3) 409 + return -EINVAL; 415 410 416 - *out_hwirq = intspec[1]; 417 - *out_type = intspec[2]; 418 - return 0; 411 + /* No PPI should point to this domain */ 412 + if (fwspec->param[0] != 0) 413 + return -EINVAL; 414 + 415 + *hwirq = fwspec->param[1]; 416 + *type = fwspec->param[2]; 417 + return 0; 418 + } 419 + 420 + return -EINVAL; 419 421 } 420 422 421 423 static int wakeupgen_domain_alloc(struct irq_domain *domain, 422 424 unsigned int virq, 423 425 unsigned int nr_irqs, void *data) 424 426 { 425 - struct of_phandle_args *args = data; 426 - struct of_phandle_args parent_args; 427 + struct irq_fwspec *fwspec = data; 428 + struct irq_fwspec parent_fwspec; 427 429 irq_hw_number_t hwirq; 428 430 int i; 429 431 430 - if (args->args_count != 3) 432 + if (fwspec->param_count != 3) 431 433 return -EINVAL; /* Not GIC compliant */ 432 - if (args->args[0] != 0) 434 + if (fwspec->param[0] != 0) 433 435 return -EINVAL; /* No PPI should point to this domain */ 434 436 435 - hwirq = args->args[1]; 437 + hwirq = fwspec->param[1]; 436 438 if (hwirq >= MAX_IRQS) 437 439 return -EINVAL; /* Can't deal with this */ 438 440 ··· 442 440 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, 443 441 &wakeupgen_chip, NULL); 444 442 445 - parent_args = *args; 446 - parent_args.np = irq_domain_get_of_node(domain->parent); 447 - return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); 443 + parent_fwspec = *fwspec; 444 + parent_fwspec.fwnode = domain->parent->fwnode; 445 + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, 446 + &parent_fwspec); 448 447 } 449 448 450 449 static const struct irq_domain_ops wakeupgen_domain_ops = { 451 - .xlate = wakeupgen_domain_xlate, 452 - .alloc = wakeupgen_domain_alloc, 453 - .free = irq_domain_free_irqs_common, 450 + .translate = wakeupgen_domain_translate, 451 + .alloc = wakeupgen_domain_alloc, 452 + .free = irq_domain_free_irqs_common, 454 453 }; 455 454 456 455 /*
+34 -28
drivers/irqchip/irq-crossbar.c
··· 78 78 static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, 79 79 irq_hw_number_t hwirq) 80 80 { 81 - struct of_phandle_args args; 81 + struct irq_fwspec fwspec; 82 82 int i; 83 83 int err; 84 + 85 + if (!irq_domain_get_of_node(domain->parent)) 86 + return -EINVAL; 84 87 85 88 raw_spin_lock(&cb->lock); 86 89 for (i = cb->int_max - 1; i >= 0; i--) { ··· 97 94 if (i < 0) 98 95 return -ENODEV; 99 96 100 - args.np = irq_domain_get_of_node(domain->parent); 101 - args.args_count = 3; 102 - args.args[0] = 0; /* SPI */ 103 - args.args[1] = i; 104 - args.args[2] = IRQ_TYPE_LEVEL_HIGH; 97 + fwspec.fwnode = domain->parent->fwnode; 98 + fwspec.param_count = 3; 99 + fwspec.param[0] = 0; /* SPI */ 100 + fwspec.param[1] = i; 101 + fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH; 105 102 106 - err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args); 103 + err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 107 104 if (err) 108 105 cb->irq_map[i] = IRQ_FREE; 109 106 else ··· 115 112 static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq, 116 113 unsigned int nr_irqs, void *data) 117 114 { 118 - struct of_phandle_args *args = data; 115 + struct irq_fwspec *fwspec = data; 119 116 irq_hw_number_t hwirq; 120 117 int i; 121 118 122 - if (args->args_count != 3) 119 + if (fwspec->param_count != 3) 123 120 return -EINVAL; /* Not GIC compliant */ 124 - if (args->args[0] != 0) 121 + if (fwspec->param[0] != 0) 125 122 return -EINVAL; /* No PPI should point to this domain */ 126 123 127 - hwirq = args->args[1]; 124 + hwirq = fwspec->param[1]; 128 125 if ((hwirq + nr_irqs) > cb->max_crossbar_sources) 129 126 return -EINVAL; /* Can't deal with this */ 130 127 ··· 169 166 raw_spin_unlock(&cb->lock); 170 167 } 171 168 172 - static int crossbar_domain_xlate(struct irq_domain *d, 173 - struct device_node *controller, 174 - const u32 *intspec, unsigned int intsize, 175 - unsigned long *out_hwirq, 176 - unsigned int *out_type) 169 + static int crossbar_domain_translate(struct irq_domain *d, 170 + struct irq_fwspec *fwspec, 171 + unsigned long *hwirq, 172 + unsigned int *type) 177 173 { 178 - if (irq_domain_get_of_node(d) != controller) 179 - return -EINVAL; /* Shouldn't happen, really... */ 180 - if (intsize != 3) 181 - return -EINVAL; /* Not GIC compliant */ 182 - if (intspec[0] != 0) 183 - return -EINVAL; /* No PPI should point to this domain */ 174 + if (is_of_node(fwspec->fwnode)) { 175 + if (fwspec->param_count != 3) 176 + return -EINVAL; 184 177 185 - *out_hwirq = intspec[1]; 186 - *out_type = intspec[2]; 187 - return 0; 178 + /* No PPI should point to this domain */ 179 + if (fwspec->param[0] != 0) 180 + return -EINVAL; 181 + 182 + *hwirq = fwspec->param[1]; 183 + *type = fwspec->param[2]; 184 + return 0; 185 + } 186 + 187 + return -EINVAL; 188 188 } 189 189 190 190 static const struct irq_domain_ops crossbar_domain_ops = { 191 - .alloc = crossbar_domain_alloc, 192 - .free = crossbar_domain_free, 193 - .xlate = crossbar_domain_xlate, 191 + .alloc = crossbar_domain_alloc, 192 + .free = crossbar_domain_free, 193 + .translate = crossbar_domain_translate, 194 194 }; 195 195 196 196 static int __init crossbar_of_init(struct device_node *node)
+11 -7
drivers/irqchip/irq-gic-v2m.c
··· 124 124 unsigned int virq, 125 125 irq_hw_number_t hwirq) 126 126 { 127 - struct of_phandle_args args; 127 + struct irq_fwspec fwspec; 128 128 struct irq_data *d; 129 129 int err; 130 130 131 - args.np = irq_domain_get_of_node(domain->parent); 132 - args.args_count = 3; 133 - args.args[0] = 0; 134 - args.args[1] = hwirq - 32; 135 - args.args[2] = IRQ_TYPE_EDGE_RISING; 131 + if (is_of_node(domain->parent->fwnode)) { 132 + fwspec.fwnode = domain->parent->fwnode; 133 + fwspec.param_count = 3; 134 + fwspec.param[0] = 0; 135 + fwspec.param[1] = hwirq - 32; 136 + fwspec.param[2] = IRQ_TYPE_EDGE_RISING; 137 + } else { 138 + return -EINVAL; 139 + } 136 140 137 - err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args); 141 + err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 138 142 if (err) 139 143 return err; 140 144
+11 -7
drivers/irqchip/irq-gic-v3-its.c
··· 1265 1265 unsigned int virq, 1266 1266 irq_hw_number_t hwirq) 1267 1267 { 1268 - struct of_phandle_args args; 1268 + struct irq_fwspec fwspec; 1269 1269 1270 - args.np = irq_domain_get_of_node(domain->parent); 1271 - args.args_count = 3; 1272 - args.args[0] = GIC_IRQ_TYPE_LPI; 1273 - args.args[1] = hwirq; 1274 - args.args[2] = IRQ_TYPE_EDGE_RISING; 1270 + if (irq_domain_get_of_node(domain->parent)) { 1271 + fwspec.fwnode = domain->parent->fwnode; 1272 + fwspec.param_count = 3; 1273 + fwspec.param[0] = GIC_IRQ_TYPE_LPI; 1274 + fwspec.param[1] = hwirq; 1275 + fwspec.param[2] = IRQ_TYPE_EDGE_RISING; 1276 + } else { 1277 + return -EINVAL; 1278 + } 1275 1279 1276 - return irq_domain_alloc_irqs_parent(domain, virq, 1, &args); 1280 + return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 1277 1281 } 1278 1282 1279 1283 static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+23 -26
drivers/irqchip/irq-gic-v3.c
··· 737 737 return 0; 738 738 } 739 739 740 - static int gic_irq_domain_xlate(struct irq_domain *d, 741 - struct device_node *controller, 742 - const u32 *intspec, unsigned int intsize, 743 - unsigned long *out_hwirq, unsigned int *out_type) 740 + static int gic_irq_domain_translate(struct irq_domain *d, 741 + struct irq_fwspec *fwspec, 742 + unsigned long *hwirq, 743 + unsigned int *type) 744 744 { 745 - if (irq_domain_get_of_node(d) != controller) 746 - return -EINVAL; 747 - if (intsize < 3) 748 - return -EINVAL; 745 + if (is_of_node(fwspec->fwnode)) { 746 + if (fwspec->param_count < 3) 747 + return -EINVAL; 749 748 750 - switch(intspec[0]) { 751 - case 0: /* SPI */ 752 - *out_hwirq = intspec[1] + 32; 753 - break; 754 - case 1: /* PPI */ 755 - *out_hwirq = intspec[1] + 16; 756 - break; 757 - case GIC_IRQ_TYPE_LPI: /* LPI */ 758 - *out_hwirq = intspec[1]; 759 - break; 760 - default: 761 - return -EINVAL; 749 + /* Get the interrupt number and add 16 to skip over SGIs */ 750 + *hwirq = fwspec->param[1] + 16; 751 + 752 + /* 753 + * For SPIs, we need to add 16 more to get the GIC irq 754 + * ID number 755 + */ 756 + if (!fwspec->param[0]) 757 + *hwirq += 16; 758 + 759 + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; 760 + return 0; 762 761 } 763 762 764 - *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 765 - return 0; 763 + return -EINVAL; 766 764 } 767 765 768 766 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, ··· 769 771 int i, ret; 770 772 irq_hw_number_t hwirq; 771 773 unsigned int type = IRQ_TYPE_NONE; 772 - struct of_phandle_args *irq_data = arg; 774 + struct irq_fwspec *fwspec = arg; 773 775 774 - ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, 775 - irq_data->args_count, &hwirq, &type); 776 + ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type); 776 777 if (ret) 777 778 return ret; 778 779 ··· 794 797 } 795 798 796 799 static const struct irq_domain_ops gic_irq_domain_ops = { 797 - .xlate = gic_irq_domain_xlate, 800 + .translate = gic_irq_domain_translate, 798 801 .alloc = gic_irq_domain_alloc, 799 802 .free = gic_irq_domain_free, 800 803 };
+29 -4
drivers/irqchip/irq-gic.c
··· 940 940 return ret; 941 941 } 942 942 943 + static int gic_irq_domain_translate(struct irq_domain *d, 944 + struct irq_fwspec *fwspec, 945 + unsigned long *hwirq, 946 + unsigned int *type) 947 + { 948 + if (is_of_node(fwspec->fwnode)) { 949 + if (fwspec->param_count < 3) 950 + return -EINVAL; 951 + 952 + /* Get the interrupt number and add 16 to skip over SGIs */ 953 + *hwirq = fwspec->param[1] + 16; 954 + 955 + /* 956 + * For SPIs, we need to add 16 more to get the GIC irq 957 + * ID number 958 + */ 959 + if (!fwspec->param[0]) 960 + *hwirq += 16; 961 + 962 + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; 963 + return 0; 964 + } 965 + 966 + return -EINVAL; 967 + } 968 + 943 969 #ifdef CONFIG_SMP 944 970 static int gic_secondary_init(struct notifier_block *nfb, unsigned long action, 945 971 void *hcpu) ··· 991 965 int i, ret; 992 966 irq_hw_number_t hwirq; 993 967 unsigned int type = IRQ_TYPE_NONE; 994 - struct of_phandle_args *irq_data = arg; 968 + struct irq_fwspec *fwspec = arg; 995 969 996 - ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, 997 - irq_data->args_count, &hwirq, &type); 970 + ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type); 998 971 if (ret) 999 972 return ret; 1000 973 ··· 1004 979 } 1005 980 1006 981 static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { 1007 - .xlate = gic_irq_domain_xlate, 982 + .translate = gic_irq_domain_translate, 1008 983 .alloc = gic_irq_domain_alloc, 1009 984 .free = irq_domain_free_irqs_top, 1010 985 };
+29 -35
drivers/irqchip/irq-imx-gpcv2.c
··· 150 150 #endif 151 151 }; 152 152 153 - static int imx_gpcv2_domain_xlate(struct irq_domain *domain, 154 - struct device_node *controller, 155 - const u32 *intspec, 156 - unsigned int intsize, 157 - unsigned long *out_hwirq, 158 - unsigned int *out_type) 153 + static int imx_gpcv2_domain_translate(struct irq_domain *d, 154 + struct irq_fwspec *fwspec, 155 + unsigned long *hwirq, 156 + unsigned int *type) 159 157 { 160 - /* Shouldn't happen, really... */ 161 - if (irq_domain_get_of_node(domain) != controller) 162 - return -EINVAL; 158 + if (is_of_node(fwspec->fwnode)) { 159 + if (fwspec->param_count != 3) 160 + return -EINVAL; 163 161 164 - /* Not GIC compliant */ 165 - if (intsize != 3) 166 - return -EINVAL; 162 + /* No PPI should point to this domain */ 163 + if (fwspec->param[0] != 0) 164 + return -EINVAL; 167 165 168 - /* No PPI should point to this domain */ 169 - if (intspec[0] != 0) 170 - return -EINVAL; 166 + *hwirq = fwspec->param[1]; 167 + *type = fwspec->param[2]; 168 + return 0; 169 + } 171 170 172 - *out_hwirq = intspec[1]; 173 - *out_type = intspec[2]; 174 - return 0; 171 + return -EINVAL; 175 172 } 176 173 177 174 static int imx_gpcv2_domain_alloc(struct irq_domain *domain, 178 175 unsigned int irq, unsigned int nr_irqs, 179 176 void *data) 180 177 { 181 - struct of_phandle_args *args = data; 182 - struct of_phandle_args parent_args; 178 + struct irq_fwspec *fwspec = data; 179 + struct irq_fwspec parent_fwspec; 183 180 irq_hw_number_t hwirq; 181 + unsigned int type; 182 + int err; 184 183 int i; 185 184 186 - /* Not GIC compliant */ 187 - if (args->args_count != 3) 188 - return -EINVAL; 185 + err = imx_gpcv2_domain_translate(domain, fwspec, &hwirq, &type); 186 + if (err) 187 + return err; 189 188 190 - /* No PPI should point to this domain */ 191 - if (args->args[0] != 0) 192 - return -EINVAL; 193 - 194 - /* Can't deal with this */ 195 - hwirq = args->args[1]; 196 189 if (hwirq >= GPC_MAX_IRQS) 197 190 return -EINVAL; 198 191 ··· 194 201 &gpcv2_irqchip_data_chip, domain->host_data); 195 202 } 196 203 197 - parent_args = *args; 198 - parent_args.np = irq_domain_get_of_node(domain->parent); 199 - return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); 204 + parent_fwspec = *fwspec; 205 + parent_fwspec.fwnode = domain->parent->fwnode; 206 + return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, 207 + &parent_fwspec); 200 208 } 201 209 202 210 static struct irq_domain_ops gpcv2_irqchip_data_domain_ops = { 203 - .xlate = imx_gpcv2_domain_xlate, 204 - .alloc = imx_gpcv2_domain_alloc, 205 - .free = irq_domain_free_irqs_common, 211 + .translate = imx_gpcv2_domain_translate, 212 + .alloc = imx_gpcv2_domain_alloc, 213 + .free = irq_domain_free_irqs_common, 206 214 }; 207 215 208 216 static int __init imx_gpcv2_irqchip_init(struct device_node *node,
+26 -23
drivers/irqchip/irq-mtk-sysirq.c
··· 67 67 .irq_set_affinity = irq_chip_set_affinity_parent, 68 68 }; 69 69 70 - static int mtk_sysirq_domain_xlate(struct irq_domain *d, 71 - struct device_node *controller, 72 - const u32 *intspec, unsigned int intsize, 73 - unsigned long *out_hwirq, 74 - unsigned int *out_type) 70 + static int mtk_sysirq_domain_translate(struct irq_domain *d, 71 + struct irq_fwspec *fwspec, 72 + unsigned long *hwirq, 73 + unsigned int *type) 75 74 { 76 - if (intsize != 3) 77 - return -EINVAL; 75 + if (is_of_node(fwspec->fwnode)) { 76 + if (fwspec->param_count != 3) 77 + return -EINVAL; 78 78 79 - /* sysirq doesn't support PPI */ 80 - if (intspec[0]) 81 - return -EINVAL; 79 + /* No PPI should point to this domain */ 80 + if (fwspec->param[0] != 0) 81 + return -EINVAL; 82 82 83 - *out_hwirq = intspec[1]; 84 - *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 85 - return 0; 83 + *hwirq = fwspec->param[1]; 84 + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; 85 + return 0; 86 + } 87 + 88 + return -EINVAL; 86 89 } 87 90 88 91 static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, ··· 93 90 { 94 91 int i; 95 92 irq_hw_number_t hwirq; 96 - struct of_phandle_args *irq_data = arg; 97 - struct of_phandle_args gic_data = *irq_data; 93 + struct irq_fwspec *fwspec = arg; 94 + struct irq_fwspec gic_fwspec = *fwspec; 98 95 99 - if (irq_data->args_count != 3) 96 + if (fwspec->param_count != 3) 100 97 return -EINVAL; 101 98 102 99 /* sysirq doesn't support PPI */ 103 - if (irq_data->args[0]) 100 + if (fwspec->param[0]) 104 101 return -EINVAL; 105 102 106 - hwirq = irq_data->args[1]; 103 + hwirq = fwspec->param[1]; 107 104 for (i = 0; i < nr_irqs; i++) 108 105 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, 109 106 &mtk_sysirq_chip, 110 107 domain->host_data); 111 108 112 - gic_data.np = irq_domain_get_of_node(domain->parent); 113 - return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); 109 + gic_fwspec.fwnode = domain->parent->fwnode; 110 + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_fwspec); 114 111 } 115 112 116 113 static const struct irq_domain_ops sysirq_domain_ops = { 117 - .xlate = mtk_sysirq_domain_xlate, 118 - .alloc = mtk_sysirq_domain_alloc, 119 - .free = irq_domain_free_irqs_common, 114 + .translate = mtk_sysirq_domain_translate, 115 + .alloc = mtk_sysirq_domain_alloc, 116 + .free = irq_domain_free_irqs_common, 120 117 }; 121 118 122 119 static int __init mtk_sysirq_of_init(struct device_node *node,
+14 -4
drivers/irqchip/irq-nvic.c
··· 48 48 handle_IRQ(irq, regs); 49 49 } 50 50 51 + static int nvic_irq_domain_translate(struct irq_domain *d, 52 + struct irq_fwspec *fwspec, 53 + unsigned long *hwirq, unsigned int *type) 54 + { 55 + if (WARN_ON(fwspec->param_count < 1)) 56 + return -EINVAL; 57 + *hwirq = fwspec->param[0]; 58 + *type = IRQ_TYPE_NONE; 59 + return 0; 60 + } 61 + 51 62 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, 52 63 unsigned int nr_irqs, void *arg) 53 64 { 54 65 int i, ret; 55 66 irq_hw_number_t hwirq; 56 67 unsigned int type = IRQ_TYPE_NONE; 57 - struct of_phandle_args *irq_data = arg; 68 + struct irq_fwspec *fwspec = arg; 58 69 59 - ret = irq_domain_xlate_onecell(domain, irq_data->np, irq_data->args, 60 - irq_data->args_count, &hwirq, &type); 70 + ret = nvic_irq_domain_translate(domain, fwspec, &hwirq, &type); 61 71 if (ret) 62 72 return ret; 63 73 ··· 78 68 } 79 69 80 70 static const struct irq_domain_ops nvic_irq_domain_ops = { 81 - .xlate = irq_domain_xlate_onecell, 71 + .translate = nvic_irq_domain_translate, 82 72 .alloc = nvic_irq_domain_alloc, 83 73 .free = irq_domain_free_irqs_top, 84 74 };
+29 -26
drivers/irqchip/irq-tegra.c
··· 220 220 #endif 221 221 }; 222 222 223 - static int tegra_ictlr_domain_xlate(struct irq_domain *domain, 224 - struct device_node *controller, 225 - const u32 *intspec, 226 - unsigned int intsize, 227 - unsigned long *out_hwirq, 228 - unsigned int *out_type) 223 + static int tegra_ictlr_domain_translate(struct irq_domain *d, 224 + struct irq_fwspec *fwspec, 225 + unsigned long *hwirq, 226 + unsigned int *type) 229 227 { 230 - if (irq_domain_get_of_node(domain) != controller) 231 - return -EINVAL; /* Shouldn't happen, really... */ 232 - if (intsize != 3) 233 - return -EINVAL; /* Not GIC compliant */ 234 - if (intspec[0] != GIC_SPI) 235 - return -EINVAL; /* No PPI should point to this domain */ 228 + if (is_of_node(fwspec->fwnode)) { 229 + if (fwspec->param_count != 3) 230 + return -EINVAL; 236 231 237 - *out_hwirq = intspec[1]; 238 - *out_type = intspec[2]; 239 - return 0; 232 + /* No PPI should point to this domain */ 233 + if (fwspec->param[0] != 0) 234 + return -EINVAL; 235 + 236 + *hwirq = fwspec->param[1]; 237 + *type = fwspec->param[2]; 238 + return 0; 239 + } 240 + 241 + return -EINVAL; 240 242 } 241 243 242 244 static int tegra_ictlr_domain_alloc(struct irq_domain *domain, 243 245 unsigned int virq, 244 246 unsigned int nr_irqs, void *data) 245 247 { 246 - struct of_phandle_args *args = data; 247 - struct of_phandle_args parent_args; 248 + struct irq_fwspec *fwspec = data; 249 + struct irq_fwspec parent_fwspec; 248 250 struct tegra_ictlr_info *info = domain->host_data; 249 251 irq_hw_number_t hwirq; 250 252 unsigned int i; 251 253 252 - if (args->args_count != 3) 254 + if (fwspec->param_count != 3) 253 255 return -EINVAL; /* Not GIC compliant */ 254 - if (args->args[0] != GIC_SPI) 256 + if (fwspec->param[0] != GIC_SPI) 255 257 return -EINVAL; /* No PPI should point to this domain */ 256 258 257 - hwirq = args->args[1]; 259 + hwirq = fwspec->param[1]; 258 260 if (hwirq >= (num_ictlrs * 32)) 259 261 return -EINVAL; 260 262 ··· 268 266 info->base[ictlr]); 269 267 } 270 268 271 - parent_args = *args; 272 - parent_args.np = irq_domain_get_of_node(domain->parent); 273 - return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); 269 + parent_fwspec = *fwspec; 270 + parent_fwspec.fwnode = domain->parent->fwnode; 271 + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, 272 + &parent_fwspec); 274 273 } 275 274 276 275 static void tegra_ictlr_domain_free(struct irq_domain *domain, ··· 287 284 } 288 285 289 286 static const struct irq_domain_ops tegra_ictlr_domain_ops = { 290 - .xlate = tegra_ictlr_domain_xlate, 291 - .alloc = tegra_ictlr_domain_alloc, 292 - .free = tegra_ictlr_domain_free, 287 + .translate = tegra_ictlr_domain_translate, 288 + .alloc = tegra_ictlr_domain_alloc, 289 + .free = tegra_ictlr_domain_free, 293 290 }; 294 291 295 292 static int __init tegra_ictlr_init(struct device_node *node,
+29 -13
drivers/irqchip/irq-vf610-mscm-ir.c
··· 130 130 { 131 131 int i; 132 132 irq_hw_number_t hwirq; 133 - struct of_phandle_args *irq_data = arg; 134 - struct of_phandle_args gic_data; 133 + struct irq_fwspec *fwspec = arg; 134 + struct irq_fwspec parent_fwspec; 135 135 136 - if (irq_data->args_count != 2) 136 + if (!irq_domain_get_of_node(domain->parent)) 137 137 return -EINVAL; 138 138 139 - hwirq = irq_data->args[0]; 139 + if (fwspec->param_count != 2) 140 + return -EINVAL; 141 + 142 + hwirq = fwspec->param[0]; 140 143 for (i = 0; i < nr_irqs; i++) 141 144 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, 142 145 &vf610_mscm_ir_irq_chip, 143 146 domain->host_data); 144 147 145 - gic_data.np = irq_domain_get_of_node(domain->parent); 148 + parent_fwspec.fwnode = domain->parent->fwnode; 146 149 147 150 if (mscm_ir_data->is_nvic) { 148 - gic_data.args_count = 1; 149 - gic_data.args[0] = irq_data->args[0]; 151 + parent_fwspec.param_count = 1; 152 + parent_fwspec.param[0] = fwspec->param[0]; 150 153 } else { 151 - gic_data.args_count = 3; 152 - gic_data.args[0] = GIC_SPI; 153 - gic_data.args[1] = irq_data->args[0]; 154 - gic_data.args[2] = irq_data->args[1]; 154 + parent_fwspec.param_count = 3; 155 + parent_fwspec.param[0] = GIC_SPI; 156 + parent_fwspec.param[1] = fwspec->param[0]; 157 + parent_fwspec.param[2] = fwspec->param[1]; 155 158 } 156 159 157 - return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); 160 + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, 161 + &parent_fwspec); 162 + } 163 + 164 + static int vf610_mscm_ir_domain_translate(struct irq_domain *d, 165 + struct irq_fwspec *fwspec, 166 + unsigned long *hwirq, 167 + unsigned int *type) 168 + { 169 + if (WARN_ON(fwspec->param_count < 2)) 170 + return -EINVAL; 171 + *hwirq = fwspec->param[0]; 172 + *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; 173 + return 0; 158 174 } 159 175 160 176 static const struct irq_domain_ops mscm_irq_domain_ops = { 161 - .xlate = irq_domain_xlate_twocell, 177 + .translate = vf610_mscm_ir_domain_translate, 162 178 .alloc = vf610_mscm_ir_domain_alloc, 163 179 .free = irq_domain_free_irqs_common, 164 180 };