^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2010 ST-Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based on omap2430.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/usb/musb-ux500.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "musb_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static const struct musb_hdrc_config ux500_musb_hdrc_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .multipoint = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .dyn_fifo = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .num_eps = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) .ram_bits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct ux500_glue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct platform_device *musb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define glue_to_musb(g) platform_get_drvdata(g->musb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void ux500_musb_set_vbus(struct musb *musb, int is_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u8 devctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* HDRC controls CPEN, but beware current surges during device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * connect. They can trigger transient overcurrent conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * that must be ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (is_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* start the session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) devctl |= MUSB_DEVCTL_SESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Wait for the musb to set as A device to enable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * VBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (time_after(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) dev_err(musb->controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "configured as A device timeout");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) musb->is_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) devctl |= MUSB_DEVCTL_SESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) MUSB_HST_MODE(musb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) musb->is_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and jumping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * right to B_IDLE...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) devctl &= ~MUSB_DEVCTL_SESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MUSB_DEV_MODE(musb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Devctl values will be updated after vbus goes below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * session_valid. The time taken depends on the capacitance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * on VBUS line. The max discharge time can be upto 1 sec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * as per the spec. Typically on our platform, it is 200ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!is_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mdelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) usb_otg_state_string(musb->xceiv->otg->state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) musb_readb(musb->mregs, MUSB_DEVCTL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int musb_otg_notifications(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long event, void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct musb *musb = container_of(nb, struct musb, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) dev_dbg(musb->controller, "musb_otg_notifications %ld %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) event, usb_otg_state_string(musb->xceiv->otg->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) case UX500_MUSB_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dev_dbg(musb->controller, "ID GND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ux500_musb_set_vbus(musb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case UX500_MUSB_VBUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) dev_dbg(musb->controller, "VBUS Connect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case UX500_MUSB_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) dev_dbg(musb->controller, "VBUS Disconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (is_host_active(musb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ux500_musb_set_vbus(musb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) musb->xceiv->otg->state = OTG_STATE_B_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) dev_dbg(musb->controller, "ID float\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static irqreturn_t ux500_musb_interrupt(int irq, void *__hci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) irqreturn_t retval = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct musb *musb = __hci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) spin_lock_irqsave(&musb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (musb->int_usb || musb->int_tx || musb->int_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) retval = musb_interrupt(musb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) spin_unlock_irqrestore(&musb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int ux500_musb_init(struct musb *musb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (IS_ERR_OR_NULL(musb->xceiv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) pr_err("HS USB OTG: no transceiver configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) musb->nb.notifier_call = musb_otg_notifications;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) status = usb_register_notifier(musb->xceiv, &musb->nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) dev_dbg(musb->controller, "notification register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) musb->isr = ux500_musb_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int ux500_musb_exit(struct musb *musb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) usb_unregister_notifier(musb->xceiv, &musb->nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) usb_put_phy(musb->xceiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static const struct musb_platform_ops ux500_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .quirks = MUSB_DMA_UX500 | MUSB_INDEXED_EP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #ifdef CONFIG_USB_UX500_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .dma_init = ux500_dma_controller_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .dma_exit = ux500_dma_controller_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .init = ux500_musb_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .exit = ux500_musb_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .fifo_mode = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .set_vbus = ux500_musb_set_vbus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static struct musb_hdrc_platform_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ux500_of_probe(struct platform_device *pdev, struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct musb_hdrc_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) const char *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int strlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) mode = of_get_property(np, "dr_mode", &strlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dev_err(&pdev->dev, "No 'dr_mode' property found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (strlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!strcmp(mode, "host"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) pdata->mode = MUSB_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!strcmp(mode, "otg"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) pdata->mode = MUSB_OTG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!strcmp(mode, "peripheral"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) pdata->mode = MUSB_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int ux500_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct resource musb_resources[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct platform_device *musb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct ux500_glue *glue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pdata = ux500_of_probe(pdev, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pdev->dev.platform_data = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_err(&pdev->dev, "no pdata or device tree found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!glue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!musb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev_err(&pdev->dev, "failed to allocate musb device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) dev_err(&pdev->dev, "failed to get clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_err(&pdev->dev, "failed to enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) musb->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) musb->dev.dma_mask = &pdev->dev.coherent_dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) glue->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) glue->musb = musb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) glue->clk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pdata->platform_ops = &ux500_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) pdata->config = &ux500_musb_hdrc_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) platform_set_drvdata(pdev, glue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) memset(musb_resources, 0x00, sizeof(*musb_resources) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ARRAY_SIZE(musb_resources));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) musb_resources[0].name = pdev->resource[0].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) musb_resources[0].start = pdev->resource[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) musb_resources[0].end = pdev->resource[0].end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) musb_resources[0].flags = pdev->resource[0].flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) musb_resources[1].name = pdev->resource[1].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) musb_resources[1].start = pdev->resource[1].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) musb_resources[1].end = pdev->resource[1].end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) musb_resources[1].flags = pdev->resource[1].flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ret = platform_device_add_resources(musb, musb_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ARRAY_SIZE(musb_resources));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dev_err(&pdev->dev, "failed to add resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dev_err(&pdev->dev, "failed to add platform_data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = platform_device_add(musb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_err(&pdev->dev, "failed to register musb device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) clk_disable_unprepare(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) platform_device_put(musb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) err0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int ux500_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct ux500_glue *glue = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) platform_device_unregister(glue->musb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) clk_disable_unprepare(glue->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int ux500_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct ux500_glue *glue = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct musb *musb = glue_to_musb(glue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (musb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) usb_phy_set_suspend(musb->xceiv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) clk_disable_unprepare(glue->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int ux500_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct ux500_glue *glue = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct musb *musb = glue_to_musb(glue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ret = clk_prepare_enable(glue->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dev_err(dev, "failed to enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (musb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) usb_phy_set_suspend(musb->xceiv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static const struct of_device_id ux500_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) { .compatible = "stericsson,db8500-musb", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) MODULE_DEVICE_TABLE(of, ux500_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static struct platform_driver ux500_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .probe = ux500_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .remove = ux500_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .name = "musb-ux500",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .pm = &ux500_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .of_match_table = ux500_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) MODULE_DESCRIPTION("UX500 MUSB Glue Layer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) MODULE_AUTHOR("Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) module_platform_driver(ux500_driver);