Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: start using the control module driver

Start using the control module driver for powering on the PHY and for
writing to the mailbox instead of writing to the control module
registers on their own.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>

authored by

Kishon Vijay Abraham I and committed by
Felipe Balbi
ca784be3 01658f0f

+40 -95
+4
Documentation/devicetree/bindings/usb/omap-usb.txt
··· 3 3 OMAP MUSB GLUE 4 4 - compatible : Should be "ti,omap4-musb" or "ti,omap3-musb" 5 5 - ti,hwmods : must be "usb_otg_hs" 6 + - ti,has-mailbox : to specify that omap uses an external mailbox 7 + (in control module) to communicate with the musb core during device connect 8 + and disconnect. 6 9 - multipoint : Should be "1" indicating the musb controller supports 7 10 multipoint. This is a MUSB configuration-specific setting. 8 11 - num_eps : Specifies the number of endpoints. This is also a ··· 27 24 usb_otg_hs: usb_otg_hs@4a0ab000 { 28 25 compatible = "ti,omap4-musb"; 29 26 ti,hwmods = "usb_otg_hs"; 27 + ti,has-mailbox; 30 28 multipoint = <1>; 31 29 num_eps = <16>; 32 30 ram_bits = <12>;
+2 -5
Documentation/devicetree/bindings/usb/usb-phy.txt
··· 4 4 5 5 Required properties: 6 6 - compatible: Should be "ti,omap-usb2" 7 - - reg : Address and length of the register set for the device. Also 8 - add the address of control module dev conf register until a driver for 9 - control module is added 7 + - reg : Address and length of the register set for the device. 10 8 11 9 Optional properties: 12 10 - ctrl-module : phandle of the control module used by PHY driver to power on ··· 14 16 15 17 usb2phy@4a0ad080 { 16 18 compatible = "ti,omap-usb2"; 17 - reg = <0x4a0ad080 0x58>, 18 - <0x4a002300 0x4>; 19 + reg = <0x4a0ad080 0x58>; 19 20 ctrl-module = <&omap_control_usb>; 20 21 };
+1
drivers/usb/musb/Kconfig
··· 11 11 select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) 12 12 select TWL4030_USB if MACH_OMAP_3430SDP 13 13 select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA 14 + select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA 14 15 select USB_OTG_UTILS 15 16 help 16 17 Say Y here if your system has a dual role high speed USB
+23 -45
drivers/usb/musb/omap2430.c
··· 37 37 #include <linux/err.h> 38 38 #include <linux/delay.h> 39 39 #include <linux/usb/musb-omap.h> 40 + #include <linux/usb/omap_control_usb.h> 40 41 41 42 #include "musb_core.h" 42 43 #include "omap2430.h" ··· 47 46 struct platform_device *musb; 48 47 enum omap_musb_vbus_id_status status; 49 48 struct work_struct omap_musb_mailbox_work; 50 - u32 __iomem *control_otghs; 49 + struct device *control_otghs; 51 50 }; 52 51 #define glue_to_musb(g) platform_get_drvdata(g->musb) 53 52 54 53 struct omap2430_glue *_glue; 55 54 56 55 static struct timer_list musb_idle_timer; 57 - 58 - /** 59 - * omap4_usb_phy_mailbox - write to usb otg mailbox 60 - * @glue: struct omap2430_glue * 61 - * @val: the value to be written to the mailbox 62 - * 63 - * On detection of a device (ID pin is grounded), this API should be called 64 - * to set AVALID, VBUSVALID and ID pin is grounded. 65 - * 66 - * When OMAP is connected to a host (OMAP in device mode), this API 67 - * is called to set AVALID, VBUSVALID and ID pin in high impedance. 68 - * 69 - * XXX: This function will be removed once we have a seperate driver for 70 - * control module 71 - */ 72 - static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val) 73 - { 74 - if (glue->control_otghs) 75 - writel(val, glue->control_otghs); 76 - } 77 56 78 57 static void musb_do_idle(unsigned long _musb) 79 58 { ··· 250 269 251 270 static void omap_musb_set_mailbox(struct omap2430_glue *glue) 252 271 { 253 - u32 val; 254 272 struct musb *musb = glue_to_musb(glue); 255 273 struct device *dev = musb->controller; 256 274 struct musb_hdrc_platform_data *pdata = dev->platform_data; ··· 265 285 musb->xceiv->last_event = USB_EVENT_ID; 266 286 if (musb->gadget_driver) { 267 287 pm_runtime_get_sync(dev); 268 - val = AVALID | VBUSVALID; 269 - omap4_usb_phy_mailbox(glue, val); 288 + omap_control_usb_set_mode(glue->control_otghs, 289 + USB_MODE_HOST); 270 290 omap2430_musb_set_vbus(musb, 1); 271 291 } 272 292 break; ··· 279 299 musb->xceiv->last_event = USB_EVENT_VBUS; 280 300 if (musb->gadget_driver) 281 301 pm_runtime_get_sync(dev); 282 - val = IDDIG | AVALID | VBUSVALID; 283 - omap4_usb_phy_mailbox(glue, val); 302 + omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); 284 303 break; 285 304 286 305 case OMAP_MUSB_ID_FLOAT: ··· 296 317 if (musb->xceiv->otg->set_vbus) 297 318 otg_set_vbus(musb->xceiv->otg, 0); 298 319 } 299 - val = SESSEND | IDDIG; 300 - omap4_usb_phy_mailbox(glue, val); 320 + omap_control_usb_set_mode(glue->control_otghs, 321 + USB_MODE_DISCONNECT); 301 322 break; 302 323 default: 303 324 dev_dbg(dev, "ID float\n"); ··· 394 415 static void omap2430_musb_enable(struct musb *musb) 395 416 { 396 417 u8 devctl; 397 - u32 val; 398 418 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 399 419 struct device *dev = musb->controller; 400 420 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); ··· 403 425 switch (glue->status) { 404 426 405 427 case OMAP_MUSB_ID_GROUND: 406 - val = AVALID | VBUSVALID; 407 - omap4_usb_phy_mailbox(glue, val); 428 + omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); 408 429 if (data->interface_type != MUSB_INTERFACE_UTMI) 409 430 break; 410 431 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); ··· 422 445 break; 423 446 424 447 case OMAP_MUSB_VBUS_VALID: 425 - val = IDDIG | AVALID | VBUSVALID; 426 - omap4_usb_phy_mailbox(glue, val); 448 + omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); 427 449 break; 428 450 429 451 default: ··· 432 456 433 457 static void omap2430_musb_disable(struct musb *musb) 434 458 { 435 - u32 val; 436 459 struct device *dev = musb->controller; 437 460 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 438 461 439 - if (glue->status != OMAP_MUSB_UNKNOWN) { 440 - val = SESSEND | IDDIG; 441 - omap4_usb_phy_mailbox(glue, val); 442 - } 462 + if (glue->status != OMAP_MUSB_UNKNOWN) 463 + omap_control_usb_set_mode(glue->control_otghs, 464 + USB_MODE_DISCONNECT); 443 465 } 444 466 445 467 static int omap2430_musb_exit(struct musb *musb) ··· 472 498 struct omap2430_glue *glue; 473 499 struct device_node *np = pdev->dev.of_node; 474 500 struct musb_hdrc_config *config; 475 - struct resource *res; 476 501 int ret = -ENOMEM; 477 502 478 503 glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); ··· 493 520 glue->dev = &pdev->dev; 494 521 glue->musb = musb; 495 522 glue->status = OMAP_MUSB_UNKNOWN; 496 - 497 - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 498 - 499 - glue->control_otghs = devm_request_and_ioremap(&pdev->dev, res); 500 - if (glue->control_otghs == NULL) 501 - dev_dbg(&pdev->dev, "Failed to obtain control memory\n"); 502 523 503 524 if (np) { 504 525 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); ··· 525 558 of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); 526 559 of_property_read_u32(np, "power", (u32 *)&pdata->power); 527 560 config->multipoint = of_property_read_bool(np, "multipoint"); 561 + pdata->has_mailbox = of_property_read_bool(np, 562 + "ti,has-mailbox"); 528 563 529 564 pdata->board_data = data; 530 565 pdata->config = config; 531 566 } 532 567 568 + if (pdata->has_mailbox) { 569 + glue->control_otghs = omap_get_control_dev(); 570 + if (IS_ERR(glue->control_otghs)) { 571 + dev_vdbg(&pdev->dev, "Failed to get control device\n"); 572 + return -ENODEV; 573 + } 574 + } else { 575 + glue->control_otghs = ERR_PTR(-ENODEV); 576 + } 533 577 pdata->platform_ops = &omap2430_ops; 534 578 535 579 platform_set_drvdata(pdev, glue);
-9
drivers/usb/musb/omap2430.h
··· 49 49 #define OTG_FORCESTDBY 0x414 50 50 # define ENABLEFORCE (1 << 0) 51 51 52 - /* 53 - * Control Module bit definitions 54 - * XXX: Will be removed once we have a driver for control module. 55 - */ 56 - #define AVALID BIT(0) 57 - #define BVALID BIT(1) 58 - #define VBUSVALID BIT(2) 59 - #define SESSEND BIT(3) 60 - #define IDDIG BIT(4) 61 52 #endif /* __MUSB_OMAP243X_H__ */
+1
drivers/usb/phy/Kconfig
··· 8 8 tristate "OMAP USB2 PHY Driver" 9 9 depends on ARCH_OMAP2PLUS 10 10 select USB_OTG_UTILS 11 + select OMAP_CONTROL_USB 11 12 help 12 13 Enable this to support the transceiver that is part of SOC. This 13 14 driver takes care of all the PHY functionality apart from comparator.
+8 -33
drivers/usb/phy/omap-usb2.c
··· 27 27 #include <linux/err.h> 28 28 #include <linux/pm_runtime.h> 29 29 #include <linux/delay.h> 30 + #include <linux/usb/omap_control_usb.h> 30 31 31 32 /** 32 33 * omap_usb2_set_comparator - links the comparator present in the sytem with ··· 52 51 return 0; 53 52 } 54 53 EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); 55 - 56 - /** 57 - * omap_usb_phy_power - power on/off the phy using control module reg 58 - * @phy: struct omap_usb * 59 - * @on: 0 or 1, based on powering on or off the PHY 60 - * 61 - * XXX: Remove this function once control module driver gets merged 62 - */ 63 - static void omap_usb_phy_power(struct omap_usb *phy, int on) 64 - { 65 - u32 val; 66 - 67 - if (on) { 68 - val = readl(phy->control_dev); 69 - if (val & PHY_PD) { 70 - writel(~PHY_PD, phy->control_dev); 71 - /* XXX: add proper documentation for this delay */ 72 - mdelay(200); 73 - } 74 - } else { 75 - writel(PHY_PD, phy->control_dev); 76 - } 77 - } 78 54 79 55 static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) 80 56 { ··· 102 124 struct omap_usb *phy = phy_to_omapusb(x); 103 125 104 126 if (suspend && !phy->is_suspended) { 105 - omap_usb_phy_power(phy, 0); 127 + omap_control_usb_phy_power(phy->control_dev, 0); 106 128 pm_runtime_put_sync(phy->dev); 107 129 phy->is_suspended = 1; 108 130 } else if (!suspend && phy->is_suspended) { ··· 112 134 ret); 113 135 return ret; 114 136 } 115 - omap_usb_phy_power(phy, 1); 137 + omap_control_usb_phy_power(phy->control_dev, 1); 116 138 phy->is_suspended = 0; 117 139 } 118 140 ··· 123 145 { 124 146 struct omap_usb *phy; 125 147 struct usb_otg *otg; 126 - struct resource *res; 127 148 128 149 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 129 150 if (!phy) { ··· 143 166 phy->phy.set_suspend = omap_usb2_suspend; 144 167 phy->phy.otg = otg; 145 168 146 - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 147 - 148 - phy->control_dev = devm_request_and_ioremap(&pdev->dev, res); 149 - if (phy->control_dev == NULL) { 150 - dev_err(&pdev->dev, "Failed to obtain io memory\n"); 151 - return -ENXIO; 169 + phy->control_dev = omap_get_control_dev(); 170 + if (IS_ERR(phy->control_dev)) { 171 + dev_dbg(&pdev->dev, "Failed to get control device\n"); 172 + return -ENODEV; 152 173 } 153 174 154 175 phy->is_suspended = 1; 155 - omap_usb_phy_power(phy, 0); 176 + omap_control_usb_phy_power(phy->control_dev, 0); 156 177 157 178 otg->set_host = omap_usb_set_host; 158 179 otg->set_peripheral = omap_usb_set_peripheral;
+1 -3
include/linux/usb/omap_usb.h
··· 25 25 struct usb_phy phy; 26 26 struct phy_companion *comparator; 27 27 struct device *dev; 28 - u32 __iomem *control_dev; 28 + struct device *control_dev; 29 29 struct clk *wkupclk; 30 30 u8 is_suspended:1; 31 31 }; 32 - 33 - #define PHY_PD 0x1 34 32 35 33 #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) 36 34