aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-06-03 01:13:41 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-06-03 01:13:41 -0400
commitb3d424e3dcbb5eba572baae30e1052b2fff7b51e (patch)
tree8055b6dca7b3cda1beffc6f5aee3a7602daef09b /drivers/phy
parentf50420223071b6ff4b586308f5c27eec54694a81 (diff)
parent692fbb89fa0b8028f402e33eb912474e11b5f435 (diff)
Merge tag 'phy-for-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next
Kishon writes: phy: for 4.2 merge window *) new Broadcom SATA3 PHY driver for Broadcom STB SoCs *) new phy API to get PHY by index which is used in EHCI and OHCI controller drivers *) support specifying supply at port level used for multi-port PHYs *) sparse warning fixes in miphy PHYs *) fix pm_runtime issues in twl4030 driver Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/Kconfig9
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/phy-brcmstb-sata.c216
-rw-r--r--drivers/phy/phy-core.c67
-rw-r--r--drivers/phy/phy-miphy28lp.c9
-rw-r--r--drivers/phy/phy-miphy365x.c9
-rw-r--r--drivers/phy/phy-rcar-gen2.c6
-rw-r--r--drivers/phy/phy-twl4030-usb.c34
8 files changed, 303 insertions, 48 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index fceac96c2a31..56e1b7585d27 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -316,4 +316,13 @@ config PHY_TUSB1210
316 help 316 help
317 Support for TI TUSB1210 USB ULPI PHY. 317 Support for TI TUSB1210 USB ULPI PHY.
318 318
319config PHY_BRCMSTB_SATA
320 tristate "Broadcom STB SATA PHY driver"
321 depends on ARCH_BRCMSTB
322 depends on OF
323 select GENERIC_PHY
324 help
325 Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs.
326 Likely useful only with CONFIG_SATA_BRCMSTB enabled.
327
319endmenu 328endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 0a2041803135..bc92b427e5ca 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -41,3 +41,4 @@ obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
41obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o 41obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
42obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o 42obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
43obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o 43obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
44obj-$(CONFIG_PHY_BRCMSTB_SATA) += phy-brcmstb-sata.o
diff --git a/drivers/phy/phy-brcmstb-sata.c b/drivers/phy/phy-brcmstb-sata.c
new file mode 100644
index 000000000000..b7e303d28caf
--- /dev/null
+++ b/drivers/phy/phy-brcmstb-sata.c
@@ -0,0 +1,216 @@
1/*
2 * Broadcom SATA3 AHCI Controller PHY Driver
3 *
4 * Copyright © 2009-2015 Broadcom Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/device.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/io.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/of.h>
24#include <linux/phy/phy.h>
25#include <linux/platform_device.h>
26
27#define SATA_MDIO_BANK_OFFSET 0x23c
28#define SATA_MDIO_REG_OFFSET(ofs) ((ofs) * 4)
29#define SATA_MDIO_REG_SPACE_SIZE 0x1000
30#define SATA_MDIO_REG_LENGTH 0x1f00
31
32#define MAX_PORTS 2
33
34/* Register offset between PHYs in PCB space */
35#define SATA_MDIO_REG_SPACE_SIZE 0x1000
36
37struct brcm_sata_port {
38 int portnum;
39 struct phy *phy;
40 struct brcm_sata_phy *phy_priv;
41 bool ssc_en;
42};
43
44struct brcm_sata_phy {
45 struct device *dev;
46 void __iomem *phy_base;
47
48 struct brcm_sata_port phys[MAX_PORTS];
49};
50
51enum sata_mdio_phy_regs_28nm {
52 PLL_REG_BANK_0 = 0x50,
53 PLL_REG_BANK_0_PLLCONTROL_0 = 0x81,
54
55 TXPMD_REG_BANK = 0x1a0,
56 TXPMD_CONTROL1 = 0x81,
57 TXPMD_CONTROL1_TX_SSC_EN_FRC = BIT(0),
58 TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL = BIT(1),
59 TXPMD_TX_FREQ_CTRL_CONTROL1 = 0x82,
60 TXPMD_TX_FREQ_CTRL_CONTROL2 = 0x83,
61 TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK = 0x3ff,
62 TXPMD_TX_FREQ_CTRL_CONTROL3 = 0x84,
63 TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK = 0x3ff,
64};
65
66static inline void __iomem *brcm_sata_phy_base(struct brcm_sata_port *port)
67{
68 struct brcm_sata_phy *priv = port->phy_priv;
69
70 return priv->phy_base + (port->portnum * SATA_MDIO_REG_SPACE_SIZE);
71}
72
73static void brcm_sata_mdio_wr(void __iomem *addr, u32 bank, u32 ofs,
74 u32 msk, u32 value)
75{
76 u32 tmp;
77
78 writel(bank, addr + SATA_MDIO_BANK_OFFSET);
79 tmp = readl(addr + SATA_MDIO_REG_OFFSET(ofs));
80 tmp = (tmp & msk) | value;
81 writel(tmp, addr + SATA_MDIO_REG_OFFSET(ofs));
82}
83
84/* These defaults were characterized by H/W group */
85#define FMIN_VAL_DEFAULT 0x3df
86#define FMAX_VAL_DEFAULT 0x3df
87#define FMAX_VAL_SSC 0x83
88
89static void brcm_sata_cfg_ssc_28nm(struct brcm_sata_port *port)
90{
91 void __iomem *base = brcm_sata_phy_base(port);
92 struct brcm_sata_phy *priv = port->phy_priv;
93 u32 tmp;
94
95 /* override the TX spread spectrum setting */
96 tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
97 brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
98
99 /* set fixed min freq */
100 brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
101 ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
102 FMIN_VAL_DEFAULT);
103
104 /* set fixed max freq depending on SSC config */
105 if (port->ssc_en) {
106 dev_info(priv->dev, "enabling SSC on port %d\n", port->portnum);
107 tmp = FMAX_VAL_SSC;
108 } else {
109 tmp = FMAX_VAL_DEFAULT;
110 }
111
112 brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
113 ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
114}
115
116static int brcm_sata_phy_init(struct phy *phy)
117{
118 struct brcm_sata_port *port = phy_get_drvdata(phy);
119
120 brcm_sata_cfg_ssc_28nm(port);
121
122 return 0;
123}
124
125static struct phy_ops phy_ops_28nm = {
126 .init = brcm_sata_phy_init,
127 .owner = THIS_MODULE,
128};
129
130static const struct of_device_id brcm_sata_phy_of_match[] = {
131 { .compatible = "brcm,bcm7445-sata-phy" },
132 {},
133};
134MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
135
136static int brcm_sata_phy_probe(struct platform_device *pdev)
137{
138 struct device *dev = &pdev->dev;
139 struct device_node *dn = dev->of_node, *child;
140 struct brcm_sata_phy *priv;
141 struct resource *res;
142 struct phy_provider *provider;
143 int count = 0;
144
145 if (of_get_child_count(dn) == 0)
146 return -ENODEV;
147
148 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
149 if (!priv)
150 return -ENOMEM;
151 dev_set_drvdata(dev, priv);
152 priv->dev = dev;
153
154 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
155 priv->phy_base = devm_ioremap_resource(dev, res);
156 if (IS_ERR(priv->phy_base))
157 return PTR_ERR(priv->phy_base);
158
159 for_each_available_child_of_node(dn, child) {
160 unsigned int id;
161 struct brcm_sata_port *port;
162
163 if (of_property_read_u32(child, "reg", &id)) {
164 dev_err(dev, "missing reg property in node %s\n",
165 child->name);
166 return -EINVAL;
167 }
168
169 if (id >= MAX_PORTS) {
170 dev_err(dev, "invalid reg: %u\n", id);
171 return -EINVAL;
172 }
173 if (priv->phys[id].phy) {
174 dev_err(dev, "already registered port %u\n", id);
175 return -EINVAL;
176 }
177
178 port = &priv->phys[id];
179 port->portnum = id;
180 port->phy_priv = priv;
181 port->phy = devm_phy_create(dev, child, &phy_ops_28nm);
182 port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
183 if (IS_ERR(port->phy)) {
184 dev_err(dev, "failed to create PHY\n");
185 return PTR_ERR(port->phy);
186 }
187
188 phy_set_drvdata(port->phy, port);
189 count++;
190 }
191
192 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
193 if (IS_ERR(provider)) {
194 dev_err(dev, "could not register PHY provider\n");
195 return PTR_ERR(provider);
196 }
197
198 dev_info(dev, "registered %d port(s)\n", count);
199
200 return 0;
201}
202
203static struct platform_driver brcm_sata_phy_driver = {
204 .probe = brcm_sata_phy_probe,
205 .driver = {
206 .of_match_table = brcm_sata_phy_of_match,
207 .name = "brcmstb-sata-phy",
208 }
209};
210module_platform_driver(brcm_sata_phy_driver);
211
212MODULE_DESCRIPTION("Broadcom STB SATA PHY driver");
213MODULE_LICENSE("GPL");
214MODULE_AUTHOR("Marc Carino");
215MODULE_AUTHOR("Brian Norris");
216MODULE_ALIAS("platform:phy-brcmstb-sata");
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 3791838f4bd4..7d535dbb63ee 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -367,13 +367,21 @@ static struct phy *_of_phy_get(struct device_node *np, int index)
367 phy_provider = of_phy_provider_lookup(args.np); 367 phy_provider = of_phy_provider_lookup(args.np);
368 if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { 368 if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
369 phy = ERR_PTR(-EPROBE_DEFER); 369 phy = ERR_PTR(-EPROBE_DEFER);
370 goto err0; 370 goto out_unlock;
371 }
372
373 if (!of_device_is_available(args.np)) {
374 dev_warn(phy_provider->dev, "Requested PHY is disabled\n");
375 phy = ERR_PTR(-ENODEV);
376 goto out_put_module;
371 } 377 }
372 378
373 phy = phy_provider->of_xlate(phy_provider->dev, &args); 379 phy = phy_provider->of_xlate(phy_provider->dev, &args);
380
381out_put_module:
374 module_put(phy_provider->owner); 382 module_put(phy_provider->owner);
375 383
376err0: 384out_unlock:
377 mutex_unlock(&phy_provider_mutex); 385 mutex_unlock(&phy_provider_mutex);
378 of_node_put(args.np); 386 of_node_put(args.np);
379 387
@@ -623,6 +631,38 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
623EXPORT_SYMBOL_GPL(devm_of_phy_get); 631EXPORT_SYMBOL_GPL(devm_of_phy_get);
624 632
625/** 633/**
634 * devm_of_phy_get_by_index() - lookup and obtain a reference to a phy by index.
635 * @dev: device that requests this phy
636 * @np: node containing the phy
637 * @index: index of the phy
638 *
639 * Gets the phy using _of_phy_get(), and associates a device with it using
640 * devres. On driver detach, release function is invoked on the devres data,
641 * then, devres data is freed.
642 *
643 */
644struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
645 int index)
646{
647 struct phy **ptr, *phy;
648
649 ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
650 if (!ptr)
651 return ERR_PTR(-ENOMEM);
652
653 phy = _of_phy_get(np, index);
654 if (!IS_ERR(phy)) {
655 *ptr = phy;
656 devres_add(dev, ptr);
657 } else {
658 devres_free(ptr);
659 }
660
661 return phy;
662}
663EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index);
664
665/**
626 * phy_create() - create a new phy 666 * phy_create() - create a new phy
627 * @dev: device that is creating the new phy 667 * @dev: device that is creating the new phy
628 * @node: device node of the phy 668 * @node: device node of the phy
@@ -651,16 +691,6 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
651 goto free_phy; 691 goto free_phy;
652 } 692 }
653 693
654 /* phy-supply */
655 phy->pwr = regulator_get_optional(dev, "phy");
656 if (IS_ERR(phy->pwr)) {
657 if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) {
658 ret = -EPROBE_DEFER;
659 goto free_ida;
660 }
661 phy->pwr = NULL;
662 }
663
664 device_initialize(&phy->dev); 694 device_initialize(&phy->dev);
665 mutex_init(&phy->mutex); 695 mutex_init(&phy->mutex);
666 696
@@ -674,6 +704,16 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
674 if (ret) 704 if (ret)
675 goto put_dev; 705 goto put_dev;
676 706
707 /* phy-supply */
708 phy->pwr = regulator_get_optional(&phy->dev, "phy");
709 if (IS_ERR(phy->pwr)) {
710 ret = PTR_ERR(phy->pwr);
711 if (ret == -EPROBE_DEFER)
712 goto put_dev;
713
714 phy->pwr = NULL;
715 }
716
677 ret = device_add(&phy->dev); 717 ret = device_add(&phy->dev);
678 if (ret) 718 if (ret)
679 goto put_dev; 719 goto put_dev;
@@ -689,9 +729,6 @@ put_dev:
689 put_device(&phy->dev); /* calls phy_release() which frees resources */ 729 put_device(&phy->dev); /* calls phy_release() which frees resources */
690 return ERR_PTR(ret); 730 return ERR_PTR(ret);
691 731
692free_ida:
693 ida_simple_remove(&phy_ida, phy->id);
694
695free_phy: 732free_phy:
696 kfree(phy); 733 kfree(phy);
697 return ERR_PTR(ret); 734 return ERR_PTR(ret);
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c
index c4cc11dcb2a2..5e257ef7ac05 100644
--- a/drivers/phy/phy-miphy28lp.c
+++ b/drivers/phy/phy-miphy28lp.c
@@ -367,7 +367,7 @@ static struct miphy28lp_pll_gen pcie_pll_gen[] = {
367 367
368static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy) 368static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy)
369{ 369{
370 void *base = miphy_phy->base; 370 void __iomem *base = miphy_phy->base;
371 u8 val; 371 u8 val;
372 372
373 /* Putting Macro in reset */ 373 /* Putting Macro in reset */
@@ -391,7 +391,7 @@ static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy)
391static inline void miphy28lp_pll_calibration(struct miphy28lp_phy *miphy_phy, 391static inline void miphy28lp_pll_calibration(struct miphy28lp_phy *miphy_phy,
392 struct pll_ratio *pll_ratio) 392 struct pll_ratio *pll_ratio)
393{ 393{
394 void *base = miphy_phy->base; 394 void __iomem *base = miphy_phy->base;
395 u8 val; 395 u8 val;
396 396
397 /* Applying PLL Settings */ 397 /* Applying PLL Settings */
@@ -1107,11 +1107,6 @@ static struct phy *miphy28lp_xlate(struct device *dev,
1107 struct device_node *phynode = args->np; 1107 struct device_node *phynode = args->np;
1108 int ret, index = 0; 1108 int ret, index = 0;
1109 1109
1110 if (!of_device_is_available(phynode)) {
1111 dev_warn(dev, "Requested PHY is disabled\n");
1112 return ERR_PTR(-ENODEV);
1113 }
1114
1115 if (args->args_count != 1) { 1110 if (args->args_count != 1) {
1116 dev_err(dev, "Invalid number of cells in 'phy' property\n"); 1111 dev_err(dev, "Invalid number of cells in 'phy' property\n");
1117 return ERR_PTR(-EINVAL); 1112 return ERR_PTR(-EINVAL);
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
index 019c2d75344e..0ff354d6e183 100644
--- a/drivers/phy/phy-miphy365x.c
+++ b/drivers/phy/phy-miphy365x.c
@@ -441,8 +441,8 @@ static int miphy365x_init(struct phy *phy)
441 return ret; 441 return ret;
442} 442}
443 443
444int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy, 444static int miphy365x_get_addr(struct device *dev,
445 int index) 445 struct miphy365x_phy *miphy_phy, int index)
446{ 446{
447 struct device_node *phynode = miphy_phy->phy->dev.of_node; 447 struct device_node *phynode = miphy_phy->phy->dev.of_node;
448 const char *name; 448 const char *name;
@@ -476,11 +476,6 @@ static struct phy *miphy365x_xlate(struct device *dev,
476 struct device_node *phynode = args->np; 476 struct device_node *phynode = args->np;
477 int ret, index; 477 int ret, index;
478 478
479 if (!of_device_is_available(phynode)) {
480 dev_warn(dev, "Requested PHY is disabled\n");
481 return ERR_PTR(-ENODEV);
482 }
483
484 if (args->args_count != 1) { 479 if (args->args_count != 1) {
485 dev_err(dev, "Invalid number of cells in 'phy' property\n"); 480 dev_err(dev, "Invalid number of cells in 'phy' property\n");
486 return ERR_PTR(-EINVAL); 481 return ERR_PTR(-EINVAL);
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index 778276aba3aa..0050301dce7a 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -195,6 +195,7 @@ static struct phy_ops rcar_gen2_phy_ops = {
195static const struct of_device_id rcar_gen2_phy_match_table[] = { 195static const struct of_device_id rcar_gen2_phy_match_table[] = {
196 { .compatible = "renesas,usb-phy-r8a7790" }, 196 { .compatible = "renesas,usb-phy-r8a7790" },
197 { .compatible = "renesas,usb-phy-r8a7791" }, 197 { .compatible = "renesas,usb-phy-r8a7791" },
198 { .compatible = "renesas,usb-phy-r8a7794" },
198 { } 199 { }
199}; 200};
200MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table); 201MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
@@ -206,11 +207,6 @@ static struct phy *rcar_gen2_phy_xlate(struct device *dev,
206 struct device_node *np = args->np; 207 struct device_node *np = args->np;
207 int i; 208 int i;
208 209
209 if (!of_device_is_available(np)) {
210 dev_warn(dev, "Requested PHY is disabled\n");
211 return ERR_PTR(-ENODEV);
212 }
213
214 drv = dev_get_drvdata(dev); 210 drv = dev_get_drvdata(dev);
215 if (!drv) 211 if (!drv)
216 return ERR_PTR(-EINVAL); 212 return ERR_PTR(-EINVAL);
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index bc42d6a8939f..3a707dd14238 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -144,6 +144,16 @@
144#define PMBR1 0x0D 144#define PMBR1 0x0D
145#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) 145#define GPIO_USB_4PIN_ULPI_2430C (3 << 0)
146 146
147/*
148 * If VBUS is valid or ID is ground, then we know a
149 * cable is present and we need to be runtime-enabled
150 */
151static inline bool cable_present(enum omap_musb_vbus_id_status stat)
152{
153 return stat == OMAP_MUSB_VBUS_VALID ||
154 stat == OMAP_MUSB_ID_GROUND;
155}
156
147struct twl4030_usb { 157struct twl4030_usb {
148 struct usb_phy phy; 158 struct usb_phy phy;
149 struct device *dev; 159 struct device *dev;
@@ -386,8 +396,6 @@ static int twl4030_usb_runtime_suspend(struct device *dev)
386 struct twl4030_usb *twl = dev_get_drvdata(dev); 396 struct twl4030_usb *twl = dev_get_drvdata(dev);
387 397
388 dev_dbg(twl->dev, "%s\n", __func__); 398 dev_dbg(twl->dev, "%s\n", __func__);
389 if (pm_runtime_suspended(dev))
390 return 0;
391 399
392 __twl4030_phy_power(twl, 0); 400 __twl4030_phy_power(twl, 0);
393 regulator_disable(twl->usb1v5); 401 regulator_disable(twl->usb1v5);
@@ -403,8 +411,6 @@ static int twl4030_usb_runtime_resume(struct device *dev)
403 int res; 411 int res;
404 412
405 dev_dbg(twl->dev, "%s\n", __func__); 413 dev_dbg(twl->dev, "%s\n", __func__);
406 if (pm_runtime_active(dev))
407 return 0;
408 414
409 res = regulator_enable(twl->usb3v1); 415 res = regulator_enable(twl->usb3v1);
410 if (res) 416 if (res)
@@ -536,8 +542,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
536 542
537 mutex_lock(&twl->lock); 543 mutex_lock(&twl->lock);
538 if (status >= 0 && status != twl->linkstat) { 544 if (status >= 0 && status != twl->linkstat) {
545 status_changed =
546 cable_present(twl->linkstat) !=
547 cable_present(status);
539 twl->linkstat = status; 548 twl->linkstat = status;
540 status_changed = true;
541 } 549 }
542 mutex_unlock(&twl->lock); 550 mutex_unlock(&twl->lock);
543 551
@@ -553,15 +561,11 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
553 * USB_LINK_VBUS state. musb_hdrc won't care until it 561 * USB_LINK_VBUS state. musb_hdrc won't care until it
554 * starts to handle softconnect right. 562 * starts to handle softconnect right.
555 */ 563 */
556 if ((status == OMAP_MUSB_VBUS_VALID) || 564 if (cable_present(status)) {
557 (status == OMAP_MUSB_ID_GROUND)) { 565 pm_runtime_get_sync(twl->dev);
558 if (pm_runtime_suspended(twl->dev))
559 pm_runtime_get_sync(twl->dev);
560 } else { 566 } else {
561 if (pm_runtime_active(twl->dev)) { 567 pm_runtime_mark_last_busy(twl->dev);
562 pm_runtime_mark_last_busy(twl->dev); 568 pm_runtime_put_autosuspend(twl->dev);
563 pm_runtime_put_autosuspend(twl->dev);
564 }
565 } 569 }
566 omap_musb_mailbox(status); 570 omap_musb_mailbox(status);
567 } 571 }
@@ -711,7 +715,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
711 pm_runtime_use_autosuspend(&pdev->dev); 715 pm_runtime_use_autosuspend(&pdev->dev);
712 pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); 716 pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
713 pm_runtime_enable(&pdev->dev); 717 pm_runtime_enable(&pdev->dev);
714 pm_runtime_get_sync(&pdev->dev);
715 718
716 /* Our job is to use irqs and status from the power module 719 /* Our job is to use irqs and status from the power module
717 * to keep the transceiver disabled when nothing's connected. 720 * to keep the transceiver disabled when nothing's connected.
@@ -767,6 +770,9 @@ static int twl4030_usb_remove(struct platform_device *pdev)
767 770
768 /* disable complete OTG block */ 771 /* disable complete OTG block */
769 twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); 772 twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
773
774 if (cable_present(twl->linkstat))
775 pm_runtime_put_noidle(twl->dev);
770 pm_runtime_mark_last_busy(twl->dev); 776 pm_runtime_mark_last_busy(twl->dev);
771 pm_runtime_put(twl->dev); 777 pm_runtime_put(twl->dev);
772 778