static int __devinit msm_pdm_led_probe(struct platform_device *pdev) { const struct led_info *pdata = pdev->dev.platform_data; struct pdm_led_data *led; struct resource *res, *ioregion; u32 tcxo_pdm_ctl; int rc; if (!pdata) { pr_err("platform data is invalid\n"); return -EINVAL; } if (pdev->id > 2) { pr_err("pdm id is invalid\n"); return -EINVAL; } led = kzalloc(sizeof(struct pdm_led_data), GFP_KERNEL); if (!led) return -ENOMEM; rc = pm_runtime_set_active(&pdev->dev); if (rc < 0) dev_dbg(&pdev->dev, "unable to set runtime pm state\n"); pm_runtime_enable(&pdev->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { pr_err("get resource failed\n"); rc = -EINVAL; goto err_get_res; } ioregion = request_mem_region(res->start, resource_size(res), pdev->name); if (!ioregion) { pr_err("request for mem region failed\n"); rc = -ENOMEM; goto err_get_res; } led->perph_base = ioremap(res->start, resource_size(res)); if (!led->perph_base) { pr_err("ioremap failed\n"); rc = -ENOMEM; goto err_ioremap; } led->pdm_offset = ((pdev->id) + 1) * 4; tcxo_pdm_ctl = readl_relaxed(led->perph_base); tcxo_pdm_ctl |= (1 << pdev->id); writel_relaxed(tcxo_pdm_ctl, led->perph_base); msm_led_brightness_set_percent(led, 0); led->cdev.brightness_set = msm_led_brightness_set; led->cdev.name = pdata->name ? : "leds-msm-pdm"; rc = led_classdev_register(&pdev->dev, &led->cdev); if (rc) { pr_err("led class registration failed\n"); goto err_led_reg; } #ifdef CONFIG_HAS_EARLYSUSPEND led->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + LED_SUSPEND_LEVEL; led->early_suspend.suspend = msm_led_pdm_early_suspend; register_early_suspend(&led->early_suspend); #endif platform_set_drvdata(pdev, led); return 0; err_led_reg: iounmap(led->perph_base); err_ioremap: release_mem_region(res->start, resource_size(res)); err_get_res: pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); kfree(led); return rc; }
static int sh_mobile_i2c_probe(struct platform_device *dev) { struct i2c_sh_mobile_platform_data *pdata = dev_get_platdata(&dev->dev); struct sh_mobile_i2c_data *pd; struct i2c_adapter *adap; struct resource *res; int ret; u32 bus_speed; pd = devm_kzalloc(&dev->dev, sizeof(struct sh_mobile_i2c_data), GFP_KERNEL); if (!pd) return -ENOMEM; pd->clk = devm_clk_get(&dev->dev, NULL); if (IS_ERR(pd->clk)) { dev_err(&dev->dev, "cannot get clock\n"); return PTR_ERR(pd->clk); } ret = sh_mobile_i2c_hook_irqs(dev); if (ret) return ret; pd->dev = &dev->dev; platform_set_drvdata(dev, pd); res = platform_get_resource(dev, IORESOURCE_MEM, 0); pd->reg = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(pd->reg)) return PTR_ERR(pd->reg); /* Use platform data bus speed or STANDARD_MODE */ ret = of_property_read_u32(dev->dev.of_node, "clock-frequency", &bus_speed); pd->bus_speed = ret ? STANDARD_MODE : bus_speed; pd->clks_per_count = 1; if (dev->dev.of_node) { const struct of_device_id *match; match = of_match_device(sh_mobile_i2c_dt_ids, &dev->dev); if (match) { const struct sh_mobile_dt_config *config; config = match->data; pd->clks_per_count = config->clks_per_count; } } else { if (pdata && pdata->bus_speed) pd->bus_speed = pdata->bus_speed; if (pdata && pdata->clks_per_count) pd->clks_per_count = pdata->clks_per_count; } /* The IIC blocks on SH-Mobile ARM processors * come with two new bits in ICIC. */ if (resource_size(res) > 0x17) pd->flags |= IIC_FLAG_HAS_ICIC67; ret = sh_mobile_i2c_init(pd); if (ret) return ret; /* Enable Runtime PM for this device. * * Also tell the Runtime PM core to ignore children * for this device since it is valid for us to suspend * this I2C master driver even though the slave devices * on the I2C bus may not be suspended. * * The state of the I2C hardware bus is unaffected by * the Runtime PM state. */ pm_suspend_ignore_children(&dev->dev, true); pm_runtime_enable(&dev->dev); /* setup the private data */ adap = &pd->adap; i2c_set_adapdata(adap, pd); adap->owner = THIS_MODULE; adap->algo = &sh_mobile_i2c_algorithm; adap->dev.parent = &dev->dev; adap->retries = 5; adap->nr = dev->id; adap->dev.of_node = dev->dev.of_node; strlcpy(adap->name, dev->name, sizeof(adap->name)); spin_lock_init(&pd->lock); init_waitqueue_head(&pd->wait); ret = i2c_add_numbered_adapter(adap); if (ret < 0) { dev_err(&dev->dev, "cannot add numbered adapter\n"); return ret; } dev_info(&dev->dev, "I2C adapter %d with bus speed %lu Hz (L/H=0x%x/0x%x)\n", adap->nr, pd->bus_speed, pd->iccl, pd->icch); return 0; }
static int sprd_i2c_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct sprd_i2c *i2c_dev; struct resource *res; u32 prop; int ret; pdev->id = of_alias_get_id(dev->of_node, "i2c"); i2c_dev = devm_kzalloc(dev, sizeof(struct sprd_i2c), GFP_KERNEL); if (!i2c_dev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c_dev->base = devm_ioremap_resource(dev, res); if (IS_ERR(i2c_dev->base)) return PTR_ERR(i2c_dev->base); i2c_dev->irq = platform_get_irq(pdev, 0); if (i2c_dev->irq < 0) { dev_err(&pdev->dev, "failed to get irq resource\n"); return i2c_dev->irq; } i2c_set_adapdata(&i2c_dev->adap, i2c_dev); init_completion(&i2c_dev->complete); snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name), "%s", "sprd-i2c"); i2c_dev->bus_freq = 100000; i2c_dev->adap.owner = THIS_MODULE; i2c_dev->dev = dev; i2c_dev->adap.retries = 3; i2c_dev->adap.algo = &sprd_i2c_algo; i2c_dev->adap.algo_data = i2c_dev; i2c_dev->adap.dev.parent = dev; i2c_dev->adap.nr = pdev->id; i2c_dev->adap.dev.of_node = dev->of_node; if (!of_property_read_u32(dev->of_node, "clock-frequency", &prop)) i2c_dev->bus_freq = prop; /* We only support 100k and 400k now, otherwise will return error. */ if (i2c_dev->bus_freq != 100000 && i2c_dev->bus_freq != 400000) return -EINVAL; sprd_i2c_clk_init(i2c_dev); platform_set_drvdata(pdev, i2c_dev); ret = clk_prepare_enable(i2c_dev->clk); if (ret) return ret; sprd_i2c_enable(i2c_dev); pm_runtime_set_autosuspend_delay(i2c_dev->dev, SPRD_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(i2c_dev->dev); pm_runtime_set_active(i2c_dev->dev); pm_runtime_enable(i2c_dev->dev); ret = pm_runtime_get_sync(i2c_dev->dev); if (ret < 0) goto err_rpm_put; ret = devm_request_threaded_irq(dev, i2c_dev->irq, sprd_i2c_isr, sprd_i2c_isr_thread, IRQF_NO_SUSPEND | IRQF_ONESHOT, pdev->name, i2c_dev); if (ret) { dev_err(&pdev->dev, "failed to request irq %d\n", i2c_dev->irq); goto err_rpm_put; } ret = i2c_add_numbered_adapter(&i2c_dev->adap); if (ret) { dev_err(&pdev->dev, "add adapter failed\n"); goto err_rpm_put; } pm_runtime_mark_last_busy(i2c_dev->dev); pm_runtime_put_autosuspend(i2c_dev->dev); return 0; err_rpm_put: pm_runtime_put_noidle(i2c_dev->dev); pm_runtime_disable(i2c_dev->dev); clk_disable_unprepare(i2c_dev->clk); return ret; }
static int fimg2d_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; struct fimg2d_platdata *pdata = to_fimg2d_plat(&pdev->dev); dev_info(&pdev->dev, "++%s\n", __func__); if (!to_fimg2d_plat(&pdev->dev)) { fimg2d_err("failed to get platform data\n"); return -ENOMEM; } /* global structure */ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { fimg2d_err("failed to allocate memory for controller\n"); return -ENOMEM; } /* setup global ctrl */ ret = fimg2d_setup_controller(ctrl); if (ret) { fimg2d_err("failed to setup controller\n"); goto drv_free; } ctrl->dev = &pdev->dev; /* memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { fimg2d_err("failed to get resource\n"); ret = -ENOENT; goto drv_free; } ctrl->mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!ctrl->mem) { fimg2d_err("failed to request memory region\n"); ret = -ENOMEM; goto drv_free; } /* ioremap */ ctrl->regs = ioremap(res->start, resource_size(res)); if (!ctrl->regs) { fimg2d_err("failed to ioremap for SFR\n"); ret = -ENOENT; goto mem_free; } fimg2d_debug("base address: 0x%lx\n", (unsigned long)res->start); /* irq */ ctrl->irq = platform_get_irq(pdev, 0); if (!ctrl->irq) { fimg2d_err("failed to get irq resource\n"); ret = -ENOENT; goto reg_unmap; } fimg2d_debug("irq: %d\n", ctrl->irq); ret = request_irq(ctrl->irq, fimg2d_irq, IRQF_DISABLED, pdev->name, ctrl); if (ret) { fimg2d_err("failed to request irq\n"); ret = -ENOENT; goto reg_unmap; } ret = fimg2d_clk_setup(ctrl); if (ret) { fimg2d_err("failed to setup clk\n"); ret = -ENOENT; goto irq_free; } #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(ctrl->dev); fimg2d_info("enable runtime pm\n"); #endif g2d_cci_snoop_init(pdata->ip_ver); exynos_sysmmu_set_fault_handler(ctrl->dev, fimg2d_sysmmu_fault_handler); fimg2d_debug("register sysmmu page fault handler\n"); /* misc register */ ret = misc_register(&fimg2d_dev); if (ret) { fimg2d_err("failed to register misc driver\n"); goto clk_release; } fimg2d_pm_qos_add(ctrl); dev_info(&pdev->dev, "fimg2d registered successfully\n"); return 0; clk_release: g2d_cci_snoop_remove(pdata->ip_ver); #ifdef CONFIG_PM_RUNTIME pm_runtime_disable(ctrl->dev); #else fimg2d_clk_off(ctrl); #endif fimg2d_clk_release(ctrl); irq_free: free_irq(ctrl->irq, NULL); reg_unmap: iounmap(ctrl->regs); mem_free: release_mem_region(res->start, resource_size(res)); drv_free: #ifdef BLIT_WORKQUE if (ctrl->work_q) destroy_workqueue(ctrl->work_q); #endif mutex_destroy(&ctrl->drvlock); kfree(ctrl); return ret; }
static int tvenc_probe(struct platform_device *pdev) { struct msm_fb_data_type *mfd; struct platform_device *mdp_dev = NULL; struct msm_fb_panel_data *pdata = NULL; int rc; if (pdev->id == 0) { tvenc_base = ioremap(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); if (!tvenc_base) { pr_err("tvenc_base ioremap failed!\n"); return -ENOMEM; } tvenc_pdata = pdev->dev.platform_data; tvenc_resource_initialized = 1; return 0; } if (!tvenc_resource_initialized) return -EPERM; mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) return -ENOMEM; if (tvenc_base == NULL) return -ENOMEM; mdp_dev = platform_device_alloc("mdp", pdev->id); if (!mdp_dev) return -ENOMEM; /* * link to the latest pdev */ mfd->pdev = mdp_dev; mfd->dest = DISPLAY_TV; /* * alloc panel device data */ if (platform_device_add_data (mdp_dev, pdev->dev.platform_data, sizeof(struct msm_fb_panel_data))) { pr_err("tvenc_probe: platform_device_add_data failed!\n"); platform_device_put(mdp_dev); return -ENOMEM; } /* * data chain */ pdata = mdp_dev->dev.platform_data; pdata->on = tvenc_on; pdata->off = tvenc_off; pdata->next = pdev; /* * get/set panel specific fb info */ mfd->panel_info = pdata->panel_info; #ifdef CONFIG_FB_MSM_MDP40 mfd->fb_imgType = MDP_RGB_565; /* base layer */ #else mfd->fb_imgType = MDP_YCRYCB_H2V1; #endif #ifdef CONFIG_MSM_BUS_SCALING if (!tvenc_bus_scale_handle && tvenc_pdata && tvenc_pdata->bus_scale_table) { tvenc_bus_scale_handle = msm_bus_scale_register_client( tvenc_pdata->bus_scale_table); if (!tvenc_bus_scale_handle) { printk(KERN_ERR "%s not able to get bus scale\n", __func__); } } #else mfd->ebi1_clk = clk_get(NULL, "ebi1_tv_clk"); if (IS_ERR(mfd->ebi1_clk)) { rc = PTR_ERR(mfd->ebi1_clk); goto tvenc_probe_err; } clk_set_rate(mfd->ebi1_clk, MSM_SYSTEM_BUS_RATE); #endif /* * set driver data */ platform_set_drvdata(mdp_dev, mfd); /* * register in mdp driver */ rc = platform_device_add(mdp_dev); if (rc) goto tvenc_probe_err; pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pdev_list[pdev_list_cnt++] = pdev; return 0; tvenc_probe_err: #ifdef CONFIG_MSM_BUS_SCALING if (tvenc_pdata && tvenc_pdata->bus_scale_table && tvenc_bus_scale_handle > 0) msm_bus_scale_unregister_client(tvenc_bus_scale_handle); #endif platform_device_put(mdp_dev); return rc; }
int usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) { struct usbnet *dev; struct net_device *net; struct usb_host_interface *interface; struct driver_info *info; struct usb_device *xdev; int status; const char *name; struct usb_driver *driver = to_usb_driver(udev->dev.driver); /* usbnet already took usb runtime pm, so have to enable the feature * for usb interface, otherwise usb_autopm_get_interface may return * failure if USB_SUSPEND(RUNTIME_PM) is enabled. */ if (!driver->supports_autosuspend) { driver->supports_autosuspend = 1; pm_runtime_enable(&udev->dev); } name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; if (!info) { dev_dbg (&udev->dev, "blacklisted by %s\n", name); return -ENODEV; } xdev = interface_to_usbdev (udev); interface = udev->cur_altsetting; usb_get_dev (xdev); status = -ENOMEM; // set up our own records net = alloc_etherdev(sizeof(*dev)); if (!net) { dbg ("can't kmalloc dev"); goto out; } /* netdev_printk() needs this so do it as early as possible */ SET_NETDEV_DEV(net, &udev->dev); dev = netdev_priv(net); dev->udev = xdev; dev->intf = udev; dev->driver_info = info; dev->driver_name = name; dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK); skb_queue_head_init (&dev->rxq); skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->done); skb_queue_head_init(&dev->rxq_pause); dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; INIT_WORK (&dev->kevent, kevent); init_usb_anchor(&dev->deferred); dev->delay.function = usbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); mutex_init (&dev->phy_mutex); dev->net = net; strcpy (net->name, "usb%d"); memcpy (net->dev_addr, node_id, sizeof node_id); /* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case. */ dev->hard_mtu = net->mtu + net->hard_header_len; #if 0 // dma_supported() is deeply broken on almost all architectures // possible with some EHCI controllers if (dma_supported (&udev->dev, DMA_BIT_MASK(64))) net->features |= NETIF_F_HIGHDMA; #endif net->netdev_ops = &usbnet_netdev_ops; net->watchdog_timeo = TX_TIMEOUT_JIFFIES; net->ethtool_ops = &usbnet_ethtool_ops; // allow device-specific bind/init procedures // NOTE net->name still not usable ... if (info->bind) { status = info->bind (dev, udev); if (status < 0) goto out1; // heuristic: "usb%d" for links we know are two-host, // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || (net->dev_addr [0] & 0x02) == 0)) strcpy (net->name, "eth%d"); /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) strcpy(net->name, "wlan%d"); /* WWAN devices should always be named "wwan%d" */ if ((dev->driver_info->flags & FLAG_WWAN) != 0) strcpy(net->name, "wwan%d"); /* maybe the remote can't receive an Ethernet MTU */ if (net->mtu > (dev->hard_mtu - net->hard_header_len)) net->mtu = dev->hard_mtu - net->hard_header_len; } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { dev->in = usb_rcvbulkpipe (xdev, info->in); dev->out = usb_sndbulkpipe (xdev, info->out); if (!(info->flags & FLAG_NO_SETINT)) status = usb_set_interface (xdev, interface->desc.bInterfaceNumber, interface->desc.bAlternateSetting); else status = 0; } if (status >= 0 && dev->status) status = init_status (dev, udev); if (status < 0) goto out3; if (!dev->rx_urb_size) dev->rx_urb_size = dev->hard_mtu; dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); if ((dev->driver_info->flags & FLAG_WLAN) != 0) SET_NETDEV_DEVTYPE(net, &wlan_type); if ((dev->driver_info->flags & FLAG_WWAN) != 0) SET_NETDEV_DEVTYPE(net, &wwan_type); status = register_netdev (net); if (status) goto out3; netif_info(dev, probe, dev->net, "register '%s' at usb-%s-%s, %s, %pM\n", udev->dev.driver->name, xdev->bus->bus_name, xdev->devpath, dev->driver_info->description, net->dev_addr); // ok, it's ready to go. usb_set_intfdata (udev, dev); netif_device_attach (net); if (dev->driver_info->flags & FLAG_LINK_INTR) netif_carrier_off(net); return 0; out3: if (info->unbind) info->unbind (dev, udev); out1: free_netdev(net); out: usb_put_dev(xdev); return status; }
static int __init omap_rtc_probe(struct platform_device *pdev) { struct resource *res; struct rtc_device *rtc; u8 reg, new_ctrl; const struct platform_device_id *id_entry; const struct of_device_id *of_id; of_id = of_match_device(omap_rtc_of_match, &pdev->dev); if (of_id) pdev->id_entry = of_id->data; omap_rtc_timer = platform_get_irq(pdev, 0); if (omap_rtc_timer <= 0) { pr_debug("%s: no update irq?\n", pdev->name); return -ENOENT; } omap_rtc_alarm = platform_get_irq(pdev, 1); if (omap_rtc_alarm <= 0) { pr_debug("%s: no alarm irq?\n", pdev->name); return -ENOENT; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rtc_base)) return PTR_ERR(rtc_base); /* Enable the clock/module so that we can access the registers */ pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); id_entry = platform_get_device_id(pdev); if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) { rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG); rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG); } rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &omap_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { pr_debug("%s: can't register RTC device, err %ld\n", pdev->name, PTR_ERR(rtc)); goto fail0; } platform_set_drvdata(pdev, rtc); /* clear pending irqs, and set 1/second periodic, * which we'll use instead of update irqs */ rtc_write(0, OMAP_RTC_INTERRUPTS_REG); /* clear old status */ reg = rtc_read(OMAP_RTC_STATUS_REG); if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { pr_info("%s: RTC power up reset detected\n", pdev->name); rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG); } if (reg & (u8) OMAP_RTC_STATUS_ALARM) rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); /* handle periodic and alarm irqs */ if (devm_request_irq(&pdev->dev, omap_rtc_timer, rtc_irq, 0, dev_name(&rtc->dev), rtc)) { pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_timer); goto fail0; } if ((omap_rtc_timer != omap_rtc_alarm) && (devm_request_irq(&pdev->dev, omap_rtc_alarm, rtc_irq, 0, dev_name(&rtc->dev), rtc))) { pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_alarm); goto fail0; } /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ reg = rtc_read(OMAP_RTC_CTRL_REG); if (reg & (u8) OMAP_RTC_CTRL_STOP) pr_info("%s: already running\n", pdev->name); /* force to 24 hour mode */ new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP); new_ctrl |= OMAP_RTC_CTRL_STOP; /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: * * - Device wake-up capability setting should come through chip * init logic. OMAP1 boards should initialize the "wakeup capable" * flag in the platform device if the board is wired right for * being woken up by RTC alarm. For OMAP-L138, this capability * is built into the SoC by the "Deep Sleep" capability. * * - Boards wired so RTC_ON_nOFF is used as the reset signal, * rather than nPWRON_RESET, should forcibly enable split * power mode. (Some chip errata report that RTC_CTRL_SPLIT * is write-only, and always reads as zero...) */ device_init_wakeup(&pdev->dev, true); if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) pr_info("%s: split power mode\n", pdev->name); if (reg != new_ctrl) rtc_write(new_ctrl, OMAP_RTC_CTRL_REG); return 0; fail0: if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) rtc_writel(0, OMAP_RTC_KICK0_REG); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return -EIO; }
/** * usbhs_omap_probe - initialize TI-based HCDs * * Allocates basic resources for this USB host controller. */ static int __devinit usbhs_omap_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usbhs_omap_platform_data *pdata = dev->platform_data; struct usbhs_hcd_omap *omap; struct resource *res; int ret = 0; int i; if (!pdata) { dev_err(dev, "Missing platform data\n"); ret = -ENOMEM; goto end_probe; } omap = kzalloc(sizeof(*omap), GFP_KERNEL); if (!omap) { dev_err(dev, "Memory allocation failed\n"); ret = -ENOMEM; goto end_probe; } spin_lock_init(&omap->lock); for (i = 0; i < OMAP3_HS_USB_PORTS; i++) omap->platdata.port_mode[i] = pdata->port_mode[i]; omap->platdata.ehci_data = pdata->ehci_data; omap->platdata.ohci_data = pdata->ohci_data; pm_runtime_enable(dev); omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); if (IS_ERR(omap->utmi_p1_fck)) { ret = PTR_ERR(omap->utmi_p1_fck); dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); goto err_end; } omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); if (IS_ERR(omap->xclk60mhsp1_ck)) { ret = PTR_ERR(omap->xclk60mhsp1_ck); dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); goto err_utmi_p1_fck; } omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); if (IS_ERR(omap->utmi_p2_fck)) { ret = PTR_ERR(omap->utmi_p2_fck); dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); goto err_xclk60mhsp1_ck; } omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); if (IS_ERR(omap->xclk60mhsp2_ck)) { ret = PTR_ERR(omap->xclk60mhsp2_ck); dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); goto err_utmi_p2_fck; } omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); if (IS_ERR(omap->usbhost_p1_fck)) { ret = PTR_ERR(omap->usbhost_p1_fck); dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); goto err_xclk60mhsp2_ck; } omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); if (IS_ERR(omap->usbtll_p1_fck)) { ret = PTR_ERR(omap->usbtll_p1_fck); dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); goto err_usbhost_p1_fck; } omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); if (IS_ERR(omap->usbhost_p2_fck)) { ret = PTR_ERR(omap->usbhost_p2_fck); dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); goto err_usbtll_p1_fck; } omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); if (IS_ERR(omap->usbtll_p2_fck)) { ret = PTR_ERR(omap->usbtll_p2_fck); dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); goto err_usbhost_p2_fck; } omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); if (IS_ERR(omap->init_60m_fclk)) { ret = PTR_ERR(omap->init_60m_fclk); dev_err(dev, "init_60m_fclk failed error:%d\n", ret); goto err_usbtll_p2_fck; } omap->usbhost_hs_fck = clk_get(dev, "usb_host_hs_fck"); if (IS_ERR(omap->usbhost_hs_fck)) { ret = PTR_ERR(omap->usbhost_hs_fck); dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); goto err_usbhost_hs_fck; } omap->usbhost_ick = clk_get(dev, "usbhost_ick"); if (IS_ERR(omap->usbhost_ick)) { ret = PTR_ERR(omap->usbhost_ick); dev_err(dev, "usbhost_ick failed error:%d\n", ret); goto err_usbhost_ick; } if (is_ehci_phy_mode(pdata->port_mode[0])) { /* for OMAP3 , the clk set paretn fails */ ret = clk_set_parent(omap->utmi_p1_fck, omap->xclk60mhsp1_ck); if (ret != 0) dev_err(dev, "xclk60mhsp1_ck set parent" "failed error:%d\n", ret); } else if (is_ehci_tll_mode(pdata->port_mode[0])) { ret = clk_set_parent(omap->utmi_p1_fck, omap->init_60m_fclk); if (ret != 0) dev_err(dev, "init_60m_fclk set parent" "failed error:%d\n", ret); } if (is_ehci_phy_mode(pdata->port_mode[1])) { ret = clk_set_parent(omap->utmi_p2_fck, omap->xclk60mhsp2_ck); if (ret != 0) dev_err(dev, "xclk60mhsp2_ck set parent" "failed error:%d\n", ret); } else if (is_ehci_tll_mode(pdata->port_mode[1])) { ret = clk_set_parent(omap->utmi_p2_fck, omap->init_60m_fclk); if (ret != 0) dev_err(dev, "init_60m_fclk set parent" "failed error:%d\n", ret); } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); if (!res) { dev_err(dev, "UHH EHCI get resource failed\n"); ret = -ENODEV; goto err_init_60m_fclk; } omap->uhh_base = ioremap(res->start, resource_size(res)); if (!omap->uhh_base) { dev_err(dev, "UHH ioremap failed\n"); ret = -ENOMEM; goto err_init_60m_fclk; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); if (!res) { dev_err(dev, "UHH EHCI get resource failed\n"); ret = -ENODEV; goto err_tll; } omap->tll_base = ioremap(res->start, resource_size(res)); if (!omap->tll_base) { dev_err(dev, "TLL ioremap failed\n"); ret = -ENOMEM; goto err_tll; } platform_set_drvdata(pdev, omap); ret = omap_usbhs_alloc_children(pdev); if (ret) { dev_err(dev, "omap_usbhs_alloc_children failed\n"); goto err_alloc; } omap_usbhs_init(dev); goto end_probe; err_alloc: iounmap(omap->tll_base); err_tll: iounmap(omap->uhh_base); err_usbhost_ick: clk_put(omap->usbhost_ick); err_usbhost_hs_fck: clk_put(omap->usbhost_hs_fck); err_init_60m_fclk: clk_put(omap->init_60m_fclk); err_usbtll_p2_fck: clk_put(omap->usbtll_p2_fck); err_usbhost_p2_fck: clk_put(omap->usbhost_p2_fck); err_usbtll_p1_fck: clk_put(omap->usbtll_p1_fck); err_usbhost_p1_fck: clk_put(omap->usbhost_p1_fck); err_xclk60mhsp2_ck: clk_put(omap->xclk60mhsp2_ck); err_utmi_p2_fck: clk_put(omap->utmi_p2_fck); err_xclk60mhsp1_ck: clk_put(omap->xclk60mhsp1_ck); err_utmi_p1_fck: clk_put(omap->utmi_p1_fck); err_end: pm_runtime_disable(dev); kfree(omap); end_probe: return ret; }
static void msm_hsusb_request_host(void *handle, int request) { struct msmusb_hcd *mhcd = handle; struct usb_hcd *hcd = mhcd_to_hcd(mhcd); struct msm_usb_host_platform_data *pdata = mhcd->pdata; struct msm_otg *otg = container_of(mhcd->xceiv, struct msm_otg, otg); #ifdef CONFIG_USB_OTG struct usb_device *udev = hcd->self.root_hub; #endif struct device *dev = hcd->self.controller; switch (request) { #ifdef CONFIG_USB_OTG case REQUEST_HNP_SUSPEND: /* disable Root hub auto suspend. As hardware is configured * for peripheral mode, mark hardware is not available. */ if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) { pm_runtime_disable(&udev->dev); /* Mark root hub as disconnected. This would * protect suspend/resume via sysfs. */ udev->state = USB_STATE_NOTATTACHED; clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); hcd->state = HC_STATE_HALT; pm_runtime_put_noidle(dev); pm_runtime_suspend(dev); } break; case REQUEST_HNP_RESUME: if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) { pm_runtime_get_noresume(dev); pm_runtime_resume(dev); disable_irq(hcd->irq); ehci_msm_reset(hcd); ehci_msm_run(hcd); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); pm_runtime_enable(&udev->dev); udev->state = USB_STATE_CONFIGURED; enable_irq(hcd->irq); } break; #endif case REQUEST_RESUME: usb_hcd_resume_root_hub(hcd); break; case REQUEST_START: if (mhcd->running) break; pm_runtime_get_noresume(dev); pm_runtime_resume(dev); wake_lock(&mhcd->wlock); msm_xusb_pm_qos_update(mhcd, 1); msm_xusb_enable_clks(mhcd); if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) if (otg->set_clk) otg->set_clk(mhcd->xceiv, 1); if (pdata->vbus_power) pdata->vbus_power(pdata->phy_info, 1); if (pdata->config_gpio) pdata->config_gpio(1); usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); mhcd->running = 1; if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) if (otg->set_clk) otg->set_clk(mhcd->xceiv, 0); break; case REQUEST_STOP: if (!mhcd->running) break; mhcd->running = 0; /* come out of lpm before deregistration */ if (PHY_TYPE(pdata->phy_info) == USB_PHY_SERIAL_PMIC) { usb_lpm_exit(hcd); if (cancel_work_sync(&(mhcd->lpm_exit_work))) usb_lpm_exit_w(&mhcd->lpm_exit_work); } usb_remove_hcd(hcd); if (pdata->config_gpio) pdata->config_gpio(0); if (pdata->vbus_power) pdata->vbus_power(pdata->phy_info, 0); msm_xusb_disable_clks(mhcd); wake_lock_timeout(&mhcd->wlock, HZ/2); msm_xusb_pm_qos_update(mhcd, 0); pm_runtime_put_noidle(dev); pm_runtime_suspend(dev); break; } }
static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; struct msm_hsic_hcd *mehci; struct msm_hsic_host_platform_data *pdata; int ret; int is_pbl = 0; int log2_itc = 0; dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n"); /* After parent device's probe is executed, it will be put in suspend * mode. When child device's probe is called, driver core is not * resuming parent device due to which parent will be in suspend even * though child is active. Hence resume the parent device explicitly. */ if (pdev->dev.parent) pm_runtime_get_sync(pdev->dev.parent); hcd = usb_create_hcd(&msm_hsic_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } mehci = hcd_to_hsic(hcd); mehci->dev = &pdev->dev; pdata = mehci->dev->platform_data; mehci->ehci.susp_sof_bug = 1; mehci->ehci.reset_sof_bug = 1; mehci->ehci.resume_sof_bug = 1; res = platform_get_resource_byname(pdev, IORESOURCE_IO, "MDM2AP_PBLRDY"); if (res) { dev_dbg(mehci->dev, "pblrdy: %d\n", res->start); is_pbl = gpio_get_value(res->start); } res = platform_get_resource_byname(pdev, IORESOURCE_IO, "ITC"); if (res) { dev_dbg(mehci->dev, "log2_itc: %d\n", res->start); log2_itc = is_pbl ? 0 : res->start; } mehci->ehci.log2_irq_thresh = log2_itc; res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "peripheral_status_irq"); if (res) mehci->peripheral_status_irq = res->start; res = platform_get_resource_byname(pdev, IORESOURCE_IO, "wakeup"); if (res) { mehci->wakeup_gpio = res->start; mehci->wakeup_irq = MSM_GPIO_TO_INT(res->start); dev_dbg(mehci->dev, "wakeup_irq: %d\n", mehci->wakeup_irq); } ret = msm_hsic_init_clocks(mehci, 1); if (ret) { dev_err(&pdev->dev, "unable to initialize clocks\n"); ret = -ENODEV; goto unmap; } ret = msm_hsic_init_vddcx(mehci, 1); if (ret) { dev_err(&pdev->dev, "unable to initialize VDDCX\n"); ret = -ENODEV; goto deinit_clocks; } init_completion(&mehci->rt_completion); init_completion(&mehci->gpt0_completion); ret = msm_hsic_reset(mehci); if (ret) { dev_err(&pdev->dev, "unable to initialize PHY\n"); goto deinit_vddcx; } ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); if (ret) { dev_err(&pdev->dev, "unable to register HCD\n"); goto unconfig_gpio; } device_init_wakeup(&pdev->dev, 1); wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev)); wake_lock(&mehci->wlock); if (mehci->peripheral_status_irq) { ret = request_threaded_irq(mehci->peripheral_status_irq, NULL, hsic_peripheral_status_change, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, "hsic_peripheral_status", mehci); if (ret) dev_err(&pdev->dev, "%s:request_irq:%d failed:%d", __func__, mehci->peripheral_status_irq, ret); } /* configure wakeup irq */ if (mehci->wakeup_irq) { ret = request_irq(mehci->wakeup_irq, msm_hsic_wakeup_irq, IRQF_TRIGGER_HIGH, "msm_hsic_wakeup", mehci); if (!ret) { disable_irq_nosync(mehci->wakeup_irq); } else { dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", mehci->wakeup_irq, ret); mehci->wakeup_irq = 0; } } ret = ehci_hsic_msm_debugfs_init(mehci); if (ret) dev_dbg(&pdev->dev, "mode debugfs file is" "not available\n"); if (pdata && pdata->bus_scale_table) { mehci->bus_perf_client = msm_bus_scale_register_client(pdata->bus_scale_table); /* Configure BUS performance parameters for MAX bandwidth */ if (mehci->bus_perf_client) { ret = msm_bus_scale_client_update_request( mehci->bus_perf_client, 1); if (ret) dev_err(&pdev->dev, "%s: Failed to vote for " "bus bandwidth %d\n", __func__, ret); } else { dev_err(&pdev->dev, "%s: Failed to register BUS " "scaling client!!\n", __func__); } } __mehci = mehci; if (pdata && pdata->swfi_latency) pm_qos_add_request(&mehci->pm_qos_req_dma, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); /* * This pdev->dev is assigned parent of root-hub by USB core, * hence, runtime framework automatically calls this driver's * runtime APIs based on root-hub's state. */ pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); /* Decrement the parent device's counter after probe. * As child is active, parent will not be put into * suspend mode. */ if (pdev->dev.parent) pm_runtime_put_sync(pdev->dev.parent); return 0; unconfig_gpio: msm_hsic_config_gpios(mehci, 0); deinit_vddcx: msm_hsic_init_vddcx(mehci, 0); deinit_clocks: msm_hsic_init_clocks(mehci, 0); unmap: iounmap(hcd->regs); put_hcd: usb_put_hcd(hcd); return ret; }
static int __devinit cyttsp4_i2c_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { struct cyttsp4_i2c *ts_i2c; struct device *dev = &client->dev; char const *adap_id = dev_get_platdata(dev); char const *id; int rc; dev_info(dev, "%s: Starting %s probe...\n", __func__, CYTTSP4_I2C_NAME); dev_dbg(dev, "%s: debug on\n", __func__); dev_vdbg(dev, "%s: verbose debug on\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(dev, "%s: fail check I2C functionality\n", __func__); rc = -EIO; goto error_alloc_data_failed; } ts_i2c = kzalloc(sizeof(struct cyttsp4_i2c), GFP_KERNEL); if (ts_i2c == NULL) { dev_err(dev, "%s: Error, kzalloc.\n", __func__); rc = -ENOMEM; goto error_alloc_data_failed; } mutex_init(&ts_i2c->lock); ts_i2c->client = client; client->dev.bus = &i2c_bus_type; i2c_set_clientdata(client, ts_i2c); dev_set_drvdata(&client->dev, ts_i2c); if (adap_id) id = adap_id; else id = CYTTSP4_I2C_NAME; dev_dbg(dev, "%s: add adap='%s' (CYTTSP4_I2C_NAME=%s)\n", __func__, id, CYTTSP4_I2C_NAME); pm_runtime_enable(&client->dev); rc = cyttsp4_add_adapter(id, &ops, dev); if (rc) { dev_err(dev, "%s: Error on probe %s\n", __func__, CYTTSP4_I2C_NAME); goto add_adapter_err; } dev_info(dev, "%s: Successful probe %s\n", __func__, CYTTSP4_I2C_NAME); return 0; add_adapter_err: pm_runtime_disable(&client->dev); dev_set_drvdata(&client->dev, NULL); i2c_set_clientdata(client, NULL); kfree(ts_i2c); error_alloc_data_failed: return rc; }
/* * Initialise the accelerometer and the various subsystems. * Should be rather independent of the bus system. */ int lis3lv02d_init_device(struct lis3lv02d *dev) { int err; irq_handler_t thread_fn; int irq_flags = 0; dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); switch (dev->whoami) { case WAI_12B: pr_info("12 bits sensor found\n"); dev->read_data = lis3lv02d_read_12; dev->mdps_max_val = 2048; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; dev->odrs = lis3_12_rates; dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; dev->scale = LIS3_SENSITIVITY_12B; dev->regs = lis3_wai12_regs; dev->regs_size = ARRAY_SIZE(lis3_wai12_regs); break; case WAI_8B: pr_info("8 bits sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; dev->odrs = lis3_8_rates; dev->odr_mask = CTRL1_DR; dev->scale = LIS3_SENSITIVITY_8B; dev->regs = lis3_wai8_regs; dev->regs_size = ARRAY_SIZE(lis3_wai8_regs); break; case WAI_3DC: pr_info("8 bits 3DC sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; dev->odrs = lis3_3dc_rates; dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; dev->scale = LIS3_SENSITIVITY_8B; break; default: pr_err("unknown sensor type 0x%X\n", dev->whoami); return -EINVAL; } dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), sizeof(lis3_wai12_regs)), GFP_KERNEL); if (dev->reg_cache == NULL) { printk(KERN_ERR DRIVER_NAME "out of memory\n"); return -ENOMEM; } mutex_init(&dev->mutex); atomic_set(&dev->wake_thread, 0); lis3lv02d_add_fs(dev); lis3lv02d_poweron(dev); if (dev->pm_dev) { pm_runtime_set_active(dev->pm_dev); pm_runtime_enable(dev->pm_dev); } if (lis3lv02d_joystick_enable()) pr_err("joystick initialization failed\n"); /* passing in platform specific data is purely optional and only * used by the SPI transport layer at the moment */ if (dev->pdata) { struct lis3lv02d_platform_data *p = dev->pdata; if (dev->whoami == WAI_8B) lis3lv02d_8b_configure(dev, p); irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; dev->irq_cfg = p->irq_cfg; if (p->irq_cfg) dev->write(dev, CTRL_REG3, p->irq_cfg); if (p->default_rate) lis3lv02d_set_odr(p->default_rate); } /* bail if we did not get an IRQ from the bus layer */ if (!dev->irq) { pr_debug("No IRQ. Disabling /dev/freefall\n"); goto out; } /* * The sensor can generate interrupts for free-fall and direction * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep * the things simple and _fast_ we activate it only for free-fall, so * no need to read register (very slow with ACPI). For the same reason, * we forbid shared interrupts. * * IRQF_TRIGGER_RISING seems pointless on HP laptops because the * io-apic is not configurable (and generates a warning) but I keep it * in case of support for other hardware. */ if (dev->pdata && dev->whoami == WAI_8B) thread_fn = lis302dl_interrupt_thread1_8b; else thread_fn = NULL; err = request_threaded_irq(dev->irq, lis302dl_interrupt, thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT | irq_flags, DRIVER_NAME, &lis3_dev); if (err < 0) { pr_err("Cannot get IRQ\n"); goto out; } if (misc_register(&lis3lv02d_misc_device)) pr_err("misc_register failed\n"); out: return 0; }
static int fimc_is_probe(struct platform_device *pdev) { struct exynos_platform_fimc_is *pdata; #if defined (ENABLE_IS_CORE) || defined (USE_MCUCTL) struct resource *mem_res; struct resource *regs_res; #endif struct fimc_is_core *core; int ret = -ENODEV; #ifndef ENABLE_IS_CORE int i; #endif u32 stream; struct pinctrl_state *s; probe_info("%s:start(%ld, %ld)\n", __func__, sizeof(struct fimc_is_core), sizeof(struct fimc_is_video_ctx)); core = kzalloc(sizeof(struct fimc_is_core), GFP_KERNEL); if (!core) { probe_err("core is NULL"); return -ENOMEM; } fimc_is_dev = &pdev->dev; dev_set_drvdata(fimc_is_dev, core); pdata = dev_get_platdata(&pdev->dev); if (!pdata) { #ifdef CONFIG_OF ret = fimc_is_parse_dt(pdev); if (ret) { err("fimc_is_parse_dt is fail(%d)", ret); return ret; } pdata = dev_get_platdata(&pdev->dev); #else BUG(); #endif } #ifdef USE_ION_ALLOC core->fimc_ion_client = ion_client_create(ion_exynos, "fimc-is"); #endif core->pdev = pdev; core->pdata = pdata; core->current_position = SENSOR_POSITION_REAR; device_init_wakeup(&pdev->dev, true); /* for mideaserver force down */ atomic_set(&core->rsccount, 0); #if defined (ENABLE_IS_CORE) || defined (USE_MCUCTL) mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { probe_err("Failed to get io memory region(%p)", mem_res); goto p_err1; } regs_res = request_mem_region(mem_res->start, resource_size(mem_res), pdev->name); if (!regs_res) { probe_err("Failed to request io memory region(%p)", regs_res); goto p_err1; } core->regs_res = regs_res; core->regs = ioremap_nocache(mem_res->start, resource_size(mem_res)); if (!core->regs) { probe_err("Failed to remap io region(%p)", core->regs); goto p_err2; } #else core->regs_res = NULL; core->regs = NULL; #endif #ifdef ENABLE_IS_CORE core->irq = platform_get_irq(pdev, 0); if (core->irq < 0) { probe_err("Failed to get irq(%d)", core->irq); goto p_err3; } #endif ret = pdata->clk_get(&pdev->dev); if (ret) { probe_err("clk_get is fail(%d)", ret); goto p_err3; } ret = fimc_is_mem_probe(&core->resourcemgr.mem, core->pdev); if (ret) { probe_err("fimc_is_mem_probe is fail(%d)", ret); goto p_err3; } ret = fimc_is_resourcemgr_probe(&core->resourcemgr, core); if (ret) { probe_err("fimc_is_resourcemgr_probe is fail(%d)", ret); goto p_err3; } ret = fimc_is_interface_probe(&core->interface, &core->resourcemgr.minfo, (ulong)core->regs, core->irq, core); if (ret) { probe_err("fimc_is_interface_probe is fail(%d)", ret); goto p_err3; } ret = fimc_is_debug_probe(); if (ret) { probe_err("fimc_is_deubg_probe is fail(%d)", ret); goto p_err3; } ret = fimc_is_vender_probe(&core->vender); if (ret) { probe_err("fimc_is_vender_probe is fail(%d)", ret); goto p_err3; } /* group initialization */ ret = fimc_is_groupmgr_probe(&core->groupmgr); if (ret) { probe_err("fimc_is_groupmgr_probe is fail(%d)", ret); goto p_err3; } for (stream = 0; stream < FIMC_IS_STREAM_COUNT; ++stream) { ret = fimc_is_ischain_probe(&core->ischain[stream], &core->interface, &core->resourcemgr, &core->groupmgr, &core->resourcemgr.mem, core->pdev, stream); if (ret) { probe_err("fimc_is_ischain_probe(%d) is fail(%d)", stream, ret); goto p_err3; } #ifndef ENABLE_IS_CORE core->ischain[stream].hardware = &core->hardware; #endif } ret = v4l2_device_register(&pdev->dev, &core->v4l2_dev); if (ret) { dev_err(&pdev->dev, "failed to register fimc-is v4l2 device\n"); goto p_err3; } #ifdef SOC_30S /* video entity - 3a0 */ fimc_is_30s_video_probe(core); #endif #ifdef SOC_30C /* video entity - 3a0 capture */ fimc_is_30c_video_probe(core); #endif #ifdef SOC_30P /* video entity - 3a0 preview */ fimc_is_30p_video_probe(core); #endif #ifdef SOC_31S /* video entity - 3a1 */ fimc_is_31s_video_probe(core); #endif #ifdef SOC_31C /* video entity - 3a1 capture */ fimc_is_31c_video_probe(core); #endif #ifdef SOC_31P /* video entity - 3a1 preview */ fimc_is_31p_video_probe(core); #endif #ifdef SOC_I0S /* video entity - isp0 */ fimc_is_i0s_video_probe(core); #endif #ifdef SOC_I0C /* video entity - isp0 capture */ fimc_is_i0c_video_probe(core); #endif #ifdef SOC_I0P /* video entity - isp0 preview */ fimc_is_i0p_video_probe(core); #endif #ifdef SOC_I1S /* video entity - isp1 */ fimc_is_i1s_video_probe(core); #endif #ifdef SOC_I1C /* video entity - isp1 capture */ fimc_is_i1c_video_probe(core); #endif #ifdef SOC_I1P /* video entity - isp1 preview */ fimc_is_i1p_video_probe(core); #endif #ifdef SOC_DIS /* video entity - dis */ fimc_is_dis_video_probe(core); #endif #ifdef SOC_SCC /* video entity - scc */ fimc_is_scc_video_probe(core); #endif #ifdef SOC_SCP /* video entity - scp */ fimc_is_scp_video_probe(core); #endif #ifdef SOC_MCS /* video entity - scp */ fimc_is_m0s_video_probe(core); fimc_is_m1s_video_probe(core); fimc_is_m0p_video_probe(core); fimc_is_m1p_video_probe(core); fimc_is_m2p_video_probe(core); fimc_is_m3p_video_probe(core); fimc_is_m4p_video_probe(core); #endif platform_set_drvdata(pdev, core); #ifndef ENABLE_IS_CORE ret = fimc_is_interface_ischain_probe(&core->interface_ischain, &core->hardware, &core->resourcemgr, core->pdev, (ulong)core->regs); if (ret) { dev_err(&pdev->dev, "interface_ischain_probe fail\n"); goto p_err1; } ret = fimc_is_hardware_probe(&core->hardware, &core->interface, &core->interface_ischain); if (ret) { dev_err(&pdev->dev, "hardware_probe fail\n"); goto p_err1; } /* set sysfs for set position to actuator */ sysfs_actuator.init_step = 0; for (i = 0; i < INIT_MAX_SETTING; i++) { sysfs_actuator.init_positions[i] = -1; sysfs_actuator.init_delays[i] = -1; } #endif #if defined(CONFIG_SOC_EXYNOS5430) || defined(CONFIG_SOC_EXYNOS5433) #if defined(CONFIG_VIDEOBUF2_ION) if (core->resourcemgr.mem.alloc_ctx) vb2_ion_attach_iommu(core->resourcemgr.mem.alloc_ctx); #endif #endif EXYNOS_MIF_ADD_NOTIFIER(&exynos_fimc_is_mif_throttling_nb); #if defined(CONFIG_PM_RUNTIME) pm_runtime_enable(&pdev->dev); #endif #ifdef ENABLE_FAULT_HANDLER #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) exynos_sysmmu_set_fault_handler(fimc_is_dev, fimc_is_fault_handler); #else iovmm_set_fault_handler(fimc_is_dev, fimc_is_fault_handler, NULL); #endif #endif /* set sysfs for debuging */ sysfs_debug.en_clk_gate = 0; sysfs_debug.en_dvfs = 1; #ifdef ENABLE_CLOCK_GATE sysfs_debug.en_clk_gate = 1; #ifdef HAS_FW_CLOCK_GATE sysfs_debug.clk_gate_mode = CLOCK_GATE_MODE_FW; #else sysfs_debug.clk_gate_mode = CLOCK_GATE_MODE_HOST; #endif #endif ret = sysfs_create_group(&core->pdev->dev.kobj, &fimc_is_debug_attr_group); s = pinctrl_lookup_state(pdata->pinctrl, "release"); if (pinctrl_select_state(pdata->pinctrl, s) < 0) { probe_err("pinctrl_select_state is fail\n"); goto p_err3; } probe_info("%s:end\n", __func__); return 0; p_err3: iounmap(core->regs); #if defined (ENABLE_IS_CORE) || defined (USE_MCUCTL) p_err2: release_mem_region(regs_res->start, resource_size(regs_res)); #endif p_err1: kfree(core); return ret; }
static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv, struct resource *io_res, u64 start, u32 size) { struct resource new_res = { .start = start, .end = start + size - 1, .flags = IORESOURCE_MEM, }; /* Detect a 64 bit address on a 32 bit system */ if (start != new_res.start) return (void __iomem *) ERR_PTR(-EINVAL); if (!resource_contains(io_res, &new_res)) return devm_ioremap_resource(dev, &new_res); return priv->iobase + (new_res.start - io_res->start); } /* * Work around broken BIOSs that return inconsistent values from the ACPI * region vs the registers. Trust the ACPI region. Such broken systems * probably cannot send large TPM commands since the buffer will be truncated. */ static u64 crb_fixup_cmd_size(struct device *dev, struct resource *io_res, u64 start, u64 size) { if (io_res->start > start || io_res->end < start) return size; if (start + size - 1 <= io_res->end) return size; dev_err(dev, FW_BUG "ACPI region does not cover the entire command/response buffer. %pr vs %llx %llx\n", io_res, start, size); return io_res->end - start + 1; } static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, struct acpi_table_tpm2 *buf) { struct list_head resources; struct resource io_res; struct device *dev = &device->dev; u32 pa_high, pa_low; u64 cmd_pa; u32 cmd_size; __le64 __rsp_pa; u64 rsp_pa; u32 rsp_size; int ret; INIT_LIST_HEAD(&resources); ret = acpi_dev_get_resources(device, &resources, crb_check_resource, &io_res); if (ret < 0) return ret; acpi_dev_free_resource_list(&resources); if (resource_type(&io_res) != IORESOURCE_MEM) { dev_err(dev, FW_BUG "TPM2 ACPI table does not define a memory resource\n"); return -EINVAL; } priv->iobase = devm_ioremap_resource(dev, &io_res); if (IS_ERR(priv->iobase)) return PTR_ERR(priv->iobase); /* The ACPI IO region starts at the head area and continues to include * the control area, as one nice sane region except for some older * stuff that puts the control area outside the ACPI IO region. */ if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || (priv->sm == ACPI_TPM2_MEMORY_MAPPED)) { if (buf->control_address == io_res.start + sizeof(*priv->regs_h)) priv->regs_h = priv->iobase; else dev_warn(dev, FW_BUG "Bad ACPI memory layout"); } ret = __crb_request_locality(dev, priv, 0); if (ret) return ret; priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address, sizeof(struct crb_regs_tail)); if (IS_ERR(priv->regs_t)) return PTR_ERR(priv->regs_t); /* * PTT HW bug w/a: wake up the device to access * possibly not retained registers. */ ret = crb_cmd_ready(dev, priv); if (ret) return ret; pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high); pa_low = ioread32(&priv->regs_t->ctrl_cmd_pa_low); cmd_pa = ((u64)pa_high << 32) | pa_low; cmd_size = crb_fixup_cmd_size(dev, &io_res, cmd_pa, ioread32(&priv->regs_t->ctrl_cmd_size)); dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n", pa_high, pa_low, cmd_size); priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size); if (IS_ERR(priv->cmd)) { ret = PTR_ERR(priv->cmd); goto out; } memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8); rsp_pa = le64_to_cpu(__rsp_pa); rsp_size = crb_fixup_cmd_size(dev, &io_res, rsp_pa, ioread32(&priv->regs_t->ctrl_rsp_size)); if (cmd_pa != rsp_pa) { priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size); ret = PTR_ERR_OR_ZERO(priv->rsp); goto out; } /* According to the PTP specification, overlapping command and response * buffer sizes must be identical. */ if (cmd_size != rsp_size) { dev_err(dev, FW_BUG "overlapping command and response buffer sizes are not identical"); ret = -EINVAL; goto out; } priv->rsp = priv->cmd; out: if (!ret) priv->cmd_size = cmd_size; crb_go_idle(dev, priv); __crb_relinquish_locality(dev, priv, 0); return ret; } static int crb_acpi_add(struct acpi_device *device) { struct acpi_table_tpm2 *buf; struct crb_priv *priv; struct tpm_chip *chip; struct device *dev = &device->dev; struct tpm2_crb_smc *crb_smc; acpi_status status; u32 sm; int rc; status = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **) &buf); if (ACPI_FAILURE(status) || buf->header.length < sizeof(*buf)) { dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n"); return -EINVAL; } /* Should the FIFO driver handle this? */ sm = buf->start_method; if (sm == ACPI_TPM2_MEMORY_MAPPED) return -ENODEV; priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL); if (!priv) return -ENOMEM; if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) { if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) { dev_err(dev, FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", buf->header.length, ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC); return -EINVAL; } crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf)); priv->smc_func_id = crb_smc->smc_func_id; } priv->sm = sm; priv->hid = acpi_device_hid(device); rc = crb_map_io(device, priv, buf); if (rc) return rc; chip = tpmm_chip_alloc(dev, &tpm_crb); if (IS_ERR(chip)) return PTR_ERR(chip); dev_set_drvdata(&chip->dev, priv); chip->acpi_dev_handle = device->handle; chip->flags = TPM_CHIP_FLAG_TPM2; rc = __crb_request_locality(dev, priv, 0); if (rc) return rc; rc = crb_cmd_ready(dev, priv); if (rc) goto out; pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); rc = tpm_chip_register(chip); if (rc) { crb_go_idle(dev, priv); pm_runtime_put_noidle(dev); pm_runtime_disable(dev); goto out; } pm_runtime_put_sync(dev); out: __crb_relinquish_locality(dev, priv, 0); return rc; } static int crb_acpi_remove(struct acpi_device *device) { struct device *dev = &device->dev; struct tpm_chip *chip = dev_get_drvdata(dev); tpm_chip_unregister(chip); pm_runtime_disable(dev); return 0; } static int __maybe_unused crb_pm_runtime_suspend(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); struct crb_priv *priv = dev_get_drvdata(&chip->dev); return crb_go_idle(dev, priv); } static int __maybe_unused crb_pm_runtime_resume(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); struct crb_priv *priv = dev_get_drvdata(&chip->dev); return crb_cmd_ready(dev, priv); } static int __maybe_unused crb_pm_suspend(struct device *dev) { int ret; ret = tpm_pm_suspend(dev); if (ret) return ret; return crb_pm_runtime_suspend(dev); }
static int serial_omap_probe(struct platform_device *pdev) { struct uart_omap_port *up; struct resource *mem, *irq; struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; int ret; if (pdev->dev.of_node) omap_up_info = of_get_uart_port_info(&pdev->dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "no irq resource?\n"); return -ENODEV; } if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } if (gpio_is_valid(omap_up_info->DTR_gpio) && omap_up_info->DTR_present) { ret = gpio_request(omap_up_info->DTR_gpio, "omap-serial"); if (ret < 0) return ret; ret = gpio_direction_output(omap_up_info->DTR_gpio, omap_up_info->DTR_inverted); if (ret < 0) return ret; } up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; if (gpio_is_valid(omap_up_info->DTR_gpio) && omap_up_info->DTR_present) { up->DTR_gpio = omap_up_info->DTR_gpio; up->DTR_inverted = omap_up_info->DTR_inverted; } else up->DTR_gpio = -EINVAL; up->DTR_active = 0; up->dev = &pdev->dev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.irq = irq->start; up->port.regshift = 2; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; if (pdev->dev.of_node) up->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); else up->port.line = pdev->id; if (up->port.line < 0) { dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", up->port.line); ret = -ENODEV; goto err_port_line; } up->pins = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(up->pins)) { dev_warn(&pdev->dev, "did not get pins for uart%i error: %li\n", up->port.line, PTR_ERR(up->pins)); up->pins = NULL; } sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; up->port.membase = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!up->port.membase) { dev_err(&pdev->dev, "can't ioremap UART\n"); ret = -ENOMEM; goto err_ioremap; } up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; if (!up->port.uartclk) { up->port.uartclk = DEFAULT_CLK_SPEED; dev_warn(&pdev->dev, "No clock speed specified: using default:" "%d\n", DEFAULT_CLK_SPEED); } up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; pm_qos_add_request(&up->pm_qos_request, PM_QOS_CPU_DMA_LATENCY, up->latency); serial_omap_uart_wq = create_singlethread_workqueue(up->name); INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); platform_set_drvdata(pdev, up); pm_runtime_enable(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->autosuspend_timeout); pm_runtime_irq_safe(&pdev->dev); pm_runtime_get_sync(&pdev->dev); omap_serial_fill_features_erratas(up); ui[up->port.line] = up; serial_omap_add_console_port(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto err_add_port; pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); return 0; err_add_port: pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); err_ioremap: err_port_line: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); return ret; }
static int __devinit ehci_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; struct msm_usb_host_platform_data *pdata; int retval; struct msmusb_hcd *mhcd; hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) return -ENOMEM; hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { usb_put_hcd(hcd); return hcd->irq; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { usb_put_hcd(hcd); return -ENODEV; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); mhcd = hcd_to_mhcd(hcd); spin_lock_init(&mhcd->lock); mhcd->in_lpm = 0; mhcd->running = 0; device_init_wakeup(&pdev->dev, 1); pdata = pdev->dev.platform_data; if (PHY_TYPE(pdata->phy_info) == USB_PHY_UNDEFINED) { usb_put_hcd(hcd); return -ENODEV; } hcd->power_budget = pdata->power_budget; mhcd->pdata = pdata; INIT_WORK(&mhcd->lpm_exit_work, usb_lpm_exit_w); wake_lock_init(&mhcd->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev)); pdata->ebi1_clk = clk_get(&pdev->dev, "core_clk"); if (IS_ERR(pdata->ebi1_clk)) pdata->ebi1_clk = NULL; else clk_set_rate(pdata->ebi1_clk, INT_MAX); #ifdef CONFIG_USB_HOST_NOTIFY if (pdata->host_notify) { hcd->host_notify = pdata->host_notify; hcd->ndev.name = dev_name(&pdev->dev); retval = host_notify_dev_register(&hcd->ndev); if (retval) { dev_err(&pdev->dev, "Failed to host_notify_dev_register\n"); return -ENODEV; } } #endif retval = msm_xusb_init_host(pdev, mhcd); if (retval < 0) { wake_lock_destroy(&mhcd->wlock); usb_put_hcd(hcd); clk_put(pdata->ebi1_clk); } pm_runtime_enable(&pdev->dev); return retval; }
static int __devinit hdmi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *res; struct i2c_adapter *phy_adapter; struct hdmi_device *hdmi_dev = NULL; struct hdmi_driver_data *drv_data; int ret; unsigned int irq_type; dev_dbg(dev, "probe start\n"); hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL); if (!hdmi_dev) { dev_err(dev, "out of memory\n"); ret = -ENOMEM; goto fail; } hdmi_dev->dev = dev; ret = hdmi_resources_init(hdmi_dev); if (ret) goto fail_hdev; /* mapping HDMI registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(dev, "get memory resource failed.\n"); ret = -ENXIO; goto fail_init; } hdmi_dev->regs = ioremap(res->start, resource_size(res)); if (hdmi_dev->regs == NULL) { dev_err(dev, "register mapping failed.\n"); ret = -ENXIO; goto fail_hdev; } /* External hpd */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(dev, "get external interrupt resource failed.\n"); ret = -ENXIO; goto fail_regs; } hdmi_dev->ext_irq = res->start; /* Internal hpd */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); if (res == NULL) { dev_err(dev, "get internal interrupt resource failed.\n"); ret = -ENXIO; goto fail_regs; } hdmi_dev->int_irq = res->start; /* workqueue for HPD */ hdmi_dev->hpd_wq = create_workqueue("hdmi-hpd"); if (hdmi_dev->hpd_wq == NULL) ret = -ENXIO; INIT_WORK(&hdmi_dev->hpd_work, s5p_hpd_kobject_uevent); /* setting v4l2 name to prevent WARN_ON in v4l2_device_register */ strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev), sizeof(hdmi_dev->v4l2_dev.name)); /* passing NULL owner prevents driver from erasing drvdata */ ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev); if (ret) { dev_err(dev, "could not register v4l2 device.\n"); goto fail_regs; } drv_data = (struct hdmi_driver_data *) platform_get_device_id(pdev)->driver_data; dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus); phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus); if (phy_adapter == NULL) { dev_err(dev, "adapter request failed\n"); ret = -ENXIO; goto fail_vdev; } hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, phy_adapter, &hdmiphy_info, NULL); /* on failure or not adapter is no longer useful */ i2c_put_adapter(phy_adapter); if (hdmi_dev->phy_sd == NULL) { dev_err(dev, "missing subdev for hdmiphy\n"); ret = -ENODEV; goto fail_vdev; } /* HDMI PHY power off * HDMI PHY is on as default configuration * So, HDMI PHY must be turned off if it's not used */ clk_enable(hdmi_dev->res.hdmiphy); v4l2_subdev_call(hdmi_dev->phy_sd, core, s_power, 0); clk_disable(hdmi_dev->res.hdmiphy); pm_runtime_enable(dev); /* irq setting by TV power on/off status */ if (!pm_runtime_suspended(hdmi_dev->dev)) { hdmi_dev->curr_irq = hdmi_dev->int_irq; irq_type = 0; s5p_v4l2_int_src_hdmi_hpd(); } else { if (s5p_v4l2_hpd_read_gpio()) atomic_set(&hdmi_dev->hpd_state, HPD_HIGH); else atomic_set(&hdmi_dev->hpd_state, HPD_LOW); hdmi_dev->curr_irq = hdmi_dev->ext_irq; irq_type = IRQ_TYPE_EDGE_BOTH; s5p_v4l2_int_src_ext_hpd(); } hdmi_dev->hpd_user_checked = false; ret = request_irq(hdmi_dev->curr_irq, hdmi_irq_handler, irq_type, "hdmi", hdmi_dev); if (ret) { dev_err(dev, "request interrupt failed.\n"); goto fail_vdev; } hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET; /* FIXME: missing fail preset is not supported */ hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset); /* default audio configuration : enable audio */ hdmi_dev->audio_enable = 1; hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE; hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE; hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC; /* register hdmi subdev as entity */ ret = hdmi_register_entity(hdmi_dev); if (ret) goto fail_irq; hdmi_entity_info_print(hdmi_dev); /* initialize hdcp resource */ ret = hdcp_prepare(hdmi_dev); if (ret) goto fail_irq; dev_info(dev, "probe sucessful\n"); return 0; fail_vdev: v4l2_device_unregister(&hdmi_dev->v4l2_dev); fail_irq: free_irq(hdmi_dev->curr_irq, hdmi_dev); fail_regs: iounmap(hdmi_dev->regs); fail_init: hdmi_resources_cleanup(hdmi_dev); fail_hdev: kfree(hdmi_dev); fail: dev_err(dev, "probe failed\n"); return ret; }
/* * Check if the die sensor is cooling down. If it's higher than * t_hot since the last throttle then throttle it again. * OMAP junction temperature could stay for a long time in an * unacceptable temperature range. The idea here is to check after * t_hot->throttle the system really came below t_hot else re-throttle * and keep doing till it's under t_hot temp range. */ static void throttle_delayed_work_fn(struct work_struct *work) { int curr; struct omap_temp_sensor *temp_sensor = container_of(work, struct omap_temp_sensor, throttle_work.work); curr = omap_read_current_temp(temp_sensor); #ifdef CONFIG_OMAP_TEMP_CONTROL if (curr >= temp_limit || curr < 0) { #else if (curr >= BGAP_THRESHOLD_T_HOT || curr < 0) { #endif pr_warn("%s: OMAP temp read %d exceeds the threshold\n", __func__, curr); omap_thermal_throttle(); schedule_delayed_work(&temp_sensor->throttle_work, msecs_to_jiffies(THROTTLE_DELAY_MS)); } else { schedule_delayed_work(&temp_sensor->throttle_work, msecs_to_jiffies(THROTTLE_DELAY_MS)); } } static irqreturn_t omap_tshut_irq_handler(int irq, void *data) { struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data; /* Need to handle thermal mgmt in bootloader * to avoid restart again at kernel level */ if (temp_sensor->is_efuse_valid) { pr_emerg("%s: Thermal shutdown reached rebooting device\n", __func__); kernel_restart(NULL); } else { pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__); } return IRQ_HANDLED; } static irqreturn_t omap_talert_irq_handler(int irq, void *data) { struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data; int t_hot, t_cold, temp_offset; t_hot = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET) & OMAP4_HOT_FLAG_MASK; t_cold = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET) & OMAP4_COLD_FLAG_MASK; temp_offset = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); if (t_hot) { omap_thermal_throttle(); schedule_delayed_work(&temp_sensor->throttle_work, msecs_to_jiffies(THROTTLE_DELAY_MS)); temp_offset &= ~(OMAP4_MASK_HOT_MASK); temp_offset |= OMAP4_MASK_COLD_MASK; } else if (t_cold) { cancel_delayed_work_sync(&temp_sensor->throttle_work); omap_thermal_unthrottle(); temp_offset &= ~(OMAP4_MASK_COLD_MASK); temp_offset |= OMAP4_MASK_HOT_MASK; } omap_temp_sensor_writel(temp_sensor, temp_offset, BGAP_CTRL_OFFSET); return IRQ_HANDLED; } static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct omap_temp_sensor *temp_sensor; struct resource *mem; int ret = 0, val; if (!pdata) { dev_err(dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; spin_lock_init(&temp_sensor->lock); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(dev, "%s:no mem resource\n", __func__); ret = -EINVAL; goto plat_res_err; } temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert"); if (temp_sensor->irq < 0) { dev_err(dev, "%s:Cannot get thermal alert irq\n", __func__); ret = -EINVAL; goto get_irq_err; } ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN, "thermal_shutdown"); if (ret) { dev_err(dev, "%s: Could not get tshut_gpio\n", __func__); goto tshut_gpio_req_err; } temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO); if (temp_sensor->tshut_irq < 0) { dev_err(dev, "%s:Cannot get thermal shutdown irq\n", __func__); ret = -EINVAL; goto get_tshut_irq_err; } temp_sensor->phy_base = pdata->offset; temp_sensor->pdev = pdev; temp_sensor->dev = dev; pm_runtime_enable(dev); pm_runtime_irq_safe(dev); /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (omap_readl(OMAP4_CTRL_MODULE_CORE + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) temp_sensor->is_efuse_valid = 1; temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); if (IS_ERR(temp_sensor->clock)) { ret = PTR_ERR(temp_sensor->clock); pr_err("%s:Unable to get fclk: %d\n", __func__, ret); ret = -EINVAL; goto clk_get_err; } /* Init delayed work for throttle decision */ INIT_DELAYED_WORK(&temp_sensor->throttle_work, throttle_delayed_work_fn); platform_set_drvdata(pdev, temp_sensor); ret = omap_temp_sensor_enable(temp_sensor); if (ret) { dev_err(dev, "%s:Cannot enable temp sensor\n", __func__); goto sensor_enable_err; } omap_enable_continuous_mode(temp_sensor); omap_configure_temp_sensor_thresholds(temp_sensor); /* 1 ms */ omap_configure_temp_sensor_counter(temp_sensor, 1); /* Wait till the first conversion is done wait for at least 1ms */ mdelay(2); /* Read the temperature once due to hw issue*/ omap_read_current_temp(temp_sensor); /* Set 2 seconds time as default counter */ omap_configure_temp_sensor_counter(temp_sensor, temp_sensor->clk_rate * 2); ret = request_threaded_irq(temp_sensor->irq, NULL, omap_talert_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "temp_sensor", (void *)temp_sensor); if (ret) { dev_err(dev, "Request threaded irq failed.\n"); goto req_irq_err; } ret = request_threaded_irq(temp_sensor->tshut_irq, NULL, omap_tshut_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tshut", (void *)temp_sensor); if (ret) { dev_err(dev, "Request threaded irq failed for TSHUT.\n"); goto tshut_irq_req_err; } ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sysfs_create_err; } /* unmask the T_COLD and unmask T_HOT at init */ val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); val |= OMAP4_MASK_COLD_MASK; val |= OMAP4_MASK_HOT_MASK; omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET); dev_info(dev, "%s probed", pdata->name); temp_sensor_pm = temp_sensor; #ifdef CONFIG_OMAP_TEMP_CONTROL ctrl_sensor = temp_sensor; tempcontrol_registerlimit(temp_limit); #endif return 0; sysfs_create_err: free_irq(temp_sensor->tshut_irq, temp_sensor); cancel_delayed_work_sync(&temp_sensor->throttle_work); tshut_irq_req_err: free_irq(temp_sensor->irq, temp_sensor); req_irq_err: platform_set_drvdata(pdev, NULL); omap_temp_sensor_disable(temp_sensor); sensor_enable_err: clk_put(temp_sensor->clock); clk_get_err: pm_runtime_disable(dev); get_tshut_irq_err: gpio_free(OMAP_TSHUT_GPIO); tshut_gpio_req_err: get_irq_err: plat_res_err: kfree(temp_sensor); return ret; } static int __devexit omap_temp_sensor_remove(struct platform_device *pdev) { struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); sysfs_remove_group(&pdev->dev.kobj, &omap_temp_sensor_group); cancel_delayed_work_sync(&temp_sensor->throttle_work); omap_temp_sensor_disable(temp_sensor); clk_put(temp_sensor->clock); platform_set_drvdata(pdev, NULL); if (temp_sensor->irq) free_irq(temp_sensor->irq, temp_sensor); if (temp_sensor->tshut_irq) free_irq(temp_sensor->tshut_irq, temp_sensor); kfree(temp_sensor); return 0; } #ifdef CONFIG_PM static void omap_temp_sensor_save_ctxt(struct omap_temp_sensor *temp_sensor) { temp_sensor_context.temp_sensor_ctrl = omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET); temp_sensor_context.bg_ctrl = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); temp_sensor_context.bg_counter = omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET); temp_sensor_context.bg_threshold = omap_temp_sensor_readl(temp_sensor, BGAP_THRESHOLD_OFFSET); temp_sensor_context.temp_sensor_tshut_threshold = omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET); }
static int sdhci_acpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; acpi_handle handle = ACPI_HANDLE(dev); struct acpi_device *device; struct sdhci_acpi_host *c; struct sdhci_host *host; struct resource *iomem; resource_size_t len; const char *hid; const char *uid; int err; if (acpi_bus_get_device(handle, &device)) return -ENODEV; if (acpi_bus_get_status(device) || !device->status.present) return -ENODEV; if (sdhci_acpi_byt_defer(dev)) return -EPROBE_DEFER; hid = acpi_device_hid(device); uid = device->pnp.unique_id; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem) return -ENOMEM; len = resource_size(iomem); if (len < 0x100) dev_err(dev, "Invalid iomem size!\n"); if (!devm_request_mem_region(dev, iomem->start, len, dev_name(dev))) return -ENOMEM; host = sdhci_alloc_host(dev, sizeof(struct sdhci_acpi_host)); if (IS_ERR(host)) return PTR_ERR(host); c = sdhci_priv(host); c->host = host; c->slot = sdhci_acpi_get_slot(hid, uid); c->pdev = pdev; c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM); platform_set_drvdata(pdev, c); host->hw_name = "ACPI"; host->ops = &sdhci_acpi_ops_dflt; host->irq = platform_get_irq(pdev, 0); host->ioaddr = devm_ioremap_nocache(dev, iomem->start, resource_size(iomem)); if (host->ioaddr == NULL) { err = -ENOMEM; goto err_free; } if (c->slot) { if (c->slot->probe_slot) { err = c->slot->probe_slot(pdev, hid, uid); if (err) goto err_free; } if (c->slot->chip) { host->ops = c->slot->chip->ops; host->quirks |= c->slot->chip->quirks; host->quirks2 |= c->slot->chip->quirks2; host->mmc->caps |= c->slot->chip->caps; host->mmc->caps2 |= c->slot->chip->caps2; host->mmc->pm_caps |= c->slot->chip->pm_caps; } host->quirks |= c->slot->quirks; host->quirks2 |= c->slot->quirks2; host->mmc->caps |= c->slot->caps; host->mmc->caps2 |= c->slot->caps2; host->mmc->pm_caps |= c->slot->pm_caps; } host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL); if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL)) { dev_warn(dev, "failed to setup card detect gpio\n"); c->use_runtime_pm = false; } } err = sdhci_add_host(host); if (err) goto err_free; if (c->use_runtime_pm) { pm_runtime_set_active(dev); pm_suspend_ignore_children(dev, 1); pm_runtime_set_autosuspend_delay(dev, 50); pm_runtime_use_autosuspend(dev); pm_runtime_enable(dev); } return 0; err_free: sdhci_free_host(c->host); return err; }
static int s5p_ehci_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); struct usb_hcd *hcd = s5p_ehci->hcd; struct ehci_hcd *ehci = hcd_to_ehci(hcd); clk_enable(s5p_ehci->clk); s5p_ehci_phy_init(pdev); /* if EHCI was off, hcd was removed */ if (!s5p_ehci->power_on) { dev_info(dev, "Nothing to do for the device (power off)\n"); return 0; } if (time_before(jiffies, ehci->next_statechange)) usleep_range(10000, 11000); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; /* Update runtime PM status and clear runtime_error */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); /* Prevent device from runtime suspend during resume time */ pm_runtime_get_sync(dev); #ifdef CONFIG_MDM_HSIC_PM set_host_stat(hsic_pm_dev, POWER_ON); wait_dev_pwr_stat(hsic_pm_dev, POWER_ON); #endif #if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) \ || defined(CONFIG_MDM_HSIC_PM) pm_runtime_mark_last_busy(&hcd->self.root_hub->dev); #endif return 0; }
int __devinit arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; const char *type_name; unsigned int reg, val; int (*apply_patch)(struct arizona *) = NULL; int ret, i; dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock); mutex_init(&arizona->reg_setting_lock); if (dev_get_platdata(arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), sizeof(arizona->pdata)); regcache_cache_only(arizona->regmap, true); switch (arizona->type) { case WM5102: case WM5110: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies); break; default: dev_err(arizona->dev, "Unknown device type %d\n", arizona->type); return -EINVAL; } ret = mfd_add_devices(arizona->dev, -1, early_devs, ARRAY_SIZE(early_devs), NULL, 0); if (ret != 0) { dev_err(dev, "Failed to add early children: %d\n", ret); return ret; } ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to request core supplies: %d\n", ret); goto err_early; } arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD"); if (IS_ERR(arizona->dcvdd)) { ret = PTR_ERR(arizona->dcvdd); dev_err(dev, "Failed to request DCVDD: %d\n", ret); goto err_early; } if (arizona->pdata.reset) { /* Start out with /RESET low to put the chip into reset */ ret = gpio_request_one(arizona->pdata.reset, GPIOF_DIR_OUT | GPIOF_INIT_LOW, "arizona /RESET"); if (ret != 0) { dev_err(dev, "Failed to request /RESET: %d\n", ret); goto err_early; } } ret = regulator_bulk_enable(arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to enable core supplies: %d\n", ret); goto err_early; } ret = regulator_enable(arizona->dcvdd); if (ret != 0) { dev_err(dev, "Failed to enable DCVDD: %d\n", ret); goto err_enable; } if (arizona->pdata.control_init_time) msleep(arizona->pdata.control_init_time); if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 1); msleep(1); } regcache_cache_only(arizona->regmap, false); ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(dev, "Failed to read ID register: %d\n", ret); goto err_reset; } ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION, &arizona->rev); if (ret != 0) { dev_err(dev, "Failed to read revision register: %d\n", ret); goto err_reset; } arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; switch (reg) { #ifdef CONFIG_MFD_WM5102 case 0x5102: type_name = "WM5102"; if (arizona->type != WM5102) { dev_err(arizona->dev, "WM5102 registered as %d\n", arizona->type); arizona->type = WM5102; } apply_patch = wm5102_patch; arizona->rev &= 0x7; break; #endif #ifdef CONFIG_MFD_WM5110 case 0x5110: type_name = "WM5110"; if (arizona->type != WM5110) { dev_err(arizona->dev, "WM5110 registered as %d\n", arizona->type); arizona->type = WM5110; } apply_patch = wm5110_patch; break; #endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_reset; } dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } msleep(1); } switch (arizona->type) { case WM5102: ret = regmap_read(arizona->regmap, 0x19, &val); if (ret != 0) dev_err(dev, "Failed to check write sequencer state: %d\n", ret); else if (val & 0x01) break; /* Fall through */ default: ret = arizona_wait_for_boot(arizona); if (ret != 0) { dev_err(arizona->dev, "Device failed initial boot: %d\n", ret); goto err_reset; } break; } if (apply_patch) { ret = apply_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err_reset; } switch (arizona->type) { case WM5102: ret = arizona_apply_hardware_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply hardware patch: %d\n", ret); goto err_reset; } break; default: break; } } for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { if (!arizona->pdata.gpio_defaults[i]) continue; regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i, arizona->pdata.gpio_defaults[i]); } pm_runtime_enable(arizona->dev); /* Chip default */ if (!arizona->pdata.clk32k_src) arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2; switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK2: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, arizona->pdata.clk32k_src - 1); arizona_clk32k_enable(arizona); break; case ARIZONA_32KZ_NONE: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, 2); break; default: dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n", arizona->pdata.clk32k_src); ret = -EINVAL; goto err_reset; } for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) { if (!arizona->pdata.micbias[i].mV && !arizona->pdata.micbias[i].bypass) continue; /* Apply default for bypass mode */ if (!arizona->pdata.micbias[i].mV) arizona->pdata.micbias[i].mV = 2800; val = (arizona->pdata.micbias[i].mV - 1500) / 100; val <<= ARIZONA_MICB1_LVL_SHIFT; if (arizona->pdata.micbias[i].ext_cap) val |= ARIZONA_MICB1_EXT_CAP; if (arizona->pdata.micbias[i].discharge) val |= ARIZONA_MICB1_DISCH; if (arizona->pdata.micbias[i].fast_start) val |= ARIZONA_MICB1_RATE; if (arizona->pdata.micbias[i].bypass) val |= ARIZONA_MICB1_BYPASS; regmap_update_bits(arizona->regmap, ARIZONA_MIC_BIAS_CTRL_1 + i, ARIZONA_MICB1_LVL_MASK | ARIZONA_MICB1_DISCH | ARIZONA_MICB1_BYPASS | ARIZONA_MICB1_RATE, val); } for (i = 0; i < ARIZONA_MAX_INPUT; i++) { /* Default for both is 0 so noop with defaults */ val = arizona->pdata.dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT; val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT; regmap_update_bits(arizona->regmap, ARIZONA_IN1L_CONTROL + (i * 8), ARIZONA_IN1_DMIC_SUP_MASK | ARIZONA_IN1_MODE_MASK, val); } for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { /* Default is 0 so noop with defaults */ if (arizona->pdata.out_mono[i]) val = ARIZONA_OUT1_MONO; else val = 0; regmap_update_bits(arizona->regmap, ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8), ARIZONA_OUT1_MONO, val); } for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) { if (arizona->pdata.spk_mute[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_1 + (i * 2), ARIZONA_SPK1_MUTE_ENDIAN_MASK | ARIZONA_SPK1_MUTE_SEQ1_MASK, arizona->pdata.spk_mute[i]); if (arizona->pdata.spk_fmt[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_2 + (i * 2), ARIZONA_SPK1_FMT_MASK, arizona->pdata.spk_fmt[i]); } /* set virtual IRQs */ arizona->virq[0] = arizona->pdata.irq_base; arizona->virq[1] = arizona->pdata.irq_base + ARIZONA_NUM_IRQ; switch (arizona->pdata.mic_spk_clamp) { case ARIZONA_MIC_CLAMP_SPKLN: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2, 0x3c, 0xc); break; case ARIZONA_MIC_CLAMP_SPKLP: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2, 0x3c, 0x1c); break; case ARIZONA_MIC_CLAMP_SPKRN: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3, 0x3c, 0xc); break; case ARIZONA_MIC_CLAMP_SPKRP: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3, 0x3c, 0x1c); break; default: break; } /* Set up for interrupts */ ret = arizona_irq_init(arizona); if (ret != 0) goto err_reset; arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error", arizona_clkgen_err, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked", arizona_overclocked, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked", arizona_underclocked, arizona); switch (arizona->type) { case WM5102: ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, ARRAY_SIZE(wm5102_devs), NULL, 0); break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, ARRAY_SIZE(wm5110_devs), NULL, 0); break; } if (ret != 0) { dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret); goto err_irq; } if (arizona->pdata.init_done) arizona->pdata.init_done(); #ifdef CONFIG_PM_RUNTIME regulator_disable(arizona->dcvdd); #endif return 0; err_irq: arizona_irq_exit(arizona); err_reset: if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 0); gpio_free(arizona->pdata.reset); } regulator_disable(arizona->dcvdd); err_enable: regulator_bulk_disable(arizona->num_core_supplies, arizona->core_supplies); err_early: mfd_remove_devices(dev); return ret; }
static int __devinit s5p_ehci_probe(struct platform_device *pdev) { struct s5p_ehci_platdata *pdata; struct s5p_ehci_hcd *s5p_ehci; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct resource *res; int irq; int err; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data defined\n"); return -EINVAL; } s5p_ehci = kzalloc(sizeof(struct s5p_ehci_hcd), GFP_KERNEL); if (!s5p_ehci) return -ENOMEM; s5p_ehci->dev = &pdev->dev; hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); err = -ENOMEM; goto fail_hcd; } s5p_ehci->hcd = hcd; s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); if (IS_ERR(s5p_ehci->clk)) { dev_err(&pdev->dev, "Failed to get usbhost clock\n"); err = PTR_ERR(s5p_ehci->clk); goto fail_clk; } err = clk_enable(s5p_ehci->clk); if (err) goto fail_clken; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "Failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENODEV; goto fail; } platform_set_drvdata(pdev, s5p_ehci); s5p_ehci_phy_init(pdev); ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); goto fail; } /* * EHCI root hubs are expected to handle remote wakeup. * So, wakeup flag init defaults for root hubs. */ device_wakeup_enable(&hcd->self.root_hub->dev); create_ehci_sys_file(ehci); s5p_ehci->power_on = 1; #ifdef CONFIG_USB_SUSPEND pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get(hcd->self.controller); #endif #ifdef CONFIG_MDM_HSIC_PM /* halt controller before driving suspend on ths bus */ ehci->susp_sof_bug = 1; set_host_stat(hsic_pm_dev, POWER_ON); /* pm_runtime_allow(&pdev->dev); */ pm_runtime_set_autosuspend_delay(&hcd->self.root_hub->dev, 0); pm_runtime_forbid(&pdev->dev); enable_periodic(ehci); #endif return 0; fail: iounmap(hcd->regs); fail_io: clk_disable(s5p_ehci->clk); fail_clken: clk_put(s5p_ehci->clk); fail_clk: usb_put_hcd(hcd); fail_hcd: kfree(s5p_ehci); return err; }
int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, struct analogix_dp_plat_data *plat_data) { struct platform_device *pdev = to_platform_device(dev); struct analogix_dp_device *dp; struct resource *res; unsigned int irq_flags; int ret; if (!plat_data) { dev_err(dev, "Invalided input plat_data\n"); return -EINVAL; } dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; dev_set_drvdata(dev, dp); dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; mutex_init(&dp->panel_lock); dp->panel_is_modeset = false; /* * platform dp driver need containor_of the plat_data to get * the driver private data, so we need to store the point of * plat_data, not the context of plat_data. */ dp->plat_data = plat_data; ret = analogix_dp_dt_parse_pdata(dp); if (ret) return ret; dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0); if (!gpio_is_valid(dp->hpd_gpio)) dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } pm_runtime_enable(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); ret = devm_request_threaded_irq(&pdev->dev, dp->irq, analogix_dp_hardirq, analogix_dp_irq_thread, irq_flags, "analogix-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); goto err_disable_pm_runtime; } disable_irq(dp->irq); dp->drm_dev = drm_dev; dp->encoder = dp->plat_data->encoder; dp->aux.name = "DP-AUX"; dp->aux.transfer = analogix_dpaux_transfer; dp->aux.dev = &pdev->dev; ret = drm_dp_aux_register(&dp->aux); if (ret) goto err_disable_pm_runtime; ret = analogix_dp_create_bridge(drm_dev, dp); if (ret) { DRM_ERROR("failed to create bridge (%d)\n", ret); drm_encoder_cleanup(dp->encoder); goto err_disable_pm_runtime; } return 0; err_disable_pm_runtime: pm_runtime_disable(dev); return ret; }
static int __devinit r_tpu_probe(struct platform_device *pdev) { struct led_renesas_tpu_config *cfg = pdev->dev.platform_data; struct r_tpu_priv *p; struct resource *res; int ret = -ENXIO; if (!cfg) { dev_err(&pdev->dev, "missing platform data\n"); goto err0; } p = kzalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { dev_err(&pdev->dev, "failed to allocate driver data\n"); ret = -ENOMEM; goto err0; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get I/O memory\n"); goto err1; } /* map memory, let mapbase point to our channel */ p->mapbase = ioremap_nocache(res->start, resource_size(res)); if (p->mapbase == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); goto err1; } /* get hold of clock */ p->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(p->clk)) { dev_err(&pdev->dev, "cannot get clock\n"); ret = PTR_ERR(p->clk); goto err2; } p->pdev = pdev; p->pin_state = R_TPU_PIN_UNUSED; p->timer_state = R_TPU_TIMER_UNUSED; p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100; r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF); platform_set_drvdata(pdev, p); INIT_WORK(&p->work, r_tpu_work); p->ldev.name = cfg->name; p->ldev.brightness = LED_OFF; p->ldev.max_brightness = cfg->max_brightness; p->ldev.brightness_set = r_tpu_set_brightness; p->ldev.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&pdev->dev, &p->ldev); if (ret < 0) goto err3; /* max_brightness may be updated by the LED core code */ p->min_rate = p->ldev.max_brightness * p->refresh_rate; pm_runtime_enable(&pdev->dev); return 0; err3: r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); clk_put(p->clk); err2: iounmap(p->mapbase); err1: kfree(p); err0: return ret; }
static int __init omap2430_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; struct omap2430_glue *glue; int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(&pdev->dev, "failed to allocate glue context\n"); goto err0; } musb = platform_device_alloc("musb-hdrc", -1); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); goto err1; } musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &omap2430_dmamask; musb->dev.coherent_dma_mask = omap2430_dmamask; glue->dev = &pdev->dev; glue->musb = musb; pdata->platform_ops = &omap2430_ops; platform_set_drvdata(pdev, glue); ret = platform_device_add_resources(musb, pdev->resource, pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); goto err2; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); goto err2; } ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } pm_runtime_enable(&pdev->dev); return 0; err2: platform_device_put(musb); err1: kfree(glue); err0: return ret; }
static int tegra30_ahub_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct tegra30_ahub_soc_data *soc_data; struct reset_control *rst; int i; struct resource *res0, *res1; void __iomem *regs_apbif, *regs_ahub; int ret = 0; if (ahub) return -ENODEV; match = of_match_device(tegra30_ahub_of_match, &pdev->dev); if (!match) return -EINVAL; soc_data = match->data; /* * The AHUB hosts a register bus: the "configlink". For this to * operate correctly, all devices on this bus must be out of reset. * Ensure that here. */ for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) { if (!(configlink_mods[i].mod_list_mask & soc_data->mod_list_mask)) continue; rst = reset_control_get_exclusive(&pdev->dev, configlink_mods[i].rst_name); if (IS_ERR(rst)) { dev_err(&pdev->dev, "Can't get reset %s\n", configlink_mods[i].rst_name); ret = PTR_ERR(rst); return ret; } ret = reset_control_deassert(rst); reset_control_put(rst); if (ret) return ret; } ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), GFP_KERNEL); if (!ahub) return -ENOMEM; dev_set_drvdata(&pdev->dev, ahub); ahub->soc_data = soc_data; ahub->dev = &pdev->dev; ahub->clk_d_audio = devm_clk_get(&pdev->dev, "d_audio"); if (IS_ERR(ahub->clk_d_audio)) { dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n"); ret = PTR_ERR(ahub->clk_d_audio); return ret; } ahub->clk_apbif = devm_clk_get(&pdev->dev, "apbif"); if (IS_ERR(ahub->clk_apbif)) { dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n"); ret = PTR_ERR(ahub->clk_apbif); return ret; } res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs_apbif = devm_ioremap_resource(&pdev->dev, res0); if (IS_ERR(regs_apbif)) return PTR_ERR(regs_apbif); ahub->apbif_addr = res0->start; ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif, &tegra30_ahub_apbif_regmap_config); if (IS_ERR(ahub->regmap_apbif)) { dev_err(&pdev->dev, "apbif regmap init failed\n"); ret = PTR_ERR(ahub->regmap_apbif); return ret; } regcache_cache_only(ahub->regmap_apbif, true); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); regs_ahub = devm_ioremap_resource(&pdev->dev, res1); if (IS_ERR(regs_ahub)) return PTR_ERR(regs_ahub); ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub, &tegra30_ahub_ahub_regmap_config); if (IS_ERR(ahub->regmap_ahub)) { dev_err(&pdev->dev, "ahub regmap init failed\n"); ret = PTR_ERR(ahub->regmap_ahub); return ret; } regcache_cache_only(ahub->regmap_ahub, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra30_ahub_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); return ret; }
static int rotator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rot_context *rot; struct exynos_drm_ippdrv *ippdrv; int ret; if (!dev->of_node) { dev_err(dev, "cannot find of_node.\n"); return -ENODEV; } rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL); if (!rot) return -ENOMEM; rot->limit_tbl = (struct rot_limit_table *) of_device_get_match_data(dev); rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rot->regs = devm_ioremap_resource(dev, rot->regs_res); if (IS_ERR(rot->regs)) return PTR_ERR(rot->regs); rot->irq = platform_get_irq(pdev, 0); if (rot->irq < 0) { dev_err(dev, "failed to get irq\n"); return rot->irq; } ret = devm_request_threaded_irq(dev, rot->irq, NULL, rotator_irq_handler, IRQF_ONESHOT, "drm_rotator", rot); if (ret < 0) { dev_err(dev, "failed to request irq\n"); return ret; } rot->clock = devm_clk_get(dev, "rotator"); if (IS_ERR(rot->clock)) { dev_err(dev, "failed to get clock\n"); return PTR_ERR(rot->clock); } pm_runtime_enable(dev); ippdrv = &rot->ippdrv; ippdrv->dev = dev; ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &rot_src_ops; ippdrv->ops[EXYNOS_DRM_OPS_DST] = &rot_dst_ops; ippdrv->check_property = rotator_ippdrv_check_property; ippdrv->start = rotator_ippdrv_start; ret = rotator_init_prop_list(ippdrv); if (ret < 0) { dev_err(dev, "failed to init property list.\n"); goto err_ippdrv_register; } DRM_DEBUG_KMS("ippdrv[%p]\n", ippdrv); platform_set_drvdata(pdev, rot); ret = exynos_drm_ippdrv_register(ippdrv); if (ret < 0) { dev_err(dev, "failed to register drm rotator device\n"); goto err_ippdrv_register; } dev_info(dev, "The exynos rotator is probed successfully\n"); return 0; err_ippdrv_register: pm_runtime_disable(dev); return ret; }
static int __devinit dwc3_probe(struct platform_device *pdev) { const struct platform_device_id *id = platform_get_device_id(pdev); struct resource *res; struct dwc3 *dwc; void __iomem *regs; unsigned int features = id->driver_data; int ret = -ENOMEM; int irq; void *mem; mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) { dev_err(&pdev->dev, "not enough memory\n"); goto err0; } dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "missing resource\n"); goto err1; } res = request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev)); if (!res) { dev_err(&pdev->dev, "can't request mem region\n"); goto err1; } regs = ioremap(res->start, resource_size(res)); if (!regs) { dev_err(&pdev->dev, "ioremap failed\n"); goto err2; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "missing IRQ\n"); goto err3; } spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); dwc->regs = regs; dwc->regs_size = resource_size(res); dwc->dev = &pdev->dev; dwc->irq = irq; pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); pm_runtime_forbid(&pdev->dev); ret = dwc3_core_init(dwc); if (ret) { dev_err(&pdev->dev, "failed to initialize core\n"); goto err3; } if (features & DWC3_HAS_PERIPHERAL) { ret = dwc3_gadget_init(dwc); if (ret) { dev_err(&pdev->dev, "failed to initialized gadget\n"); goto err4; } } ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(&pdev->dev, "failed to initialize debugfs\n"); goto err5; } pm_runtime_allow(&pdev->dev); return 0; err5: if (features & DWC3_HAS_PERIPHERAL) dwc3_gadget_exit(dwc); err4: dwc3_core_exit(dwc); err3: iounmap(regs); err2: release_mem_region(res->start, resource_size(res)); err1: kfree(dwc->mem); err0: return ret; }
static int __devinit ehci_msm2_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; struct msm_hcd *mhcd; const struct msm_usb_host_platform_data *pdata; char pdev_name[PDEV_NAME_LEN]; int ret; int res_gpio; dev_info(&pdev->dev, "ehci_msm2 probe\n"); /* If there is no WAN device present, we don't need to start the EHCI stack */ if(!wan_present()) return -ENODEV; if (pdev->dev.of_node) { dev_dbg(&pdev->dev, "device tree enabled\n"); pdev->dev.platform_data = ehci_msm2_dt_to_pdata(pdev); } if (!pdev->dev.platform_data) dev_dbg(&pdev->dev, "No platform data given\n"); if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &ehci_msm_dma_mask; if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); hcd = usb_create_hcd(&msm_hc2_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd_to_bus(hcd)->skip_resume = true; hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } mhcd = hcd_to_mhcd(hcd); mhcd->dev = &pdev->dev; spin_lock_init(&mhcd->wakeup_lock); mhcd->async_irq = platform_get_irq_byname(pdev, "async_irq"); if (mhcd->async_irq < 0) { dev_dbg(&pdev->dev, "platform_get_irq for async_int failed\n"); mhcd->async_irq = 0; } else { ret = request_irq(mhcd->async_irq, msm_async_irq, IRQF_TRIGGER_RISING, "msm_ehci_host", mhcd); if (ret) { dev_err(&pdev->dev, "request irq failed (ASYNC INT)\n"); goto unmap; } disable_irq(mhcd->async_irq); } snprintf(pdev_name, PDEV_NAME_LEN, "%s.%d", pdev->name, pdev->id); mhcd->xo_clk = clk_get(&pdev->dev, "xo"); if (!IS_ERR(mhcd->xo_clk)) { ret = clk_prepare_enable(mhcd->xo_clk); } else { mhcd->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, pdev_name); if (IS_ERR(mhcd->xo_handle)) { dev_err(&pdev->dev, "%s fail to get handle for X0 D0\n", __func__); ret = PTR_ERR(mhcd->xo_handle); goto free_async_irq; } else { ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_ON); } } if (ret) { dev_err(&pdev->dev, "%s failed to vote for TCXO %d\n", __func__, ret); goto free_xo_handle; } if (pdev->dev.of_node) { res_gpio = of_get_named_gpio(pdev->dev.of_node, "usb2,resume-gpio", 0); if (res_gpio < 0){ res_gpio = 0; goto devote_xo_handle; } mhcd->resume_gpio = res_gpio; gpio_request(mhcd->resume_gpio, "USB2_RESUME"); } else { res = platform_get_resource_byname(pdev, IORESOURCE_IO, "resume_gpio"); if (res) { dev_dbg(&pdev->dev, "resume_gpio:%d\n", res->start); mhcd->resume_gpio = res->start; } } if(pdev->dev.of_node){ res_gpio = of_get_named_gpio(pdev->dev.of_node, "usb2,wakeup-gpio", 0); if (res_gpio < 0){ res_gpio = 0; goto devote_xo_handle; } mhcd->wakeup_gpio = res_gpio; } else { res = platform_get_resource_byname(pdev, IORESOURCE_IO, "wakeup_gpio"); if (res) { dev_dbg(&pdev->dev, "wakeup gpio:%d\n", res->start); mhcd->wakeup_gpio = res->start; } } if (pdev->dev.of_node) mhcd->wakeup_irq = gpio_to_irq(mhcd->wakeup_gpio); else mhcd->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq"); if (mhcd->wakeup_irq > 0) { dev_dbg(&pdev->dev, "wakeup irq:%d\n", res->start); irq_set_status_flags(mhcd->wakeup_irq, IRQ_NOAUTOEN); ret = request_irq(mhcd->wakeup_irq, msm_hsusb_wakeup_irq, IRQF_TRIGGER_HIGH, "msm_hsusb_wakeup", mhcd); if (ret) { dev_err(&pdev->dev, "request_irq(%d) failed:%d\n", mhcd->wakeup_irq, ret); mhcd->wakeup_irq = 0; } } else { mhcd->wakeup_irq = 0; } spin_lock_init(&mhcd->wakeup_lock); ret = msm_ehci_init_clocks(mhcd, 1); if (ret) { dev_err(&pdev->dev, "unable to initialize clocks\n"); ret = -ENODEV; goto devote_xo_handle; } ret = msm_ehci_init_vddcx(mhcd, 1); if (ret) { dev_err(&pdev->dev, "unable to initialize VDDCX\n"); ret = -ENODEV; goto deinit_clocks; } ret = msm_ehci_config_vddcx(mhcd, 1); if (ret) { dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); goto deinit_vddcx; } ret = msm_ehci_ldo_init(mhcd, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); goto deinit_vddcx; } ret = msm_ehci_ldo_enable(mhcd, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg enable failed\n"); goto deinit_ldo; } ret = msm_ehci_init_vbus(mhcd, 1); if (ret) { dev_err(&pdev->dev, "unable to get vbus\n"); goto disable_ldo; } pdata = mhcd->dev->platform_data; if (pdata && pdata->use_sec_phy) mhcd->usb_phy_ctrl_reg = USB_PHY_CTRL2; else mhcd->usb_phy_ctrl_reg = USB_PHY_CTRL; ret = msm_hsusb_reset(mhcd); if (ret) { dev_err(&pdev->dev, "hsusb PHY initialization failed\n"); goto vbus_deinit; } if( pdata && pdata->phy_sof_workaround) { /* defer bus suspend until RH suspend */ mhcd->ehci.susp_sof_bug = 1; mhcd->ehci.resume_sof_bug = 1; } ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); if (ret) { dev_err(&pdev->dev, "unable to register HCD\n"); goto vbus_deinit; } if (pdata && (!pdata->dock_connect_irq || !irq_read_line(pdata->dock_connect_irq))) msm_ehci_vbus_power(mhcd, 1); device_init_wakeup(&pdev->dev, 1); wake_lock_init(&mhcd->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev)); wake_lock(&mhcd->wlock); INIT_WORK(&mhcd->phy_susp_fail_work, msm_ehci_phy_susp_fail_work); /* * This pdev->dev is assigned parent of root-hub by USB core, * hence, runtime framework automatically calls this driver's * runtime APIs based on root-hub's state. */ /* configure pmic_gpio_irq for D+ change */ if (pdata && pdata->pmic_gpio_dp_irq) mhcd->pmic_gpio_dp_irq = pdata->pmic_gpio_dp_irq; if (mhcd->pmic_gpio_dp_irq) { ret = request_threaded_irq(mhcd->pmic_gpio_dp_irq, NULL, msm_ehci_host_wakeup_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "msm_ehci_host_wakeup", mhcd); if (!ret) { disable_irq_nosync(mhcd->pmic_gpio_dp_irq); } else { dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", mhcd->pmic_gpio_dp_irq, ret); mhcd->pmic_gpio_dp_irq = 0; } } if (pdata && pdata->pd_rework_installed) mhcd->flags |= ALLOW_EHCI_RETENTION; pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; vbus_deinit: msm_ehci_init_vbus(mhcd, 0); disable_ldo: msm_ehci_ldo_enable(mhcd, 0); deinit_ldo: msm_ehci_ldo_init(mhcd, 0); deinit_vddcx: msm_ehci_init_vddcx(mhcd, 0); deinit_clocks: msm_ehci_init_clocks(mhcd, 0); devote_xo_handle: if (!IS_ERR(mhcd->xo_clk)) clk_disable_unprepare(mhcd->xo_clk); else msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_OFF); if(mhcd->wakeup_irq) free_irq(mhcd->wakeup_irq, mhcd); if(mhcd->resume_gpio) gpio_free(mhcd->resume_gpio); free_xo_handle: if (!IS_ERR(mhcd->xo_clk)) clk_put(mhcd->xo_clk); else msm_xo_put(mhcd->xo_handle); free_async_irq: if (mhcd->async_irq) free_irq(mhcd->async_irq, mhcd); unmap: iounmap(hcd->regs); put_hcd: usb_put_hcd(hcd); return ret; }
static int vpss_probe(struct platform_device *pdev) { struct resource *res; char *platform_name; if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data\n"); return -ENOENT; } platform_name = pdev->dev.platform_data; if (!strcmp(platform_name, "dm355_vpss")) oper_cfg.platform = DM355; else if (!strcmp(platform_name, "dm365_vpss")) oper_cfg.platform = DM365; else if (!strcmp(platform_name, "dm644x_vpss")) oper_cfg.platform = DM644X; else { dev_err(&pdev->dev, "vpss driver not supported on this platform\n"); return -ENODEV; } dev_info(&pdev->dev, "%s vpss probed\n", platform_name); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); oper_cfg.vpss_regs_base0 = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(oper_cfg.vpss_regs_base0)) return PTR_ERR(oper_cfg.vpss_regs_base0); if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); oper_cfg.vpss_regs_base1 = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(oper_cfg.vpss_regs_base1)) return PTR_ERR(oper_cfg.vpss_regs_base1); } if (oper_cfg.platform == DM355) { oper_cfg.hw_ops.enable_clock = dm355_enable_clock; oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source; /* Setup vpss interrupts */ bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL); bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL); } else if (oper_cfg.platform == DM365) { oper_cfg.hw_ops.enable_clock = dm365_enable_clock; oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source; /* Setup vpss interrupts */ isp5_write((isp5_read(DM365_ISP5_PCCR) | DM365_ISP5_PCCR_BL_CLK_ENABLE | DM365_ISP5_PCCR_ISIF_CLK_ENABLE | DM365_ISP5_PCCR_H3A_CLK_ENABLE | DM365_ISP5_PCCR_RSZ_CLK_ENABLE | DM365_ISP5_PCCR_IPIPE_CLK_ENABLE | DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE | DM365_ISP5_PCCR_RSV), DM365_ISP5_PCCR); isp5_write((isp5_read(DM365_ISP5_BCR) | DM365_ISP5_BCR_ISIF_OUT_ENABLE), DM365_ISP5_BCR); isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1); isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2); isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3); } else oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow; pm_runtime_enable(&pdev->dev); pm_runtime_get(&pdev->dev); spin_lock_init(&oper_cfg.vpss_lock); dev_info(&pdev->dev, "%s vpss probe success\n", platform_name); return 0; }