Re: RFC: qcom spmi/ssbi-gpio hierarchical irqchip problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

On Mon, Nov 26, 2018 at 09:41:38AM +0100, Linus Walleij wrote:
> Hi folks,
> 
> I see some people are working on the Qualcomm PMIC GPIOs,
> so wanted to bring to your attention one of the long overdue
> TODO things with the SPMI/SSBI GPIO.
> 
> I discussed it with Bjorn in the past and ran into it when hashing
> out some GPIO lines on the APQ8060 DragonBoard but it has
> since been forgotten.
> 
> The problem is that these drivers should have hierarchical
> irqchips.
> 
> For example (arch/arm/boot/dts/qcom-msm8660.dtsi):
> 
>                 qcom,ssbi@500000 {
>                         compatible = "qcom,ssbi";
>                         reg = <0x500000 0x1000>;
>                         qcom,controller-type = "pmic-arbiter";
> 
>                         pm8058: pmic@0 {
>                                 compatible = "qcom,pm8058";
>                                 interrupt-parent = <&tlmm>;
>                                 interrupts = <88 8>;
>                                 #interrupt-cells = <2>;
>                                 interrupt-controller;
>                                 #address-cells = <1>;
>                                 #size-cells = <0>;
> 
>                                 pm8058_gpio: gpio@150 {
>                                         compatible = "qcom,pm8058-gpio",
>                                                      "qcom,ssbi-gpio";
>                                         reg = <0x150>;
>                                         interrupt-parent = <&pm8058>;
>                                         interrupts = <192 IRQ_TYPE_NONE>,
>                                                      <193 IRQ_TYPE_NONE>,
>                                                      <194 IRQ_TYPE_NONE>,
>                                                      <195 IRQ_TYPE_NONE>,
>                                                      <196 IRQ_TYPE_NONE>,
> (...)
> 
> As you can see qcom,pm8058-gpio clearly specifies that
> it is consuming IRQs 192, 193.... from its parent PMIC
> interrupt controller.
> 
> (This is not a problem just with old boards like mine,
> but all later platforms using PMIC GPIO IRQs as well.)
> 
> This means the GPIO driver (ssbi, spmi) should be
> hierarchical and pick one of those IRQs.
> 
> However device tree consumers does not specify that
> it picks IRQs from the GPIO chip (in this case the
> pm8058_gpio node) but instead pick them directly from
> pm8058.
> 
> For example:
> 
>                 /* GPIO controlled ethernet power regulator */
>                 dragon_veth: xc622a331mrg {
>                         compatible = "regulator-fixed";
>                         regulator-name = "XC6222A331MR-G";
>                         regulator-min-microvolt = <3300000>;
>                         regulator-max-microvolt = <3300000>;
>                         vin-supply = <&vph>;
>                         gpio = <&pm8058_gpio 40 GPIO_ACTIVE_HIGH>;
>                         enable-active-high;
> 
> So this consumer is picking GPIO 40 on the GPIO and
> proceeds to pick an IRQ from the underlying PMIC.
> 
> We are lucky that the
> ethernet driver calls gpio[d]_to_irq() on the GPIO line, resulting
> in this function getting called in the driver:
> 
> static int pm8xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
> {
>         struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
>         struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
> 
>         return pin->irq;
> }
> 
> Which does the translation to the parent IRQ and it "works" for
> this case where you specify GPIO offset but not IRQ.
> 
> The problem is that all irqchips in a device tree should
> be usable straight off, without using any gpio[d]_to_irq() calls:
> they are orthogonal abstractions and should not depend
> on each other like this. It doesn't work at all with these
> drivers that don't have proper (hierarchical) irqchips.
> 
> Device tree nodes that use the irqchip directly does not work,
> so for example this consumer is out of luck:
> 
> ak8975@c {
>          compatible = "asahi-kasei,ak8975";
>          reg = <0x0c>;
>          /* FIXME: GPIO33 has interrupt 224 on the PM8058 */
>          interrupt-parent = <&pm8058>;
>          interrupts = <224 IRQ_TYPE_EDGE_RISING>;
>          (...)
> };
> 
> Since we are unable to pick an interrupt directly from the GPIO
> block, we need to refer to the parent to talk directly to the
> irqchip in the PMIC.
> 
> If we had implemented a proper hierarchical irqchip in
> the SSBI/SSPI-gpio drivers we could pick the IRQ just fine
> and things would get orderly in the device tree and
> /proc/interrupts.
> 
> This is not the only driver with this problem, but definately
> one of the most used drivers with this problem.
> 
> It's on my TODO as well and I bet on Bjorn's too, it's just
> that maybe we don't use it so much, so if any of you folks
> are actively using PMIC GPIO IRQs and can easily test
> these, could you please look into this?

I started to work this evening on converting pinctrl-spmi-gpio.c to
hierarchical irqs using pinctrl-stm32.c as a reference. I'll be
able to test that this is working properly on the Nexus 5 by using
gpio-keys with the volume up/down buttons on the phone. I'll need to
remove the call to gpiod_to_irq() from gpio_keys.c in my local tree..

stm32_pctl_probe() only sets up the hierarchical irqs if
interrupt-parent is defined on that node in device tree.
qcom-pm8941.dtsi currently doesn't have this property in the current
mainline and it is also not present in the downstream Android sources
for the Nexus 5. Does anyone know what I should put for the parent
interrupt controller? I don't have access to the documentation for
this particular hardware. For your convenience, here is the relevant
device tree node from qcom-pm8941.dtsi:

pm8941_gpios: gpios@c000 {
        compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio";
        reg = <0xc000>;
        gpio-controller;
        gpio-ranges = <&pm8941_gpios 0 0 36>;
        #gpio-cells = <2>;
        interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
                     <0 0xc1 0 IRQ_TYPE_NONE>,
                     <0 0xc2 0 IRQ_TYPE_NONE>,
                     <0 0xc3 0 IRQ_TYPE_NONE>,
                     <0 0xc4 0 IRQ_TYPE_NONE>,
                     <0 0xc5 0 IRQ_TYPE_NONE>,
                     <0 0xc6 0 IRQ_TYPE_NONE>,
                     <0 0xc7 0 IRQ_TYPE_NONE>,
                     <0 0xc8 0 IRQ_TYPE_NONE>,
                     <0 0xc9 0 IRQ_TYPE_NONE>,
                     <0 0xca 0 IRQ_TYPE_NONE>,
                     <0 0xcb 0 IRQ_TYPE_NONE>,
                     <0 0xcc 0 IRQ_TYPE_NONE>,
                     <0 0xcd 0 IRQ_TYPE_NONE>,
                     <0 0xce 0 IRQ_TYPE_NONE>,
                     <0 0xcf 0 IRQ_TYPE_NONE>,
                     <0 0xd0 0 IRQ_TYPE_NONE>,
                     <0 0xd1 0 IRQ_TYPE_NONE>,
                     <0 0xd2 0 IRQ_TYPE_NONE>,
                     <0 0xd3 0 IRQ_TYPE_NONE>,
                     <0 0xd4 0 IRQ_TYPE_NONE>,
                     <0 0xd5 0 IRQ_TYPE_NONE>,
                     <0 0xd6 0 IRQ_TYPE_NONE>,
                     <0 0xd7 0 IRQ_TYPE_NONE>,
                     <0 0xd8 0 IRQ_TYPE_NONE>,
                     <0 0xd9 0 IRQ_TYPE_NONE>,
                     <0 0xda 0 IRQ_TYPE_NONE>,
                     <0 0xdb 0 IRQ_TYPE_NONE>,
                     <0 0xdc 0 IRQ_TYPE_NONE>,
                     <0 0xdd 0 IRQ_TYPE_NONE>,
                     <0 0xde 0 IRQ_TYPE_NONE>,
                     <0 0xdf 0 IRQ_TYPE_NONE>,
                     <0 0xe0 0 IRQ_TYPE_NONE>,
                     <0 0xe1 0 IRQ_TYPE_NONE>,
                     <0 0xe2 0 IRQ_TYPE_NONE>,
                     <0 0xe3 0 IRQ_TYPE_NONE>;

        boost_bypass_n_pin: boost-bypass {
                pins = "gpio21";
                function = "normal";
        };
};

Thanks,

Brian



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux