aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/renesas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/renesas')
-rw-r--r--drivers/phy/renesas/phy-rcar-gen2.c2
-rw-r--r--drivers/phy/renesas/phy-rcar-gen3-usb2.c19
2 files changed, 17 insertions, 4 deletions
diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c
index 8dc5710d9c98..2926e4937301 100644
--- a/drivers/phy/renesas/phy-rcar-gen2.c
+++ b/drivers/phy/renesas/phy-rcar-gen2.c
@@ -391,6 +391,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
error = of_property_read_u32(np, "reg", &channel_num);
if (error || channel_num > 2) {
dev_err(dev, "Invalid \"reg\" property\n");
+ of_node_put(np);
return error;
}
channel->select_mask = select_mask[channel_num];
@@ -406,6 +407,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
data->gen2_phy_ops);
if (IS_ERR(phy->phy)) {
dev_err(dev, "Failed to create PHY\n");
+ of_node_put(np);
return PTR_ERR(phy->phy);
}
phy_set_drvdata(phy->phy, phy);
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 1322185a00a2..8ffba67568ec 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -13,6 +13,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
@@ -106,6 +107,7 @@ struct rcar_gen3_chan {
struct rcar_gen3_phy rphys[NUM_OF_PHYS];
struct regulator *vbus;
struct work_struct work;
+ struct mutex lock; /* protects rphys[...].powered */
enum usb_dr_mode dr_mode;
bool extcon_host;
bool is_otg_channel;
@@ -437,15 +439,16 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
struct rcar_gen3_chan *channel = rphy->ch;
void __iomem *usb2_base = channel->base;
u32 val;
- int ret;
+ int ret = 0;
+ mutex_lock(&channel->lock);
if (!rcar_gen3_are_all_rphys_power_off(channel))
- return 0;
+ goto out;
if (channel->vbus) {
ret = regulator_enable(channel->vbus);
if (ret)
- return ret;
+ goto out;
}
val = readl(usb2_base + USB2_USBCTR);
@@ -454,7 +457,10 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
val &= ~USB2_USBCTR_PLL_RST;
writel(val, usb2_base + USB2_USBCTR);
+out:
+ /* The powered flag should be set for any other phys anyway */
rphy->powered = true;
+ mutex_unlock(&channel->lock);
return 0;
}
@@ -465,14 +471,18 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p)
struct rcar_gen3_chan *channel = rphy->ch;
int ret = 0;
+ mutex_lock(&channel->lock);
rphy->powered = false;
if (!rcar_gen3_are_all_rphys_power_off(channel))
- return 0;
+ goto out;
if (channel->vbus)
ret = regulator_disable(channel->vbus);
+out:
+ mutex_unlock(&channel->lock);
+
return ret;
}
@@ -639,6 +649,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
if (!phy_usb2_ops)
return -EINVAL;
+ mutex_init(&channel->lock);
for (i = 0; i < NUM_OF_PHYS; i++) {
channel->rphys[i].phy = devm_phy_create(dev, NULL,
phy_usb2_ops);