[PATCH v3 3/4] phy-sun4i-usb: Add workaround for missing Vbus det interrupts on A31
Kishon Vijay Abraham I
kishon at ti.com
Fri Jun 17 06:12:58 PDT 2016
On Sunday 05 June 2016 08:29 PM, Hans de Goede wrote:
> The A31 companion pmic (axp221) does not generate vbus change interrupts
> when the board is driving vbus, so we must poll when using the pmic for
> vbus-det _and_ we're driving vbus.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Acked-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
> Changes in v2:
> -No changes
> Changes in v3:
> -No changes
> ---
> drivers/phy/phy-sun4i-usb.c | 34 ++++++++++++++++++++++++----------
> 1 file changed, 24 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> index e3cbaae..a7abae6 100644
> --- a/drivers/phy/phy-sun4i-usb.c
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -95,6 +95,7 @@
>
> enum sun4i_usb_phy_type {
> sun4i_a10_phy,
> + sun6i_a31_phy,
> sun8i_a33_phy,
> sun8i_h3_phy,
> };
> @@ -125,7 +126,6 @@ struct sun4i_usb_phy_data {
> /* phy0 / otg related variables */
> struct extcon_dev *extcon;
> bool phy0_init;
> - bool phy0_poll;
> struct gpio_desc *id_det_gpio;
> struct gpio_desc *vbus_det_gpio;
> struct power_supply *vbus_power_supply;
> @@ -353,6 +353,24 @@ static bool sun4i_usb_phy0_have_vbus_det(struct sun4i_usb_phy_data *data)
> return data->vbus_det_gpio || data->vbus_power_supply;
> }
>
> +static bool sun4i_usb_phy0_poll(struct sun4i_usb_phy_data *data)
> +{
> + if ((data->id_det_gpio && data->id_det_irq < 0) ||
> + (data->vbus_det_gpio && data->vbus_det_irq < 0))
> + return true;
> +
> + /*
> + * The A31 companion pmic (axp221) does not generate vbus change
> + * interrupts when the board is driving vbus, so we must poll
> + * when using the pmic for vbus-det _and_ we're driving vbus.
> + */
> + if (data->cfg->type == sun6i_a31_phy &&
> + data->vbus_power_supply && data->phys[0].regulator_on)
> + return true;
> +
> + return false;
> +}
> +
> static int sun4i_usb_phy_power_on(struct phy *_phy)
> {
> struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> @@ -374,7 +392,7 @@ static int sun4i_usb_phy_power_on(struct phy *_phy)
> phy->regulator_on = true;
>
> /* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */
> - if (phy->index == 0 && data->vbus_det_gpio && data->phy0_poll)
> + if (phy->index == 0 && sun4i_usb_phy0_poll(data))
> mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
>
> return 0;
> @@ -395,7 +413,7 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
> * phy0 vbus typically slowly discharges, sometimes this causes the
> * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan.
> */
> - if (phy->index == 0 && data->vbus_det_gpio && !data->phy0_poll)
> + if (phy->index == 0 && !sun4i_usb_phy0_poll(data))
> mod_delayed_work(system_wq, &data->detect, POLL_TIME);
>
> return 0;
> @@ -483,7 +501,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
> if (vbus_notify)
> extcon_set_cable_state_(data->extcon, EXTCON_USB, vbus_det);
>
> - if (data->phy0_poll)
> + if (sun4i_usb_phy0_poll(data))
> queue_delayed_work(system_wq, &data->detect, POLL_TIME);
> }
>
> @@ -668,11 +686,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
> }
>
> data->id_det_irq = gpiod_to_irq(data->id_det_gpio);
> - data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio);
> - if ((data->id_det_gpio && data->id_det_irq < 0) ||
> - (data->vbus_det_gpio && data->vbus_det_irq < 0))
> - data->phy0_poll = true;
> -
> if (data->id_det_irq >= 0) {
> ret = devm_request_irq(dev, data->id_det_irq,
> sun4i_usb_phy0_id_vbus_det_irq,
> @@ -684,6 +697,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
> }
> }
>
> + data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio);
> if (data->vbus_det_irq >= 0) {
> ret = devm_request_irq(dev, data->vbus_det_irq,
> sun4i_usb_phy0_id_vbus_det_irq,
> @@ -735,7 +749,7 @@ static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
>
> static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
> .num_phys = 3,
> - .type = sun4i_a10_phy,
> + .type = sun6i_a31_phy,
> .disc_thresh = 3,
> .phyctl_offset = REG_PHYCTL_A10,
> .dedicated_clocks = true,
>
More information about the linux-arm-kernel
mailing list