aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/qcom-apq8060-dragonboard.dts21
-rw-r--r--arch/arm/boot/dts/qcom-apq8064.dtsi46
-rw-r--r--arch/arm/boot/dts/qcom-mdm9615.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom-msm8660.dtsi47
-rw-r--r--drivers/mfd/Kconfig2
-rw-r--r--drivers/mfd/qcom-pm8xxx.c75
-rw-r--r--drivers/pinctrl/qcom/Kconfig1
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c157
-rw-r--r--include/linux/irq.h1
-rw-r--r--include/linux/irqdomain.h5
-rw-r--r--kernel/irq/chip.c11
-rw-r--r--kernel/irq/irqdomain.c45
12 files changed, 236 insertions, 184 deletions
diff --git a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
index 497bb065eb9d..4e6c50d45cb2 100644
--- a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
@@ -93,9 +93,8 @@
93 vdd-supply = <&pm8058_l14>; // 2.85V 93 vdd-supply = <&pm8058_l14>; // 2.85V
94 aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>; 94 aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>;
95 capella,aset-resistance-ohms = <100000>; 95 capella,aset-resistance-ohms = <100000>;
96 /* GPIO34 has interrupt 225 on the PM8058 */
97 /* Trig on both edges - getting close or far away */ 96 /* Trig on both edges - getting close or far away */
98 interrupts-extended = <&pm8058 225 IRQ_TYPE_EDGE_BOTH>; 97 interrupts-extended = <&pm8058_gpio 34 IRQ_TYPE_EDGE_BOTH>;
99 /* MPP05 analog input to the XOADC */ 98 /* MPP05 analog input to the XOADC */
100 io-channels = <&xoadc 0x00 0x05>; 99 io-channels = <&xoadc 0x00 0x05>;
101 io-channel-names = "aout"; 100 io-channel-names = "aout";
@@ -515,9 +514,8 @@
515 ak8975@c { 514 ak8975@c {
516 compatible = "asahi-kasei,ak8975"; 515 compatible = "asahi-kasei,ak8975";
517 reg = <0x0c>; 516 reg = <0x0c>;
518 /* FIXME: GPIO33 has interrupt 224 on the PM8058 */ 517 interrupt-parent = <&pm8058_gpio>;
519 interrupt-parent = <&pm8058>; 518 interrupts = <33 IRQ_TYPE_EDGE_RISING>;
520 interrupts = <224 IRQ_TYPE_EDGE_RISING>;
521 pinctrl-names = "default"; 519 pinctrl-names = "default";
522 pinctrl-0 = <&dragon_ak8975_gpios>; 520 pinctrl-0 = <&dragon_ak8975_gpios>;
523 vid-supply = <&pm8058_lvs0>; // 1.8V 521 vid-supply = <&pm8058_lvs0>; // 1.8V
@@ -526,9 +524,8 @@
526 bmp085@77 { 524 bmp085@77 {
527 compatible = "bosch,bmp085"; 525 compatible = "bosch,bmp085";
528 reg = <0x77>; 526 reg = <0x77>;
529 /* FIXME: GPIO16 has interrupt 207 on the PM8058 */ 527 interrupt-parent = <&pm8058_gpio>;
530 interrupt-parent = <&pm8058>; 528 interrupts = <16 IRQ_TYPE_EDGE_RISING>;
531 interrupts = <207 IRQ_TYPE_EDGE_RISING>;
532 reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>; 529 reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>;
533 pinctrl-names = "default"; 530 pinctrl-names = "default";
534 pinctrl-0 = <&dragon_bmp085_gpios>; 531 pinctrl-0 = <&dragon_bmp085_gpios>;
@@ -539,12 +536,11 @@
539 compatible = "invensense,mpu3050"; 536 compatible = "invensense,mpu3050";
540 reg = <0x68>; 537 reg = <0x68>;
541 /* 538 /*
542 * GPIO17 has interrupt 208 on the 539 * GPIO17 is pulled high by a 10k
543 * PM8058, it is pulled high by a 10k
544 * resistor to VLOGIC so needs to be 540 * resistor to VLOGIC so needs to be
545 * active low/falling edge. 541 * active low/falling edge.
546 */ 542 */
547 interrupts-extended = <&pm8058 208 IRQ_TYPE_EDGE_FALLING>; 543 interrupts-extended = <&pm8058_gpio 17 IRQ_TYPE_EDGE_FALLING>;
548 pinctrl-names = "default"; 544 pinctrl-names = "default";
549 pinctrl-0 = <&dragon_mpu3050_gpios>; 545 pinctrl-0 = <&dragon_mpu3050_gpios>;
550 vlogic-supply = <&pm8058_lvs0>; // 1.8V 546 vlogic-supply = <&pm8058_lvs0>; // 1.8V
@@ -589,11 +585,10 @@
589 compatible = "smsc,lan9221", "smsc,lan9115"; 585 compatible = "smsc,lan9221", "smsc,lan9115";
590 reg = <2 0x0 0x100>; 586 reg = <2 0x0 0x100>;
591 /* 587 /*
592 * GPIO7 has interrupt 198 on the PM8058
593 * The second interrupt is the PME interrupt 588 * The second interrupt is the PME interrupt
594 * for network wakeup, connected to the TLMM. 589 * for network wakeup, connected to the TLMM.
595 */ 590 */
596 interrupts-extended = <&pm8058 198 IRQ_TYPE_EDGE_FALLING>, 591 interrupts-extended = <&pm8058_gpio 7 IRQ_TYPE_EDGE_FALLING>,
597 <&tlmm 29 IRQ_TYPE_EDGE_RISING>; 592 <&tlmm 29 IRQ_TYPE_EDGE_RISING>;
598 reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>; 593 reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
599 vdd33a-supply = <&dragon_veth>; 594 vdd33a-supply = <&dragon_veth>;
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 48c3cf427610..4744fe757cf4 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -705,50 +705,8 @@
705 compatible = "qcom,pm8921-gpio", 705 compatible = "qcom,pm8921-gpio",
706 "qcom,ssbi-gpio"; 706 "qcom,ssbi-gpio";
707 reg = <0x150>; 707 reg = <0x150>;
708 interrupts = <192 IRQ_TYPE_NONE>, 708 interrupt-controller;
709 <193 IRQ_TYPE_NONE>, 709 #interrupt-cells = <2>;
710 <194 IRQ_TYPE_NONE>,
711 <195 IRQ_TYPE_NONE>,
712 <196 IRQ_TYPE_NONE>,
713 <197 IRQ_TYPE_NONE>,
714 <198 IRQ_TYPE_NONE>,
715 <199 IRQ_TYPE_NONE>,
716 <200 IRQ_TYPE_NONE>,
717 <201 IRQ_TYPE_NONE>,
718 <202 IRQ_TYPE_NONE>,
719 <203 IRQ_TYPE_NONE>,
720 <204 IRQ_TYPE_NONE>,
721 <205 IRQ_TYPE_NONE>,
722 <206 IRQ_TYPE_NONE>,
723 <207 IRQ_TYPE_NONE>,
724 <208 IRQ_TYPE_NONE>,
725 <209 IRQ_TYPE_NONE>,
726 <210 IRQ_TYPE_NONE>,
727 <211 IRQ_TYPE_NONE>,
728 <212 IRQ_TYPE_NONE>,
729 <213 IRQ_TYPE_NONE>,
730 <214 IRQ_TYPE_NONE>,
731 <215 IRQ_TYPE_NONE>,
732 <216 IRQ_TYPE_NONE>,
733 <217 IRQ_TYPE_NONE>,
734 <218 IRQ_TYPE_NONE>,
735 <219 IRQ_TYPE_NONE>,
736 <220 IRQ_TYPE_NONE>,
737 <221 IRQ_TYPE_NONE>,
738 <222 IRQ_TYPE_NONE>,
739 <223 IRQ_TYPE_NONE>,
740 <224 IRQ_TYPE_NONE>,
741 <225 IRQ_TYPE_NONE>,
742 <226 IRQ_TYPE_NONE>,
743 <227 IRQ_TYPE_NONE>,
744 <228 IRQ_TYPE_NONE>,
745 <229 IRQ_TYPE_NONE>,
746 <230 IRQ_TYPE_NONE>,
747 <231 IRQ_TYPE_NONE>,
748 <232 IRQ_TYPE_NONE>,
749 <233 IRQ_TYPE_NONE>,
750 <234 IRQ_TYPE_NONE>,
751 <235 IRQ_TYPE_NONE>;
752 gpio-controller; 710 gpio-controller;
753 #gpio-cells = <2>; 711 #gpio-cells = <2>;
754 712
diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi
index c852b69229c9..0ed6fc3e873c 100644
--- a/arch/arm/boot/dts/qcom-mdm9615.dtsi
+++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi
@@ -323,13 +323,8 @@
323 323
324 pmicgpio: gpio@150 { 324 pmicgpio: gpio@150 {
325 compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio"; 325 compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio";
326 interrupt-parent = <&pmicintc>; 326 interrupt-controller;
327 interrupts = <24 IRQ_TYPE_NONE>, 327 #interrupt-cells = <2>;
328 <25 IRQ_TYPE_NONE>,
329 <26 IRQ_TYPE_NONE>,
330 <27 IRQ_TYPE_NONE>,
331 <28 IRQ_TYPE_NONE>,
332 <29 IRQ_TYPE_NONE>;
333 gpio-controller; 328 gpio-controller;
334 #gpio-cells = <2>; 329 #gpio-cells = <2>;
335 }; 330 };
diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
index 70698941f64c..a4eeebcfd63a 100644
--- a/arch/arm/boot/dts/qcom-msm8660.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
@@ -285,51 +285,8 @@
285 compatible = "qcom,pm8058-gpio", 285 compatible = "qcom,pm8058-gpio",
286 "qcom,ssbi-gpio"; 286 "qcom,ssbi-gpio";
287 reg = <0x150>; 287 reg = <0x150>;
288 interrupt-parent = <&pm8058>; 288 interrupt-controller;
289 interrupts = <192 IRQ_TYPE_NONE>, 289 #interrupt-cells = <2>;
290 <193 IRQ_TYPE_NONE>,
291 <194 IRQ_TYPE_NONE>,
292 <195 IRQ_TYPE_NONE>,
293 <196 IRQ_TYPE_NONE>,
294 <197 IRQ_TYPE_NONE>,
295 <198 IRQ_TYPE_NONE>,
296 <199 IRQ_TYPE_NONE>,
297 <200 IRQ_TYPE_NONE>,
298 <201 IRQ_TYPE_NONE>,
299 <202 IRQ_TYPE_NONE>,
300 <203 IRQ_TYPE_NONE>,
301 <204 IRQ_TYPE_NONE>,
302 <205 IRQ_TYPE_NONE>,
303 <206 IRQ_TYPE_NONE>,
304 <207 IRQ_TYPE_NONE>,
305 <208 IRQ_TYPE_NONE>,
306 <209 IRQ_TYPE_NONE>,
307 <210 IRQ_TYPE_NONE>,
308 <211 IRQ_TYPE_NONE>,
309 <212 IRQ_TYPE_NONE>,
310 <213 IRQ_TYPE_NONE>,
311 <214 IRQ_TYPE_NONE>,
312 <215 IRQ_TYPE_NONE>,
313 <216 IRQ_TYPE_NONE>,
314 <217 IRQ_TYPE_NONE>,
315 <218 IRQ_TYPE_NONE>,
316 <219 IRQ_TYPE_NONE>,
317 <220 IRQ_TYPE_NONE>,
318 <221 IRQ_TYPE_NONE>,
319 <222 IRQ_TYPE_NONE>,
320 <223 IRQ_TYPE_NONE>,
321 <224 IRQ_TYPE_NONE>,
322 <225 IRQ_TYPE_NONE>,
323 <226 IRQ_TYPE_NONE>,
324 <227 IRQ_TYPE_NONE>,
325 <228 IRQ_TYPE_NONE>,
326 <229 IRQ_TYPE_NONE>,
327 <230 IRQ_TYPE_NONE>,
328 <231 IRQ_TYPE_NONE>,
329 <232 IRQ_TYPE_NONE>,
330 <233 IRQ_TYPE_NONE>,
331 <234 IRQ_TYPE_NONE>,
332 <235 IRQ_TYPE_NONE>;
333 gpio-controller; 290 gpio-controller;
334 #gpio-cells = <2>; 291 #gpio-cells = <2>;
335 292
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 76f9909cf396..5f1349c86a6f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -928,7 +928,7 @@ config UCB1400_CORE
928config MFD_PM8XXX 928config MFD_PM8XXX
929 tristate "Qualcomm PM8xxx PMIC chips driver" 929 tristate "Qualcomm PM8xxx PMIC chips driver"
930 depends on (ARM || HEXAGON || COMPILE_TEST) 930 depends on (ARM || HEXAGON || COMPILE_TEST)
931 select IRQ_DOMAIN 931 select IRQ_DOMAIN_HIERARCHY
932 select MFD_CORE 932 select MFD_CORE
933 select REGMAP 933 select REGMAP
934 help 934 help
diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c
index e6e8d81c15fd..8eb2528793f9 100644
--- a/drivers/mfd/qcom-pm8xxx.c
+++ b/drivers/mfd/qcom-pm8xxx.c
@@ -70,22 +70,23 @@
70#define PM8XXX_NR_IRQS 256 70#define PM8XXX_NR_IRQS 256
71#define PM8821_NR_IRQS 112 71#define PM8821_NR_IRQS 112
72 72
73struct pm_irq_data {
74 int num_irqs;
75 struct irq_chip *irq_chip;
76 void (*irq_handler)(struct irq_desc *desc);
77};
78
73struct pm_irq_chip { 79struct pm_irq_chip {
74 struct regmap *regmap; 80 struct regmap *regmap;
75 spinlock_t pm_irq_lock; 81 spinlock_t pm_irq_lock;
76 struct irq_domain *irqdomain; 82 struct irq_domain *irqdomain;
77 unsigned int num_irqs;
78 unsigned int num_blocks; 83 unsigned int num_blocks;
79 unsigned int num_masters; 84 unsigned int num_masters;
85 const struct pm_irq_data *pm_irq_data;
86 /* MUST BE AT THE END OF THIS STRUCT */
80 u8 config[0]; 87 u8 config[0];
81}; 88};
82 89
83struct pm_irq_data {
84 int num_irqs;
85 const struct irq_domain_ops *irq_domain_ops;
86 void (*irq_handler)(struct irq_desc *desc);
87};
88
89static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp, 90static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
90 unsigned int *ip) 91 unsigned int *ip)
91{ 92{
@@ -375,21 +376,38 @@ static struct irq_chip pm8xxx_irq_chip = {
375 .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, 376 .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
376}; 377};
377 378
378static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq, 379static void pm8xxx_irq_domain_map(struct pm_irq_chip *chip,
379 irq_hw_number_t hwirq) 380 struct irq_domain *domain, unsigned int irq,
381 irq_hw_number_t hwirq, unsigned int type)
380{ 382{
381 struct pm_irq_chip *chip = d->host_data; 383 irq_domain_set_info(domain, irq, hwirq, chip->pm_irq_data->irq_chip,
382 384 chip, handle_level_irq, NULL, NULL);
383 irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq);
384 irq_set_chip_data(irq, chip);
385 irq_set_noprobe(irq); 385 irq_set_noprobe(irq);
386}
387
388static int pm8xxx_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
389 unsigned int nr_irqs, void *data)
390{
391 struct pm_irq_chip *chip = domain->host_data;
392 struct irq_fwspec *fwspec = data;
393 irq_hw_number_t hwirq;
394 unsigned int type;
395 int ret, i;
396
397 ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type);
398 if (ret)
399 return ret;
400
401 for (i = 0; i < nr_irqs; i++)
402 pm8xxx_irq_domain_map(chip, domain, virq + i, hwirq + i, type);
386 403
387 return 0; 404 return 0;
388} 405}
389 406
390static const struct irq_domain_ops pm8xxx_irq_domain_ops = { 407static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
391 .xlate = irq_domain_xlate_twocell, 408 .alloc = pm8xxx_irq_domain_alloc,
392 .map = pm8xxx_irq_domain_map, 409 .free = irq_domain_free_irqs_common,
410 .translate = irq_domain_translate_twocell,
393}; 411};
394 412
395static void pm8821_irq_mask_ack(struct irq_data *d) 413static void pm8821_irq_mask_ack(struct irq_data *d)
@@ -473,23 +491,6 @@ static struct irq_chip pm8821_irq_chip = {
473 .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, 491 .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
474}; 492};
475 493
476static int pm8821_irq_domain_map(struct irq_domain *d, unsigned int irq,
477 irq_hw_number_t hwirq)
478{
479 struct pm_irq_chip *chip = d->host_data;
480
481 irq_set_chip_and_handler(irq, &pm8821_irq_chip, handle_level_irq);
482 irq_set_chip_data(irq, chip);
483 irq_set_noprobe(irq);
484
485 return 0;
486}
487
488static const struct irq_domain_ops pm8821_irq_domain_ops = {
489 .xlate = irq_domain_xlate_twocell,
490 .map = pm8821_irq_domain_map,
491};
492
493static const struct regmap_config ssbi_regmap_config = { 494static const struct regmap_config ssbi_regmap_config = {
494 .reg_bits = 16, 495 .reg_bits = 16,
495 .val_bits = 8, 496 .val_bits = 8,
@@ -501,13 +502,13 @@ static const struct regmap_config ssbi_regmap_config = {
501 502
502static const struct pm_irq_data pm8xxx_data = { 503static const struct pm_irq_data pm8xxx_data = {
503 .num_irqs = PM8XXX_NR_IRQS, 504 .num_irqs = PM8XXX_NR_IRQS,
504 .irq_domain_ops = &pm8xxx_irq_domain_ops, 505 .irq_chip = &pm8xxx_irq_chip,
505 .irq_handler = pm8xxx_irq_handler, 506 .irq_handler = pm8xxx_irq_handler,
506}; 507};
507 508
508static const struct pm_irq_data pm8821_data = { 509static const struct pm_irq_data pm8821_data = {
509 .num_irqs = PM8821_NR_IRQS, 510 .num_irqs = PM8821_NR_IRQS,
510 .irq_domain_ops = &pm8821_irq_domain_ops, 511 .irq_chip = &pm8821_irq_chip,
511 .irq_handler = pm8821_irq_handler, 512 .irq_handler = pm8821_irq_handler,
512}; 513};
513 514
@@ -571,14 +572,14 @@ static int pm8xxx_probe(struct platform_device *pdev)
571 572
572 platform_set_drvdata(pdev, chip); 573 platform_set_drvdata(pdev, chip);
573 chip->regmap = regmap; 574 chip->regmap = regmap;
574 chip->num_irqs = data->num_irqs; 575 chip->num_blocks = DIV_ROUND_UP(data->num_irqs, 8);
575 chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
576 chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); 576 chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
577 chip->pm_irq_data = data;
577 spin_lock_init(&chip->pm_irq_lock); 578 spin_lock_init(&chip->pm_irq_lock);
578 579
579 chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, 580 chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
580 data->num_irqs, 581 data->num_irqs,
581 data->irq_domain_ops, 582 &pm8xxx_irq_domain_ops,
582 chip); 583 chip);
583 if (!chip->irqdomain) 584 if (!chip->irqdomain)
584 return -ENODEV; 585 return -ENODEV;
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 93efbffcd3a4..2e66ab72c10b 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -150,6 +150,7 @@ config PINCTRL_QCOM_SSBI_PMIC
150 select PINMUX 150 select PINMUX
151 select PINCONF 151 select PINCONF
152 select GENERIC_PINCONF 152 select GENERIC_PINCONF
153 select IRQ_DOMAIN_HIERARCHY
153 help 154 help
154 This is the pinctrl, pinmux, pinconf and gpiolib driver for the 155 This is the pinctrl, pinmux, pinconf and gpiolib driver for the
155 Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips, 156 Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips,
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
index ded7d765af2e..08dd62b5cebe 100644
--- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
@@ -55,6 +55,8 @@
55 55
56#define PM8XXX_MAX_GPIOS 44 56#define PM8XXX_MAX_GPIOS 44
57 57
58#define PM8XXX_GPIO_PHYSICAL_OFFSET 1
59
58/* custom pinconf parameters */ 60/* custom pinconf parameters */
59#define PM8XXX_QCOM_DRIVE_STRENGH (PIN_CONFIG_END + 1) 61#define PM8XXX_QCOM_DRIVE_STRENGH (PIN_CONFIG_END + 1)
60#define PM8XXX_QCOM_PULL_UP_STRENGTH (PIN_CONFIG_END + 2) 62#define PM8XXX_QCOM_PULL_UP_STRENGTH (PIN_CONFIG_END + 2)
@@ -99,6 +101,9 @@ struct pm8xxx_gpio {
99 101
100 struct pinctrl_desc desc; 102 struct pinctrl_desc desc;
101 unsigned npins; 103 unsigned npins;
104
105 struct fwnode_handle *fwnode;
106 struct irq_domain *domain;
102}; 107};
103 108
104static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = { 109static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {
@@ -499,11 +504,12 @@ static int pm8xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
499 504
500 if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) { 505 if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) {
501 ret = pin->output_value; 506 ret = pin->output_value;
502 } else { 507 } else if (pin->irq >= 0) {
503 ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state); 508 ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
504 if (!ret) 509 if (!ret)
505 ret = !!state; 510 ret = !!state;
506 } 511 } else
512 ret = -EINVAL;
507 513
508 return ret; 514 return ret;
509} 515}
@@ -533,7 +539,7 @@ static int pm8xxx_gpio_of_xlate(struct gpio_chip *chip,
533 if (flags) 539 if (flags)
534 *flags = gpio_desc->args[1]; 540 *flags = gpio_desc->args[1];
535 541
536 return gpio_desc->args[0] - 1; 542 return gpio_desc->args[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;
537} 543}
538 544
539 545
@@ -541,8 +547,31 @@ static int pm8xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
541{ 547{
542 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip); 548 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
543 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; 549 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
550 struct irq_fwspec fwspec;
551 int ret;
552
553 fwspec.fwnode = pctrl->fwnode;
554 fwspec.param_count = 2;
555 fwspec.param[0] = offset + PM8XXX_GPIO_PHYSICAL_OFFSET;
556 fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
557
558 ret = irq_create_fwspec_mapping(&fwspec);
559
560 /*
561 * Cache the IRQ since pm8xxx_gpio_get() needs this to get determine the
562 * line level.
563 */
564 pin->irq = ret;
565
566 return ret;
567}
568
569static void pm8xxx_gpio_free(struct gpio_chip *chip, unsigned int offset)
570{
571 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
572 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
544 573
545 return pin->irq; 574 pin->irq = -1;
546} 575}
547 576
548#ifdef CONFIG_DEBUG_FS 577#ifdef CONFIG_DEBUG_FS
@@ -571,7 +600,7 @@ static void pm8xxx_gpio_dbg_show_one(struct seq_file *s,
571 "no", "high", "medium", "low" 600 "no", "high", "medium", "low"
572 }; 601 };
573 602
574 seq_printf(s, " gpio%-2d:", offset + 1); 603 seq_printf(s, " gpio%-2d:", offset + PM8XXX_GPIO_PHYSICAL_OFFSET);
575 if (pin->disable) { 604 if (pin->disable) {
576 seq_puts(s, " ---"); 605 seq_puts(s, " ---");
577 } else { 606 } else {
@@ -603,6 +632,7 @@ static void pm8xxx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
603#endif 632#endif
604 633
605static const struct gpio_chip pm8xxx_gpio_template = { 634static const struct gpio_chip pm8xxx_gpio_template = {
635 .free = pm8xxx_gpio_free,
606 .direction_input = pm8xxx_gpio_direction_input, 636 .direction_input = pm8xxx_gpio_direction_input,
607 .direction_output = pm8xxx_gpio_direction_output, 637 .direction_output = pm8xxx_gpio_direction_output,
608 .get = pm8xxx_gpio_get, 638 .get = pm8xxx_gpio_get,
@@ -664,13 +694,75 @@ static int pm8xxx_pin_populate(struct pm8xxx_gpio *pctrl,
664 return 0; 694 return 0;
665} 695}
666 696
697static struct irq_chip pm8xxx_irq_chip = {
698 .name = "ssbi-gpio",
699 .irq_mask_ack = irq_chip_mask_ack_parent,
700 .irq_unmask = irq_chip_unmask_parent,
701 .irq_set_type = irq_chip_set_type_parent,
702 .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
703};
704
705static int pm8xxx_domain_translate(struct irq_domain *domain,
706 struct irq_fwspec *fwspec,
707 unsigned long *hwirq,
708 unsigned int *type)
709{
710 struct pm8xxx_gpio *pctrl = container_of(domain->host_data,
711 struct pm8xxx_gpio, chip);
712
713 if (fwspec->param_count != 2 || fwspec->param[0] < 1 ||
714 fwspec->param[0] > pctrl->chip.ngpio)
715 return -EINVAL;
716
717 *hwirq = fwspec->param[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;
718 *type = fwspec->param[1];
719
720 return 0;
721}
722
723static int pm8xxx_domain_alloc(struct irq_domain *domain, unsigned int virq,
724 unsigned int nr_irqs, void *data)
725{
726 struct pm8xxx_gpio *pctrl = container_of(domain->host_data,
727 struct pm8xxx_gpio, chip);
728 struct irq_fwspec *fwspec = data;
729 struct irq_fwspec parent_fwspec;
730 irq_hw_number_t hwirq;
731 unsigned int type;
732 int ret, i;
733
734 ret = pm8xxx_domain_translate(domain, fwspec, &hwirq, &type);
735 if (ret)
736 return ret;
737
738 for (i = 0; i < nr_irqs; i++)
739 irq_domain_set_info(domain, virq + i, hwirq + i,
740 &pm8xxx_irq_chip, pctrl, handle_level_irq,
741 NULL, NULL);
742
743 parent_fwspec.fwnode = domain->parent->fwnode;
744 parent_fwspec.param_count = 2;
745 parent_fwspec.param[0] = hwirq + 0xc0;
746 parent_fwspec.param[1] = fwspec->param[1];
747
748 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
749 &parent_fwspec);
750}
751
752static const struct irq_domain_ops pm8xxx_domain_ops = {
753 .activate = gpiochip_irq_domain_activate,
754 .alloc = pm8xxx_domain_alloc,
755 .deactivate = gpiochip_irq_domain_deactivate,
756 .free = irq_domain_free_irqs_common,
757 .translate = pm8xxx_domain_translate,
758};
759
667static const struct of_device_id pm8xxx_gpio_of_match[] = { 760static const struct of_device_id pm8xxx_gpio_of_match[] = {
668 { .compatible = "qcom,pm8018-gpio" }, 761 { .compatible = "qcom,pm8018-gpio", .data = (void *) 6 },
669 { .compatible = "qcom,pm8038-gpio" }, 762 { .compatible = "qcom,pm8038-gpio", .data = (void *) 12 },
670 { .compatible = "qcom,pm8058-gpio" }, 763 { .compatible = "qcom,pm8058-gpio", .data = (void *) 44 },
671 { .compatible = "qcom,pm8917-gpio" }, 764 { .compatible = "qcom,pm8917-gpio", .data = (void *) 38 },
672 { .compatible = "qcom,pm8921-gpio" }, 765 { .compatible = "qcom,pm8921-gpio", .data = (void *) 44 },
673 { .compatible = "qcom,ssbi-gpio" },
674 { }, 766 { },
675}; 767};
676MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match); 768MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
@@ -678,22 +770,18 @@ MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
678static int pm8xxx_gpio_probe(struct platform_device *pdev) 770static int pm8xxx_gpio_probe(struct platform_device *pdev)
679{ 771{
680 struct pm8xxx_pin_data *pin_data; 772 struct pm8xxx_pin_data *pin_data;
773 struct irq_domain *parent_domain;
774 struct device_node *parent_node;
681 struct pinctrl_pin_desc *pins; 775 struct pinctrl_pin_desc *pins;
682 struct pm8xxx_gpio *pctrl; 776 struct pm8xxx_gpio *pctrl;
683 int ret; 777 int ret, i;
684 int i, npins;
685 778
686 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); 779 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
687 if (!pctrl) 780 if (!pctrl)
688 return -ENOMEM; 781 return -ENOMEM;
689 782
690 pctrl->dev = &pdev->dev; 783 pctrl->dev = &pdev->dev;
691 npins = platform_irq_count(pdev); 784 pctrl->npins = (uintptr_t) device_get_match_data(&pdev->dev);
692 if (!npins)
693 return -EINVAL;
694 if (npins < 0)
695 return npins;
696 pctrl->npins = npins;
697 785
698 pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL); 786 pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
699 if (!pctrl->regmap) { 787 if (!pctrl->regmap) {
@@ -720,12 +808,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
720 808
721 for (i = 0; i < pctrl->desc.npins; i++) { 809 for (i = 0; i < pctrl->desc.npins; i++) {
722 pin_data[i].reg = SSBI_REG_ADDR_GPIO(i); 810 pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);
723 pin_data[i].irq = platform_get_irq(pdev, i); 811 pin_data[i].irq = -1;
724 if (pin_data[i].irq < 0) {
725 dev_err(&pdev->dev,
726 "missing interrupts for pin %d\n", i);
727 return pin_data[i].irq;
728 }
729 812
730 ret = pm8xxx_pin_populate(pctrl, &pin_data[i]); 813 ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
731 if (ret) 814 if (ret)
@@ -756,10 +839,29 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
756 pctrl->chip.of_gpio_n_cells = 2; 839 pctrl->chip.of_gpio_n_cells = 2;
757 pctrl->chip.label = dev_name(pctrl->dev); 840 pctrl->chip.label = dev_name(pctrl->dev);
758 pctrl->chip.ngpio = pctrl->npins; 841 pctrl->chip.ngpio = pctrl->npins;
842
843 parent_node = of_irq_find_parent(pctrl->dev->of_node);
844 if (!parent_node)
845 return -ENXIO;
846
847 parent_domain = irq_find_host(parent_node);
848 of_node_put(parent_node);
849 if (!parent_domain)
850 return -ENXIO;
851
852 pctrl->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
853 pctrl->domain = irq_domain_create_hierarchy(parent_domain, 0,
854 pctrl->chip.ngpio,
855 pctrl->fwnode,
856 &pm8xxx_domain_ops,
857 &pctrl->chip);
858 if (!pctrl->domain)
859 return -ENODEV;
860
759 ret = gpiochip_add_data(&pctrl->chip, pctrl); 861 ret = gpiochip_add_data(&pctrl->chip, pctrl);
760 if (ret) { 862 if (ret) {
761 dev_err(&pdev->dev, "failed register gpiochip\n"); 863 dev_err(&pdev->dev, "failed register gpiochip\n");
762 return ret; 864 goto err_chip_add_data;
763 } 865 }
764 866
765 /* 867 /*
@@ -789,6 +891,8 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
789 891
790unregister_gpiochip: 892unregister_gpiochip:
791 gpiochip_remove(&pctrl->chip); 893 gpiochip_remove(&pctrl->chip);
894err_chip_add_data:
895 irq_domain_remove(pctrl->domain);
792 896
793 return ret; 897 return ret;
794} 898}
@@ -798,6 +902,7 @@ static int pm8xxx_gpio_remove(struct platform_device *pdev)
798 struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev); 902 struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);
799 903
800 gpiochip_remove(&pctrl->chip); 904 gpiochip_remove(&pctrl->chip);
905 irq_domain_remove(pctrl->domain);
801 906
802 return 0; 907 return 0;
803} 908}
diff --git a/include/linux/irq.h b/include/linux/irq.h
index def2b2aac8b1..9a1a67d2e07d 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -605,6 +605,7 @@ extern void irq_chip_disable_parent(struct irq_data *data);
605extern void irq_chip_ack_parent(struct irq_data *data); 605extern void irq_chip_ack_parent(struct irq_data *data);
606extern int irq_chip_retrigger_hierarchy(struct irq_data *data); 606extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
607extern void irq_chip_mask_parent(struct irq_data *data); 607extern void irq_chip_mask_parent(struct irq_data *data);
608extern void irq_chip_mask_ack_parent(struct irq_data *data);
608extern void irq_chip_unmask_parent(struct irq_data *data); 609extern void irq_chip_unmask_parent(struct irq_data *data);
609extern void irq_chip_eoi_parent(struct irq_data *data); 610extern void irq_chip_eoi_parent(struct irq_data *data);
610extern int irq_chip_set_affinity_parent(struct irq_data *data, 611extern int irq_chip_set_affinity_parent(struct irq_data *data,
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 35965f41d7be..fcefe0c7263f 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -419,6 +419,11 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
419 const u32 *intspec, unsigned int intsize, 419 const u32 *intspec, unsigned int intsize,
420 irq_hw_number_t *out_hwirq, unsigned int *out_type); 420 irq_hw_number_t *out_hwirq, unsigned int *out_type);
421 421
422int irq_domain_translate_twocell(struct irq_domain *d,
423 struct irq_fwspec *fwspec,
424 unsigned long *out_hwirq,
425 unsigned int *out_type);
426
422/* IPI functions */ 427/* IPI functions */
423int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest); 428int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
424int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); 429int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 086d5a34b5a0..0aefc2e69cf5 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1278,6 +1278,17 @@ void irq_chip_mask_parent(struct irq_data *data)
1278EXPORT_SYMBOL_GPL(irq_chip_mask_parent); 1278EXPORT_SYMBOL_GPL(irq_chip_mask_parent);
1279 1279
1280/** 1280/**
1281 * irq_chip_mask_ack_parent - Mask and acknowledge the parent interrupt
1282 * @data: Pointer to interrupt specific data
1283 */
1284void irq_chip_mask_ack_parent(struct irq_data *data)
1285{
1286 data = data->parent_data;
1287 data->chip->irq_mask_ack(data);
1288}
1289EXPORT_SYMBOL_GPL(irq_chip_mask_ack_parent);
1290
1291/**
1281 * irq_chip_unmask_parent - Unmask the parent interrupt 1292 * irq_chip_unmask_parent - Unmask the parent interrupt
1282 * @data: Pointer to interrupt specific data 1293 * @data: Pointer to interrupt specific data
1283 */ 1294 */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8b0be4bd6565..56a30d542b8e 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -729,16 +729,17 @@ static int irq_domain_translate(struct irq_domain *d,
729 return 0; 729 return 0;
730} 730}
731 731
732static void of_phandle_args_to_fwspec(struct of_phandle_args *irq_data, 732static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args,
733 unsigned int count,
733 struct irq_fwspec *fwspec) 734 struct irq_fwspec *fwspec)
734{ 735{
735 int i; 736 int i;
736 737
737 fwspec->fwnode = irq_data->np ? &irq_data->np->fwnode : NULL; 738 fwspec->fwnode = np ? &np->fwnode : NULL;
738 fwspec->param_count = irq_data->args_count; 739 fwspec->param_count = count;
739 740
740 for (i = 0; i < irq_data->args_count; i++) 741 for (i = 0; i < count; i++)
741 fwspec->param[i] = irq_data->args[i]; 742 fwspec->param[i] = args[i];
742} 743}
743 744
744unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) 745unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
@@ -836,7 +837,9 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
836{ 837{
837 struct irq_fwspec fwspec; 838 struct irq_fwspec fwspec;
838 839
839 of_phandle_args_to_fwspec(irq_data, &fwspec); 840 of_phandle_args_to_fwspec(irq_data->np, irq_data->args,
841 irq_data->args_count, &fwspec);
842
840 return irq_create_fwspec_mapping(&fwspec); 843 return irq_create_fwspec_mapping(&fwspec);
841} 844}
842EXPORT_SYMBOL_GPL(irq_create_of_mapping); 845EXPORT_SYMBOL_GPL(irq_create_of_mapping);
@@ -928,11 +931,10 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
928 const u32 *intspec, unsigned int intsize, 931 const u32 *intspec, unsigned int intsize,
929 irq_hw_number_t *out_hwirq, unsigned int *out_type) 932 irq_hw_number_t *out_hwirq, unsigned int *out_type)
930{ 933{
931 if (WARN_ON(intsize < 2)) 934 struct irq_fwspec fwspec;
932 return -EINVAL; 935
933 *out_hwirq = intspec[0]; 936 of_phandle_args_to_fwspec(ctrlr, intspec, intsize, &fwspec);
934 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; 937 return irq_domain_translate_twocell(d, &fwspec, out_hwirq, out_type);
935 return 0;
936} 938}
937EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell); 939EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
938 940
@@ -968,6 +970,27 @@ const struct irq_domain_ops irq_domain_simple_ops = {
968}; 970};
969EXPORT_SYMBOL_GPL(irq_domain_simple_ops); 971EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
970 972
973/**
974 * irq_domain_translate_twocell() - Generic translate for direct two cell
975 * bindings
976 *
977 * Device Tree IRQ specifier translation function which works with two cell
978 * bindings where the cell values map directly to the hwirq number
979 * and linux irq flags.
980 */
981int irq_domain_translate_twocell(struct irq_domain *d,
982 struct irq_fwspec *fwspec,
983 unsigned long *out_hwirq,
984 unsigned int *out_type)
985{
986 if (WARN_ON(fwspec->param_count < 2))
987 return -EINVAL;
988 *out_hwirq = fwspec->param[0];
989 *out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
990 return 0;
991}
992EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
993
971int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq, 994int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
972 int node, const struct irq_affinity_desc *affinity) 995 int node, const struct irq_affinity_desc *affinity)
973{ 996{