From c7ec4ec5a3c4bd25c2d6cadc01062291679a4946 Mon Sep 17 00:00:00 2001 From: lyz Date: Mon, 7 Jul 2014 19:24:02 +0800 Subject: [PATCH] usb: update soft reset 1.add rst_flag to distinguish different reset cases 2.use new reset framework APIs --- arch/arm/boot/dts/rk3288.dtsi | 12 ++ drivers/usb/dwc_otg_310/dwc_otg_driver.c | 2 +- drivers/usb/dwc_otg_310/dwc_otg_hcd_linux.c | 2 +- drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c | 2 +- drivers/usb/dwc_otg_310/usbdev_rk.h | 12 +- drivers/usb/dwc_otg_310/usbdev_rk30.c | 6 +- drivers/usb/dwc_otg_310/usbdev_rk32.c | 126 +++++++++++++------- drivers/usb/host/ehci-rkhsic.c | 4 +- drivers/usb/host/ehci-rockchip.c | 6 +- 9 files changed, 113 insertions(+), 59 deletions(-) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 2c250835ecf0..438ae0d567d9 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1075,6 +1075,9 @@ interrupts = ; clocks = <&clk_gates13 4>, <&clk_gates7 4>; clock-names = "clk_usbphy0", "hclk_usb0"; + resets = <&reset RK3288_SOFT_RST_USBOTG_H>, <&reset RK3288_SOFT_RST_USBOTGPHY>, + <&reset RK3288_SOFT_RST_USBOTGC>; + reset-names = "otg_ahb", "otg_phy", "otg_controller"; /*0 - Normal, 1 - Force Host, 2 - Force Device*/ rockchip,usb-mode = <0>; }; @@ -1087,6 +1090,9 @@ <&usbphy_480m>; clock-names = "clk_usbphy1", "hclk_usb1", "usbphy_480m"; + resets = <&reset RK3288_SOFT_RST_USBHOST1_H>, <&reset RK3288_SOFT_RST_USBHOST1PHY>, + <&reset RK3288_SOFT_RST_USBHOST1C>; + reset-names = "host1_ahb", "host1_phy", "host1_controller"; }; usb2: usb@ff500000 { @@ -1095,6 +1101,9 @@ interrupts = ; clocks = <&clk_gates13 5>, <&clk_gates7 6>; clock-names = "clk_usbphy2", "hclk_usb2"; + resets = <&reset RK3288_SOFT_RST_USBHOST0_H>, <&reset RK3288_SOFT_RST_USBHOST0PHY>, + <&reset RK3288_SOFT_RST_USBHOST0C>, <&reset RK3288_SOFT_RST_USB_HOST0>; + reset-names = "ehci_ahb", "ehci_phy", "ehci_controller", "ehci"; }; usb3: usb@ff520000 { @@ -1115,6 +1124,9 @@ clock-names = "hsicphy_480m", "hclk_hsic", "hsicphy_12m", "usbphy_480m", "hsic_usbphy1", "hsic_usbphy2"; + resets = <&reset RK3288_SOFT_RST_HSIC>, <&reset RK3288_SOFT_RST_HSIC_AUX>, + <&reset RK3288_SOFT_RST_HSICPHY>; + reset-names = "hsic_ahb", "hsic_aux", "hsic_phy"; }; gmac: eth@ff290000 { diff --git a/drivers/usb/dwc_otg_310/dwc_otg_driver.c b/drivers/usb/dwc_otg_310/dwc_otg_driver.c index 74deafef62f1..3afba4084333 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_driver.c @@ -1029,7 +1029,7 @@ static int host20_driver_probe(struct platform_device *_dev) pldata->phy_suspend(pldata, USB_PHY_ENABLED); if (pldata->soft_reset) - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_POR); res_base = platform_get_resource(_dev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd_linux.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd_linux.c index 7da1cd71e0d6..42c3dc1349d7 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd_linux.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd_linux.c @@ -376,7 +376,7 @@ static void dwc_otg_hcd_enable(struct work_struct *work) _core_if->hcd_cb->disconnect(_core_if->hcd_cb->p); } #endif - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_RECNT); dwc_otg_disable_host_interrupts(core_if); if (pldata->phy_suspend) pldata->phy_suspend(pldata, USB_PHY_SUSPEND); diff --git a/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c b/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c index def6e719d969..6a733ddf0117 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c @@ -1479,7 +1479,7 @@ static void dwc_phy_reconnect(struct work_struct *work) if (gctrl.b.bsesvld) { pcd->conn_status++; - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_RECNT); dwc_pcd_reset(pcd); /* * Enable the global interrupt after all the interrupt diff --git a/drivers/usb/dwc_otg_310/usbdev_rk.h b/drivers/usb/dwc_otg_310/usbdev_rk.h index f79adac1563f..0c6e48a57d98 100755 --- a/drivers/usb/dwc_otg_310/usbdev_rk.h +++ b/drivers/usb/dwc_otg_310/usbdev_rk.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,13 @@ #define USB_REMOTE_WAKEUP (6) #define USB_IRQ_WAKEUP (7) +enum rkusb_rst_flag { + RST_POR = 0, /* Reset power-on */ + RST_RECNT, /* Reset re-connect */ + RST_CHN_HALT, /* Reset a channel halt has been detected */ + RST_OTHER, +}; + extern int rk_usb_charger_status; extern void rk_send_wakeup_key(void); /* rk3188 platform data */ @@ -63,7 +71,7 @@ struct dwc_otg_platform_data { int phy_status; void (*hw_init) (void); void (*phy_suspend) (void *pdata, int suspend); - void (*soft_reset) (void); + void (*soft_reset) (void *pdata, enum rkusb_rst_flag rst_type); void (*clock_init) (void *pdata); void (*clock_enable) (void *pdata, int enable); void (*power_enable) (int enable); @@ -83,7 +91,7 @@ struct rkehci_platform_data { void (*clock_init) (void *pdata); void (*clock_enable) (void *pdata, int enable); void (*phy_suspend) (void *pdata, int suspend); - void (*soft_reset) (void); + void (*soft_reset) (void *pdata, enum rkusb_rst_flag rst_type); int (*get_status) (int id); int clk_status; int phy_status; diff --git a/drivers/usb/dwc_otg_310/usbdev_rk30.c b/drivers/usb/dwc_otg_310/usbdev_rk30.c index 0f3c134c9e55..dcdfb7d38e24 100755 --- a/drivers/usb/dwc_otg_310/usbdev_rk30.c +++ b/drivers/usb/dwc_otg_310/usbdev_rk30.c @@ -43,7 +43,7 @@ static void usb20otg_phy_suspend(void *pdata, int suspend) } } -static void usb20otg_soft_reset(void) +static void usb20otg_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { } @@ -192,7 +192,7 @@ static void usb20host_phy_suspend(void *pdata, int suspend) } } -static void usb20host_soft_reset(void) +static void usb20host_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { } @@ -368,7 +368,7 @@ static void rk_hsic_clock_enable(void *pdata, int enable) } } -static void rk_hsic_soft_reset(void) +static void rk_hsic_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { } diff --git a/drivers/usb/dwc_otg_310/usbdev_rk32.c b/drivers/usb/dwc_otg_310/usbdev_rk32.c index d1a9406fe3f9..97675201256b 100755 --- a/drivers/usb/dwc_otg_310/usbdev_rk32.c +++ b/drivers/usb/dwc_otg_310/usbdev_rk32.c @@ -43,16 +43,26 @@ static void usb20otg_phy_suspend(void *pdata, int suspend) } } -static void usb20otg_soft_reset(void) +static void usb20otg_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTG_H, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGPHY, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGC, true); - udelay(5); + struct dwc_otg_platform_data *usbpdata = pdata; + struct reset_control *rst_otg_h, *rst_otg_p, *rst_otg_c; + + rst_otg_h = devm_reset_control_get(usbpdata->dev, "otg_ahb"); + rst_otg_p = devm_reset_control_get(usbpdata->dev, "otg_phy"); + rst_otg_c = devm_reset_control_get(usbpdata->dev, "otg_controller"); + if (IS_ERR(rst_otg_h) || IS_ERR(rst_otg_p) || IS_ERR(rst_otg_c)) { + dev_err(usbpdata->dev, "Fail to get reset control from dts\n"); + return; + } - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTG_H, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGPHY, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGC, false); + reset_control_assert(rst_otg_h); + reset_control_assert(rst_otg_p); + reset_control_assert(rst_otg_c); + udelay(5); + reset_control_deassert(rst_otg_h); + reset_control_deassert(rst_otg_p); + reset_control_deassert(rst_otg_c); mdelay(2); } @@ -206,16 +216,26 @@ static void usb20host_phy_suspend(void *pdata, int suspend) } } -static void usb20host_soft_reset(void) +static void usb20host_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1_H, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1PHY, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1C, true); - udelay(5); + struct dwc_otg_platform_data *usbpdata = pdata; + struct reset_control *rst_host1_h, *rst_host1_p, *rst_host1_c; - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1_H, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1PHY, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1C, false); + rst_host1_h = devm_reset_control_get(usbpdata->dev, "host1_ahb"); + rst_host1_p = devm_reset_control_get(usbpdata->dev, "host1_phy"); + rst_host1_c = devm_reset_control_get(usbpdata->dev, "host1_controller"); + if (IS_ERR(rst_host1_h) || IS_ERR(rst_host1_p) || IS_ERR(rst_host1_c)) { + dev_err(usbpdata->dev, "Fail to get reset control from dts\n"); + return; + } + + reset_control_assert(rst_host1_h); + reset_control_assert(rst_host1_p); + reset_control_assert(rst_host1_c); + udelay(5); + reset_control_deassert(rst_host1_h); + reset_control_deassert(rst_host1_p); + reset_control_deassert(rst_host1_c); mdelay(2); } @@ -392,16 +412,22 @@ static void rk_hsic_clock_enable(void *pdata, int enable) } } -static void rk_hsic_soft_reset(void) +static void rk_hsic_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC_AUX, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSICPHY, true); - udelay(5); + struct rkehci_platform_data *usbpdata = pdata; + struct reset_control *rst_hsic_h, rst_hsic_a, rst_hsic_p; - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC_AUX, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSICPHY, false); + rst_hsic_h = devm_reset_control_get(usbpdata->dev, "hsic_ahb"); + rst_hsic_a = devm_reset_control_get(usbpdata->dev, "hsic_aux"); + rst_hsic_p = devm_reset_control_get(usbpdata->dev, "hsic_phy"); + + reset_control_assert(rst_hsic_h); + reset_control_assert(rst_hsic_a); + reset_control_assert(rst_hsic_p); + udelay(5); + reset_control_deassert(rst_hsic_h); + reset_control_deassert(rst_hsic_a); + reset_control_deassert(rst_hsic_p); mdelay(2); /* HSIC per-port reset */ @@ -491,18 +517,31 @@ static void rk_ehci_clock_enable(void *pdata, int enable) } } -static void rk_ehci_soft_reset(void) +static void rk_ehci_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0_H, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0PHY, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0C, true); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USB_HOST0, true); - udelay(5); + struct rkehci_platform_data *usbpdata = pdata; + struct reset_control *rst_host0_h, *rst_host0_p, + *rst_host0_c , *rst_host0; + + rst_host0_h = devm_reset_control_get(usbpdata->dev, "ehci_ahb"); + rst_host0_p = devm_reset_control_get(usbpdata->dev, "ehci_phy"); + rst_host0_c = devm_reset_control_get(usbpdata->dev, "ehci_controller"); + rst_host0 = devm_reset_control_get(usbpdata->dev, "ehci"); + if (IS_ERR(rst_host0_h) || IS_ERR(rst_host0_p) || + IS_ERR(rst_host0_c) || IS_ERR(rst_host0)) { + dev_err(usbpdata->dev, "Fail to get reset control from dts\n"); + return; + } - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0_H, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0PHY, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0C, false); - rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USB_HOST0, false); + reset_control_assert(rst_host0_h); + reset_control_assert(rst_host0_p); + reset_control_assert(rst_host0_c); + reset_control_assert(rst_host0); + udelay(5); + reset_control_deassert(rst_host0_h); + reset_control_deassert(rst_host0_p); + reset_control_deassert(rst_host0_c); + reset_control_deassert(rst_host0); mdelay(2); } @@ -595,7 +634,7 @@ static void rk_ohci_clock_enable(void *pdata, int enable) } } -static void rk_ohci_soft_reset(void) +static void rk_ohci_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) { } @@ -725,34 +764,29 @@ static int otg_irq_detect_init(struct platform_device *pdev) /*register otg_bvalid irq */ irq = platform_get_irq_byname(pdev, "otg_bvalid"); - if (irq > 0) { - ret = - request_irq(irq, bvalid_irq_handler, 0, "otg_bvalid", NULL); + if ((irq > 0) && control_usb->usb_irq_wakeup) { + ret = request_irq(irq, bvalid_irq_handler, + 0, "otg_bvalid", NULL); if (ret < 0) { dev_err(&pdev->dev, "request_irq %d failed!\n", irq); - return ret; } else { /* enable bvalid irq */ control_usb->grf_uoc0_base->CON4 = 0x000c000c; - if (control_usb->usb_irq_wakeup) - enable_irq_wake(irq); } } /*register otg_id irq */ irq = platform_get_irq_byname(pdev, "otg_id"); - if (irq > 0) { + if ((irq > 0) && control_usb->usb_irq_wakeup) { ret = request_irq(irq, id_irq_handler, 0, "otg_id", NULL); if (ret < 0) { dev_err(&pdev->dev, "request_irq %d failed!\n", irq); - return ret; } else { + /* enable otg_id irq */ control_usb->grf_uoc0_base->CON4 = 0x00f000f0; - if (control_usb->usb_irq_wakeup) - enable_irq_wake(irq); } } -#ifdef USB_LINESTATE_IRQ +#if 0 /*register otg_linestate irq */ irq = platform_get_irq_byname(pdev, "otg_linestate"); if (irq > 0) { diff --git a/drivers/usb/host/ehci-rkhsic.c b/drivers/usb/host/ehci-rkhsic.c index 72495a8c8291..659bcf0fd414 100755 --- a/drivers/usb/host/ehci-rkhsic.c +++ b/drivers/usb/host/ehci-rkhsic.c @@ -142,7 +142,7 @@ static ssize_t ehci_rkhsic_power_store(struct device *_dev, usb_remove_hcd(hcd); break; case 1: /* power on */ - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_POR); usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED); ehci_rkhsic_port_power(ehci, 1); @@ -275,7 +275,7 @@ static int ehci_rkhsic_probe(struct platform_device *pdev) } if (pldata->soft_reset) - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_POR);; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { diff --git a/drivers/usb/host/ehci-rockchip.c b/drivers/usb/host/ehci-rockchip.c index 74fd0b786d53..03217cd22e7e 100755 --- a/drivers/usb/host/ehci-rockchip.c +++ b/drivers/usb/host/ehci-rockchip.c @@ -97,7 +97,7 @@ static void rk_ehci_hcd_enable(struct work_struct *work) usb_remove_hcd(hcd); /* reset cru and reinitialize EHCI controller */ - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_RECNT); usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED); if (pldata->phy_suspend) pldata->phy_suspend(pldata, USB_PHY_SUSPEND); @@ -228,7 +228,7 @@ static ssize_t ehci_power_store(struct device *_dev, usb_remove_hcd(hcd); break; case 1: /* power on */ - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_POR); usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED); ehci_port_power(ehci, 1); break; @@ -357,7 +357,7 @@ static int ehci_rk_probe(struct platform_device *pdev) pldata->phy_suspend(pldata, USB_PHY_ENABLED); if (pldata->soft_reset) - pldata->soft_reset(); + pldata->soft_reset(pldata, RST_POR);; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { -- 2.34.1