summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Muellner <christoph.muellner@theobroma-systems.com>2019-06-14 14:39:02 +0200
committerChristoph Muellner <christoph.muellner@theobroma-systems.com>2019-09-27 20:57:23 +0200
commitd56fb5f89b1501dd7922c1c6d3c97f963df7a4af (patch)
tree743bbe5dc197278b9bc8161bf5bb1e6d9e5da52e
parent6903a6d6c2ee1a591be70ffd8b8b582d9d4e3473 (diff)
usb: dwc_otg_310: Prevent phy access if not probed.
In case the PHY is not successfully probed, we cannot access PHY functions like usb20otg_hw_init(), because they assume successful probing and might dereference NULL pointers otherwise. This patch addresses this by introducing a flag 'is_probed', which can be checked during controller probing time to verify, that the PHY has been probed. If this was not the case, controller probing will be deferred. Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
-rw-r--r--drivers/usb/dwc_otg_310/dwc_otg_driver.c12
-rw-r--r--drivers/usb/dwc_otg_310/usbdev_rk.h2
-rw-r--r--drivers/usb/dwc_otg_310/usbdev_rk3368.c10
3 files changed, 24 insertions, 0 deletions
diff --git a/drivers/usb/dwc_otg_310/dwc_otg_driver.c b/drivers/usb/dwc_otg_310/dwc_otg_driver.c
index 7bcf93dbe905..e903bb30f367 100644
--- a/drivers/usb/dwc_otg_310/dwc_otg_driver.c
+++ b/drivers/usb/dwc_otg_310/dwc_otg_driver.c
@@ -992,6 +992,12 @@ static int host20_driver_probe(struct platform_device *_dev)
return -EINVAL;
}
+ if (pldata->is_probed) {
+ if (pldata->is_probed() == 0) {
+ return -EPROBE_DEFER;
+ }
+ }
+
if (pldata->hw_init)
pldata->hw_init();
@@ -1381,6 +1387,12 @@ static int otg20_driver_probe(struct platform_device *_dev)
return -EINVAL;
}
+ if (pldata->is_probed) {
+ if (pldata->is_probed() == 0) {
+ return -EPROBE_DEFER;
+ }
+ }
+
if (pldata->hw_init)
pldata->hw_init();
diff --git a/drivers/usb/dwc_otg_310/usbdev_rk.h b/drivers/usb/dwc_otg_310/usbdev_rk.h
index 7fb62c23e16c..4d129d7b9c45 100644
--- a/drivers/usb/dwc_otg_310/usbdev_rk.h
+++ b/drivers/usb/dwc_otg_310/usbdev_rk.h
@@ -97,6 +97,7 @@ struct dwc_otg_platform_data {
void (*bc_detect_cb) (int bc_type);
int (*get_status) (int id);
void (*phy_power_down)(int power_down);
+ int (*is_probed) (void);
};
struct rkehci_platform_data {
@@ -140,6 +141,7 @@ struct dwc_otg_control_usb {
int usb_irq_wakeup;
int linestate_wakeup;
int chip_id;
+ int is_probed;
};
enum {
diff --git a/drivers/usb/dwc_otg_310/usbdev_rk3368.c b/drivers/usb/dwc_otg_310/usbdev_rk3368.c
index 65739aa3b7e3..789898d00a4f 100644
--- a/drivers/usb/dwc_otg_310/usbdev_rk3368.c
+++ b/drivers/usb/dwc_otg_310/usbdev_rk3368.c
@@ -5,6 +5,13 @@
static struct dwc_otg_control_usb *control_usb;
+static int usb20_is_probed(void)
+{
+ if (!control_usb)
+ return 0;
+ return control_usb->is_probed;
+}
+
static u32 uoc_read(u32 reg)
{
unsigned int val;
@@ -216,6 +223,7 @@ struct dwc_otg_platform_data usb20otg_pdata_rk3368 = {
.power_enable = usb20otg_power_enable,
.dwc_otg_uart_mode = dwc_otg_uart_mode,
.bc_detect_cb = rk_battery_charger_detect_cb,
+ .is_probed = usb20_is_probed,
};
#endif
@@ -498,6 +506,8 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
+ control_usb->is_probed = 1;
+
return 0;
err: