1cedf8602SSascha Hauer /* 2cedf8602SSascha Hauer * phy.c -- USB phy handling 3cedf8602SSascha Hauer * 4cedf8602SSascha Hauer * Copyright (C) 2004-2013 Texas Instruments 5cedf8602SSascha Hauer * 6cedf8602SSascha Hauer * This program is free software; you can redistribute it and/or modify 7cedf8602SSascha Hauer * it under the terms of the GNU General Public License as published by 8cedf8602SSascha Hauer * the Free Software Foundation; either version 2 of the License, or 9cedf8602SSascha Hauer * (at your option) any later version. 10cedf8602SSascha Hauer */ 11cedf8602SSascha Hauer #include <linux/kernel.h> 12cedf8602SSascha Hauer #include <linux/export.h> 13cedf8602SSascha Hauer #include <linux/err.h> 14cedf8602SSascha Hauer #include <linux/device.h> 15cedf8602SSascha Hauer #include <linux/module.h> 16cedf8602SSascha Hauer #include <linux/slab.h> 17cedf8602SSascha Hauer #include <linux/of.h> 18cedf8602SSascha Hauer 19cedf8602SSascha Hauer #include <linux/usb/phy.h> 20cedf8602SSascha Hauer 21cedf8602SSascha Hauer static LIST_HEAD(phy_list); 22cedf8602SSascha Hauer static LIST_HEAD(phy_bind_list); 23cedf8602SSascha Hauer static DEFINE_SPINLOCK(phy_lock); 24cedf8602SSascha Hauer 25cedf8602SSascha Hauer static struct usb_phy *__usb_find_phy(struct list_head *list, 26cedf8602SSascha Hauer enum usb_phy_type type) 27cedf8602SSascha Hauer { 28cedf8602SSascha Hauer struct usb_phy *phy = NULL; 29cedf8602SSascha Hauer 30cedf8602SSascha Hauer list_for_each_entry(phy, list, head) { 31cedf8602SSascha Hauer if (phy->type != type) 32cedf8602SSascha Hauer continue; 33cedf8602SSascha Hauer 34cedf8602SSascha Hauer return phy; 35cedf8602SSascha Hauer } 36cedf8602SSascha Hauer 37cedf8602SSascha Hauer return ERR_PTR(-ENODEV); 38cedf8602SSascha Hauer } 39cedf8602SSascha Hauer 40cedf8602SSascha Hauer static struct usb_phy *__usb_find_phy_dev(struct device *dev, 41cedf8602SSascha Hauer struct list_head *list, u8 index) 42cedf8602SSascha Hauer { 43cedf8602SSascha Hauer struct usb_phy_bind *phy_bind = NULL; 44cedf8602SSascha Hauer 45cedf8602SSascha Hauer list_for_each_entry(phy_bind, list, list) { 46cedf8602SSascha Hauer if (!(strcmp(phy_bind->dev_name, dev_name(dev))) && 47cedf8602SSascha Hauer phy_bind->index == index) { 48cedf8602SSascha Hauer if (phy_bind->phy) 49cedf8602SSascha Hauer return phy_bind->phy; 50cedf8602SSascha Hauer else 51cedf8602SSascha Hauer return ERR_PTR(-EPROBE_DEFER); 52cedf8602SSascha Hauer } 53cedf8602SSascha Hauer } 54cedf8602SSascha Hauer 55cedf8602SSascha Hauer return ERR_PTR(-ENODEV); 56cedf8602SSascha Hauer } 57cedf8602SSascha Hauer 58cedf8602SSascha Hauer static struct usb_phy *__of_usb_find_phy(struct device_node *node) 59cedf8602SSascha Hauer { 60cedf8602SSascha Hauer struct usb_phy *phy; 61cedf8602SSascha Hauer 62cedf8602SSascha Hauer list_for_each_entry(phy, &phy_list, head) { 63cedf8602SSascha Hauer if (node != phy->dev->of_node) 64cedf8602SSascha Hauer continue; 65cedf8602SSascha Hauer 66cedf8602SSascha Hauer return phy; 67cedf8602SSascha Hauer } 68cedf8602SSascha Hauer 69cedf8602SSascha Hauer return ERR_PTR(-ENODEV); 70cedf8602SSascha Hauer } 71cedf8602SSascha Hauer 72cedf8602SSascha Hauer static void devm_usb_phy_release(struct device *dev, void *res) 73cedf8602SSascha Hauer { 74cedf8602SSascha Hauer struct usb_phy *phy = *(struct usb_phy **)res; 75cedf8602SSascha Hauer 76cedf8602SSascha Hauer usb_put_phy(phy); 77cedf8602SSascha Hauer } 78cedf8602SSascha Hauer 79cedf8602SSascha Hauer static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) 80cedf8602SSascha Hauer { 81cedf8602SSascha Hauer return res == match_data; 82cedf8602SSascha Hauer } 83cedf8602SSascha Hauer 84cedf8602SSascha Hauer /** 85cedf8602SSascha Hauer * devm_usb_get_phy - find the USB PHY 86cedf8602SSascha Hauer * @dev - device that requests this phy 87cedf8602SSascha Hauer * @type - the type of the phy the controller requires 88cedf8602SSascha Hauer * 89cedf8602SSascha Hauer * Gets the phy using usb_get_phy(), and associates a device with it using 90cedf8602SSascha Hauer * devres. On driver detach, release function is invoked on the devres data, 91cedf8602SSascha Hauer * then, devres data is freed. 92cedf8602SSascha Hauer * 93cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 94cedf8602SSascha Hauer */ 95cedf8602SSascha Hauer struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) 96cedf8602SSascha Hauer { 97cedf8602SSascha Hauer struct usb_phy **ptr, *phy; 98cedf8602SSascha Hauer 99cedf8602SSascha Hauer ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); 100cedf8602SSascha Hauer if (!ptr) 1017f4d1e7bSGabor Juhos return ERR_PTR(-ENOMEM); 102cedf8602SSascha Hauer 103cedf8602SSascha Hauer phy = usb_get_phy(type); 104cedf8602SSascha Hauer if (!IS_ERR(phy)) { 105cedf8602SSascha Hauer *ptr = phy; 106cedf8602SSascha Hauer devres_add(dev, ptr); 107cedf8602SSascha Hauer } else 108cedf8602SSascha Hauer devres_free(ptr); 109cedf8602SSascha Hauer 110cedf8602SSascha Hauer return phy; 111cedf8602SSascha Hauer } 112110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(devm_usb_get_phy); 113cedf8602SSascha Hauer 114cedf8602SSascha Hauer /** 115cedf8602SSascha Hauer * usb_get_phy - find the USB PHY 116cedf8602SSascha Hauer * @type - the type of the phy the controller requires 117cedf8602SSascha Hauer * 118cedf8602SSascha Hauer * Returns the phy driver, after getting a refcount to it; or 119cedf8602SSascha Hauer * -ENODEV if there is no such phy. The caller is responsible for 120cedf8602SSascha Hauer * calling usb_put_phy() to release that count. 121cedf8602SSascha Hauer * 122cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 123cedf8602SSascha Hauer */ 124cedf8602SSascha Hauer struct usb_phy *usb_get_phy(enum usb_phy_type type) 125cedf8602SSascha Hauer { 126cedf8602SSascha Hauer struct usb_phy *phy = NULL; 127cedf8602SSascha Hauer unsigned long flags; 128cedf8602SSascha Hauer 129cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 130cedf8602SSascha Hauer 131cedf8602SSascha Hauer phy = __usb_find_phy(&phy_list, type); 132cedf8602SSascha Hauer if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { 133e9d123a5SJosh Boyer pr_debug("PHY: unable to find transceiver of type %s\n", 134cedf8602SSascha Hauer usb_phy_type_string(type)); 1359dc9cb0cSMathias Krause if (!IS_ERR(phy)) 1369dc9cb0cSMathias Krause phy = ERR_PTR(-ENODEV); 1379dc9cb0cSMathias Krause 138cedf8602SSascha Hauer goto err0; 139cedf8602SSascha Hauer } 140cedf8602SSascha Hauer 141cedf8602SSascha Hauer get_device(phy->dev); 142cedf8602SSascha Hauer 143cedf8602SSascha Hauer err0: 144cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 145cedf8602SSascha Hauer 146cedf8602SSascha Hauer return phy; 147cedf8602SSascha Hauer } 148110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(usb_get_phy); 149cedf8602SSascha Hauer 150cedf8602SSascha Hauer /** 151cedf8602SSascha Hauer * devm_usb_get_phy_by_phandle - find the USB PHY by phandle 152cedf8602SSascha Hauer * @dev - device that requests this phy 153cedf8602SSascha Hauer * @phandle - name of the property holding the phy phandle value 154cedf8602SSascha Hauer * @index - the index of the phy 155cedf8602SSascha Hauer * 156cedf8602SSascha Hauer * Returns the phy driver associated with the given phandle value, 157cedf8602SSascha Hauer * after getting a refcount to it, -ENODEV if there is no such phy or 158cedf8602SSascha Hauer * -EPROBE_DEFER if there is a phandle to the phy, but the device is 159cedf8602SSascha Hauer * not yet loaded. While at that, it also associates the device with 160cedf8602SSascha Hauer * the phy using devres. On driver detach, release function is invoked 161cedf8602SSascha Hauer * on the devres data, then, devres data is freed. 162cedf8602SSascha Hauer * 163cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 164cedf8602SSascha Hauer */ 165cedf8602SSascha Hauer struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, 166cedf8602SSascha Hauer const char *phandle, u8 index) 167cedf8602SSascha Hauer { 168cedf8602SSascha Hauer struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr; 169cedf8602SSascha Hauer unsigned long flags; 170cedf8602SSascha Hauer struct device_node *node; 171cedf8602SSascha Hauer 172cedf8602SSascha Hauer if (!dev->of_node) { 173cedf8602SSascha Hauer dev_dbg(dev, "device does not have a device node entry\n"); 174cedf8602SSascha Hauer return ERR_PTR(-EINVAL); 175cedf8602SSascha Hauer } 176cedf8602SSascha Hauer 177cedf8602SSascha Hauer node = of_parse_phandle(dev->of_node, phandle, index); 178cedf8602SSascha Hauer if (!node) { 179cedf8602SSascha Hauer dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, 180cedf8602SSascha Hauer dev->of_node->full_name); 181cedf8602SSascha Hauer return ERR_PTR(-ENODEV); 182cedf8602SSascha Hauer } 183cedf8602SSascha Hauer 184cedf8602SSascha Hauer ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); 185cedf8602SSascha Hauer if (!ptr) { 186cedf8602SSascha Hauer dev_dbg(dev, "failed to allocate memory for devres\n"); 187cedf8602SSascha Hauer goto err0; 188cedf8602SSascha Hauer } 189cedf8602SSascha Hauer 190cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 191cedf8602SSascha Hauer 192cedf8602SSascha Hauer phy = __of_usb_find_phy(node); 193cedf8602SSascha Hauer if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { 1941290a958SArjun Sreedharan if (!IS_ERR(phy)) 195cedf8602SSascha Hauer phy = ERR_PTR(-EPROBE_DEFER); 1961290a958SArjun Sreedharan 197cedf8602SSascha Hauer devres_free(ptr); 198cedf8602SSascha Hauer goto err1; 199cedf8602SSascha Hauer } 200cedf8602SSascha Hauer 201cedf8602SSascha Hauer *ptr = phy; 202cedf8602SSascha Hauer devres_add(dev, ptr); 203cedf8602SSascha Hauer 204cedf8602SSascha Hauer get_device(phy->dev); 205cedf8602SSascha Hauer 206cedf8602SSascha Hauer err1: 207cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 208cedf8602SSascha Hauer 209cedf8602SSascha Hauer err0: 210cedf8602SSascha Hauer of_node_put(node); 211cedf8602SSascha Hauer 212cedf8602SSascha Hauer return phy; 213cedf8602SSascha Hauer } 214110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_phandle); 215cedf8602SSascha Hauer 216cedf8602SSascha Hauer /** 217cedf8602SSascha Hauer * usb_get_phy_dev - find the USB PHY 218cedf8602SSascha Hauer * @dev - device that requests this phy 219cedf8602SSascha Hauer * @index - the index of the phy 220cedf8602SSascha Hauer * 221cedf8602SSascha Hauer * Returns the phy driver, after getting a refcount to it; or 222cedf8602SSascha Hauer * -ENODEV if there is no such phy. The caller is responsible for 223cedf8602SSascha Hauer * calling usb_put_phy() to release that count. 224cedf8602SSascha Hauer * 225cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 226cedf8602SSascha Hauer */ 227cedf8602SSascha Hauer struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) 228cedf8602SSascha Hauer { 229cedf8602SSascha Hauer struct usb_phy *phy = NULL; 230cedf8602SSascha Hauer unsigned long flags; 231cedf8602SSascha Hauer 232cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 233cedf8602SSascha Hauer 234cedf8602SSascha Hauer phy = __usb_find_phy_dev(dev, &phy_bind_list, index); 235cedf8602SSascha Hauer if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { 236e9d123a5SJosh Boyer dev_dbg(dev, "unable to find transceiver\n"); 2372c4e3dbfSArjun Sreedharan if (!IS_ERR(phy)) 2382c4e3dbfSArjun Sreedharan phy = ERR_PTR(-ENODEV); 2392c4e3dbfSArjun Sreedharan 240cedf8602SSascha Hauer goto err0; 241cedf8602SSascha Hauer } 242cedf8602SSascha Hauer 243cedf8602SSascha Hauer get_device(phy->dev); 244cedf8602SSascha Hauer 245cedf8602SSascha Hauer err0: 246cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 247cedf8602SSascha Hauer 248cedf8602SSascha Hauer return phy; 249cedf8602SSascha Hauer } 250110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(usb_get_phy_dev); 251cedf8602SSascha Hauer 252cedf8602SSascha Hauer /** 253cedf8602SSascha Hauer * devm_usb_get_phy_dev - find the USB PHY using device ptr and index 254cedf8602SSascha Hauer * @dev - device that requests this phy 255cedf8602SSascha Hauer * @index - the index of the phy 256cedf8602SSascha Hauer * 257cedf8602SSascha Hauer * Gets the phy using usb_get_phy_dev(), and associates a device with it using 258cedf8602SSascha Hauer * devres. On driver detach, release function is invoked on the devres data, 259cedf8602SSascha Hauer * then, devres data is freed. 260cedf8602SSascha Hauer * 261cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 262cedf8602SSascha Hauer */ 263cedf8602SSascha Hauer struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) 264cedf8602SSascha Hauer { 265cedf8602SSascha Hauer struct usb_phy **ptr, *phy; 266cedf8602SSascha Hauer 267cedf8602SSascha Hauer ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); 268cedf8602SSascha Hauer if (!ptr) 269cedf8602SSascha Hauer return NULL; 270cedf8602SSascha Hauer 271cedf8602SSascha Hauer phy = usb_get_phy_dev(dev, index); 272cedf8602SSascha Hauer if (!IS_ERR(phy)) { 273cedf8602SSascha Hauer *ptr = phy; 274cedf8602SSascha Hauer devres_add(dev, ptr); 275cedf8602SSascha Hauer } else 276cedf8602SSascha Hauer devres_free(ptr); 277cedf8602SSascha Hauer 278cedf8602SSascha Hauer return phy; 279cedf8602SSascha Hauer } 280110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(devm_usb_get_phy_dev); 281cedf8602SSascha Hauer 282cedf8602SSascha Hauer /** 283cedf8602SSascha Hauer * devm_usb_put_phy - release the USB PHY 284cedf8602SSascha Hauer * @dev - device that wants to release this phy 285cedf8602SSascha Hauer * @phy - the phy returned by devm_usb_get_phy() 286cedf8602SSascha Hauer * 287cedf8602SSascha Hauer * destroys the devres associated with this phy and invokes usb_put_phy 288cedf8602SSascha Hauer * to release the phy. 289cedf8602SSascha Hauer * 290cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 291cedf8602SSascha Hauer */ 292cedf8602SSascha Hauer void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) 293cedf8602SSascha Hauer { 294cedf8602SSascha Hauer int r; 295cedf8602SSascha Hauer 296cedf8602SSascha Hauer r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); 297cedf8602SSascha Hauer dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); 298cedf8602SSascha Hauer } 299110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(devm_usb_put_phy); 300cedf8602SSascha Hauer 301cedf8602SSascha Hauer /** 302cedf8602SSascha Hauer * usb_put_phy - release the USB PHY 303cedf8602SSascha Hauer * @x: the phy returned by usb_get_phy() 304cedf8602SSascha Hauer * 305cedf8602SSascha Hauer * Releases a refcount the caller received from usb_get_phy(). 306cedf8602SSascha Hauer * 307cedf8602SSascha Hauer * For use by USB host and peripheral drivers. 308cedf8602SSascha Hauer */ 309cedf8602SSascha Hauer void usb_put_phy(struct usb_phy *x) 310cedf8602SSascha Hauer { 311cedf8602SSascha Hauer if (x) { 312cedf8602SSascha Hauer struct module *owner = x->dev->driver->owner; 313cedf8602SSascha Hauer 314cedf8602SSascha Hauer put_device(x->dev); 315cedf8602SSascha Hauer module_put(owner); 316cedf8602SSascha Hauer } 317cedf8602SSascha Hauer } 318110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(usb_put_phy); 319cedf8602SSascha Hauer 320cedf8602SSascha Hauer /** 321cedf8602SSascha Hauer * usb_add_phy - declare the USB PHY 322cedf8602SSascha Hauer * @x: the USB phy to be used; or NULL 323cedf8602SSascha Hauer * @type - the type of this PHY 324cedf8602SSascha Hauer * 325cedf8602SSascha Hauer * This call is exclusively for use by phy drivers, which 326cedf8602SSascha Hauer * coordinate the activities of drivers for host and peripheral 327cedf8602SSascha Hauer * controllers, and in some cases for VBUS current regulation. 328cedf8602SSascha Hauer */ 329cedf8602SSascha Hauer int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) 330cedf8602SSascha Hauer { 331cedf8602SSascha Hauer int ret = 0; 332cedf8602SSascha Hauer unsigned long flags; 333cedf8602SSascha Hauer struct usb_phy *phy; 334cedf8602SSascha Hauer 335cedf8602SSascha Hauer if (x->type != USB_PHY_TYPE_UNDEFINED) { 336cedf8602SSascha Hauer dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); 337cedf8602SSascha Hauer return -EINVAL; 338cedf8602SSascha Hauer } 339cedf8602SSascha Hauer 34031e32227SNeil Zhang ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); 34131e32227SNeil Zhang 342cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 343cedf8602SSascha Hauer 344cedf8602SSascha Hauer list_for_each_entry(phy, &phy_list, head) { 345cedf8602SSascha Hauer if (phy->type == type) { 346cedf8602SSascha Hauer ret = -EBUSY; 347cedf8602SSascha Hauer dev_err(x->dev, "transceiver type %s already exists\n", 348cedf8602SSascha Hauer usb_phy_type_string(type)); 349cedf8602SSascha Hauer goto out; 350cedf8602SSascha Hauer } 351cedf8602SSascha Hauer } 352cedf8602SSascha Hauer 353cedf8602SSascha Hauer x->type = type; 354cedf8602SSascha Hauer list_add_tail(&x->head, &phy_list); 355cedf8602SSascha Hauer 356cedf8602SSascha Hauer out: 357cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 358cedf8602SSascha Hauer return ret; 359cedf8602SSascha Hauer } 360110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(usb_add_phy); 361cedf8602SSascha Hauer 362cedf8602SSascha Hauer /** 363cedf8602SSascha Hauer * usb_add_phy_dev - declare the USB PHY 364cedf8602SSascha Hauer * @x: the USB phy to be used; or NULL 365cedf8602SSascha Hauer * 366cedf8602SSascha Hauer * This call is exclusively for use by phy drivers, which 367cedf8602SSascha Hauer * coordinate the activities of drivers for host and peripheral 368cedf8602SSascha Hauer * controllers, and in some cases for VBUS current regulation. 369cedf8602SSascha Hauer */ 370cedf8602SSascha Hauer int usb_add_phy_dev(struct usb_phy *x) 371cedf8602SSascha Hauer { 372cedf8602SSascha Hauer struct usb_phy_bind *phy_bind; 373cedf8602SSascha Hauer unsigned long flags; 374cedf8602SSascha Hauer 375cedf8602SSascha Hauer if (!x->dev) { 376cedf8602SSascha Hauer dev_err(x->dev, "no device provided for PHY\n"); 377cedf8602SSascha Hauer return -EINVAL; 378cedf8602SSascha Hauer } 379cedf8602SSascha Hauer 38031e32227SNeil Zhang ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); 38131e32227SNeil Zhang 382cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 383cedf8602SSascha Hauer list_for_each_entry(phy_bind, &phy_bind_list, list) 384cedf8602SSascha Hauer if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev)))) 385cedf8602SSascha Hauer phy_bind->phy = x; 386cedf8602SSascha Hauer 387cedf8602SSascha Hauer list_add_tail(&x->head, &phy_list); 388cedf8602SSascha Hauer 389cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 390cedf8602SSascha Hauer return 0; 391cedf8602SSascha Hauer } 392110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(usb_add_phy_dev); 393cedf8602SSascha Hauer 394cedf8602SSascha Hauer /** 395cedf8602SSascha Hauer * usb_remove_phy - remove the OTG PHY 396cedf8602SSascha Hauer * @x: the USB OTG PHY to be removed; 397cedf8602SSascha Hauer * 398cedf8602SSascha Hauer * This reverts the effects of usb_add_phy 399cedf8602SSascha Hauer */ 400cedf8602SSascha Hauer void usb_remove_phy(struct usb_phy *x) 401cedf8602SSascha Hauer { 402cedf8602SSascha Hauer unsigned long flags; 403cedf8602SSascha Hauer struct usb_phy_bind *phy_bind; 404cedf8602SSascha Hauer 405cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 406cedf8602SSascha Hauer if (x) { 407cedf8602SSascha Hauer list_for_each_entry(phy_bind, &phy_bind_list, list) 408cedf8602SSascha Hauer if (phy_bind->phy == x) 409cedf8602SSascha Hauer phy_bind->phy = NULL; 410cedf8602SSascha Hauer list_del(&x->head); 411cedf8602SSascha Hauer } 412cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 413cedf8602SSascha Hauer } 414110ff6d0SFelipe Balbi EXPORT_SYMBOL_GPL(usb_remove_phy); 415cedf8602SSascha Hauer 416cedf8602SSascha Hauer /** 417cedf8602SSascha Hauer * usb_bind_phy - bind the phy and the controller that uses the phy 418cedf8602SSascha Hauer * @dev_name: the device name of the device that will bind to the phy 419cedf8602SSascha Hauer * @index: index to specify the port number 420cedf8602SSascha Hauer * @phy_dev_name: the device name of the phy 421cedf8602SSascha Hauer * 422cedf8602SSascha Hauer * Fills the phy_bind structure with the dev_name and phy_dev_name. This will 423cedf8602SSascha Hauer * be used when the phy driver registers the phy and when the controller 424cedf8602SSascha Hauer * requests this phy. 425cedf8602SSascha Hauer * 426cedf8602SSascha Hauer * To be used by platform specific initialization code. 427cedf8602SSascha Hauer */ 42819d8ceddSDenis Efremov int usb_bind_phy(const char *dev_name, u8 index, 429cedf8602SSascha Hauer const char *phy_dev_name) 430cedf8602SSascha Hauer { 431cedf8602SSascha Hauer struct usb_phy_bind *phy_bind; 432cedf8602SSascha Hauer unsigned long flags; 433cedf8602SSascha Hauer 434cedf8602SSascha Hauer phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL); 435e9d123a5SJosh Boyer if (!phy_bind) 436cedf8602SSascha Hauer return -ENOMEM; 437cedf8602SSascha Hauer 438cedf8602SSascha Hauer phy_bind->dev_name = dev_name; 439cedf8602SSascha Hauer phy_bind->phy_dev_name = phy_dev_name; 440cedf8602SSascha Hauer phy_bind->index = index; 441cedf8602SSascha Hauer 442cedf8602SSascha Hauer spin_lock_irqsave(&phy_lock, flags); 443cedf8602SSascha Hauer list_add_tail(&phy_bind->list, &phy_bind_list); 444cedf8602SSascha Hauer spin_unlock_irqrestore(&phy_lock, flags); 445cedf8602SSascha Hauer 446cedf8602SSascha Hauer return 0; 447cedf8602SSascha Hauer } 448cedf8602SSascha Hauer EXPORT_SYMBOL_GPL(usb_bind_phy); 449df9f7b31SKiran Raparthy 450df9f7b31SKiran Raparthy /** 451df9f7b31SKiran Raparthy * usb_phy_set_event - set event to phy event 452df9f7b31SKiran Raparthy * @x: the phy returned by usb_get_phy(); 453df9f7b31SKiran Raparthy * 454df9f7b31SKiran Raparthy * This sets event to phy event 455df9f7b31SKiran Raparthy */ 456df9f7b31SKiran Raparthy void usb_phy_set_event(struct usb_phy *x, unsigned long event) 457df9f7b31SKiran Raparthy { 458df9f7b31SKiran Raparthy x->last_event = event; 459df9f7b31SKiran Raparthy } 460df9f7b31SKiran Raparthy EXPORT_SYMBOL_GPL(usb_phy_set_event); 461