The otg-id/otg-bvalid/linestate irqs are multiplexed to one irq in otg-port on some Rockchip SoC (e.g RV1108), this patch add a quirk to support this mux irq feature.
Signed-off-by: Frank Wang <frank.w...@rock-chips.com> --- .../bindings/phy/phy-rockchip-inno-usb2.txt | 5 ++ drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 68 +++++++++++++++++----- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt index ddf868a..d49572b 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt @@ -22,6 +22,8 @@ Optional properties: register files". - rockchip,companion_grf_quirk : when set driver will request "rockchip,usbgrf" phandle as one companion-grf. + - rockchip,otg_mux_irq_quirk: set if otg-id/otg-bvalid/linestate irqs + are multiplexed to one irq in otg-port on some SoCs. Required nodes : a sub-node is required for each port the phy provides. The sub-node name is used to identify host or otg port, @@ -36,6 +38,9 @@ Required properties (port (child) node): * "otg-id" : for the otg id interrupt. * "otg-bvalid" : for the otg vbus interrupt. * "linestate" : for the host/otg linestate interrupt. + * "otg-mux" : otg-port interrupt, which multiplex otg-id/otg-bvalid/ + linestate irqs to one irq. Should specify if + rockchip,otg_mux_irq_quirk property is set. Optional properties: - phy-supply : phandle to a regulator that provides power to VBUS. diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 669e5f6..925919c 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -172,6 +172,8 @@ struct rockchip_usb2phy_cfg { * @vbus_attached: otg device vbus status. * @bvalid_irq: IRQ number assigned for vbus valid rise detection. * @ls_irq: IRQ number assigned for linestate detection. + * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate + * irqs to one irq in otg-port. * @mutex: for register updating in sm_work. * @chg_work: charge detect work. * @otg_sm_work: OTG state machine work. @@ -189,6 +191,7 @@ struct rockchip_usb2phy_port { bool vbus_attached; int bvalid_irq; int ls_irq; + int otg_mux_irq; struct mutex mutex; struct delayed_work chg_work; struct delayed_work otg_sm_work; @@ -228,6 +231,7 @@ struct rockchip_usb2phy { const struct rockchip_usb2phy_cfg *phy_cfg; struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; unsigned int companion_grf_quirk:1; + unsigned int otg_mux_irq_quirk:1; }; static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy) @@ -935,6 +939,17 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data) return IRQ_HANDLED; } +static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data) +{ + struct rockchip_usb2phy_port *rport = data; + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); + + if (property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st)) + return rockchip_usb2phy_bvalid_irq(irq, data); + else + return IRQ_NONE; +} + static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy, struct rockchip_usb2phy_port *rport, struct device_node *child_np) @@ -1011,20 +1026,44 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, rport->utmi_avalid = of_property_read_bool(child_np, "rockchip,utmi-avalid"); - rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid"); - if (rport->bvalid_irq < 0) { - dev_err(rphy->dev, "no vbus valid irq provided\n"); - ret = rport->bvalid_irq; - goto out; - } + if (rphy->otg_mux_irq_quirk) { + rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux"); + if (rport->otg_mux_irq < 0) { + dev_err(rphy->dev, "no otg-mux irq provided\n"); + ret = rport->otg_mux_irq; + goto out; + } - ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, NULL, - rockchip_usb2phy_bvalid_irq, - IRQF_ONESHOT, - "rockchip_usb2phy_bvalid", rport); - if (ret) { - dev_err(rphy->dev, "failed to request otg-bvalid irq handle\n"); - goto out; + ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq, + NULL, + rockchip_usb2phy_otg_mux_irq, + IRQF_ONESHOT, + "rockchip_usb2phy_otg", + rport); + if (ret) { + dev_err(rphy->dev, + "failed to request otg-mux irq handle\n"); + goto out; + } + } else { + rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid"); + if (rport->bvalid_irq < 0) { + dev_err(rphy->dev, "no vbus valid irq provided\n"); + ret = rport->bvalid_irq; + goto out; + } + + ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, + NULL, + rockchip_usb2phy_bvalid_irq, + IRQF_ONESHOT, + "rockchip_usb2phy_bvalid", + rport); + if (ret) { + dev_err(rphy->dev, + "failed to request otg-bvalid irq handle\n"); + goto out; + } } if (!IS_ERR(rphy->edev)) { @@ -1081,6 +1120,9 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) rphy->usbgrf = NULL; } + rphy->otg_mux_irq_quirk = + device_property_read_bool(dev, "rockchip,otg_mux_irq_quirk"); + if (of_property_read_u32(np, "reg", ®)) { dev_err(dev, "the reg property is not assigned in %s node\n", np->name); -- 2.0.0