static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) { struct nop_usb_xceiv *nop; int err; nop = kzalloc(sizeof *nop, GFP_KERNEL); if (!nop) return -ENOMEM; nop->dev = &pdev->dev; nop->otg.dev = nop->dev; nop->otg.label = "nop-xceiv"; nop->otg.state = OTG_STATE_UNDEFINED; nop->otg.set_host = nop_set_host; nop->otg.set_peripheral = nop_set_peripheral; nop->otg.set_suspend = nop_set_suspend; nop->otg.id = pdev->id; err = otg_set_transceiver(&nop->otg); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto exit; } platform_set_drvdata(pdev, nop); ATOMIC_INIT_NOTIFIER_HEAD(&nop->otg.notifier); return 0; exit: kfree(nop); return err; }
static int __init msm_cpuidle_early_init(void) { #ifdef CONFIG_MSM_SLEEP_STATS unsigned int cpu; for_each_possible_cpu(cpu) ATOMIC_INIT_NOTIFIER_HEAD(&per_cpu(msm_cpuidle_notifiers, cpu)); #endif return 0; }
static int mxs_phy_probe(struct platform_device *pdev) { struct resource *res; void __iomem *base; struct clk *clk; struct mxs_phy *mxs_phy; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "can't get device resources\n"); return -ENOENT; } base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "can't get the clock, err=%ld", PTR_ERR(clk)); return PTR_ERR(clk); } mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); if (!mxs_phy) { dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); return -ENOMEM; } mxs_phy->phy.io_priv = base; mxs_phy->phy.dev = &pdev->dev; mxs_phy->phy.label = DRIVER_NAME; mxs_phy->phy.init = mxs_phy_init; mxs_phy->phy.shutdown = mxs_phy_shutdown; mxs_phy->phy.set_suspend = mxs_phy_suspend; mxs_phy->phy.notify_connect = mxs_phy_on_connect; mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); mxs_phy->clk = clk; platform_set_drvdata(pdev, &mxs_phy->phy); ret = usb_add_phy_dev(&mxs_phy->phy); if (ret) return ret; return 0; }
int ocmem_notifier_init(void) { int id; /* Maximum notifiers for each subsystem */ notifier_threshold = 1; mutex_lock(&nc_lock); for (id = 0; id < OCMEM_CLIENT_MAX; id++) { notifiers[id].owner = id; ATOMIC_INIT_NOTIFIER_HEAD(¬ifiers[id].nc); notifiers[id].listeners = 0; } mutex_unlock(&nc_lock); return 0; }
static int __init opal_message_init(void) { int ret, i; for (i = 0; i < OPAL_MSG_TYPE_MAX; i++) ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]); ret = opal_notifier_register(&opal_message_nb); if (ret) { pr_err("%s: Can't register OPAL event notifier (%d)\n", __func__, ret); return ret; } return 0; }
//init function for switch_usb_class mode static int __init switch_usb_class_init(void) { int ret = 0; struct switch_usb_info *sui; hwlog_info("%s: ------entry.\n", __func__); ret = platform_driver_register(&usb_switch_driver); if(NULL == p_switch_usb_info) { sui = kzalloc(sizeof(struct switch_usb_info), GFP_KERNEL); if(NULL == sui) { pr_err("kzalloc failed!\n"); return -ENOMEM; } p_switch_usb_info = sui; ATOMIC_INIT_NOTIFIER_HEAD(&sui->charger_type_notifier_head); spin_lock_init(&sui->reg_flag_lock); } hwlog_info("%s: ------end. ret=%d\n", __func__, ret); return ret; }
static int __devinit archos_twl6030_usb_probe(struct platform_device *pdev) { struct archos_twl6030_usb *twl; int status, err; struct twl4030_usb_data *pdata; struct device *dev = &pdev->dev; pdata = dev->platform_data; twl = kzalloc(sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); twl->otg.dev = twl->dev; twl->otg.label = "twl6030"; twl->otg.set_host = archos_twl6030_set_host; twl->otg.set_peripheral = archos_twl6030_set_peripheral; twl->asleep = 1; twl->otg.set_vbus = archos_twl6030_set_vbus; twl->otg.init = archos_twl6030_phy_init; twl->otg.shutdown = archos_twl6030_phy_shutdown; twl->otg.enable_irq = archos_twl6030_enable_irq; twl->features = pdata->features; twl->state = STATE_UNKNOWN; /* init spinlock for workqueue */ spin_lock_init(&twl->lock); err = archos_twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); kfree(twl); return err; } platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); twl->irq_enabled = true; status = request_irq(twl->irq1, archos_twl6030_usbotg_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "archos_twl6030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq1, status); device_remove_file(twl->dev, &dev_attr_vbus); kfree(twl); return status; } status = request_irq(twl->irq2, archos_twl6030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "archos_twl6030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq2, status); free_irq(twl->irq1, twl); device_remove_file(twl->dev, &dev_attr_vbus); kfree(twl); return status; } INIT_DELAYED_WORK(&twl->work, linkstat_work); /* only active when a gadget is registered */ err = otg_set_transceiver(&twl->otg); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto err_otg; } twl->vbus_draw = regulator_get(&pdev->dev, "vbus_musb"); if (IS_ERR(twl->vbus_draw)) { dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", PTR_ERR(twl->vbus_draw)); twl->vbus_draw = NULL; goto err_otg; } /* initialize switches */ twl->usb_switch.name = USB_SW_NAME; twl->usb_switch.print_name = usb_switch_print_name; twl->usb_switch.print_state = usb_switch_print_state; if (switch_dev_register(&twl->usb_switch) < 0) { dev_err(&pdev->dev, "Error creating USB switch\n"); goto err_switch; } twl->asleep = 0; pdata->phy_init(dev); archos_twl6030_enable_irq(&twl->otg); dev_err(&pdev->dev, "Initialized Archos TWL6030 USB module\n"); return 0; err_switch: regulator_put(twl->vbus_draw); err_otg: device_remove_file(twl->dev, &dev_attr_vbus); free_irq(twl->irq1, twl); free_irq(twl->irq2, twl); kfree(twl); return err; }
static int cpcap_otg_probe(struct platform_device *pdev) { struct cpcap_otg_data *cpcap; struct resource *res; unsigned long val; int err; cpcap = kzalloc(sizeof(struct cpcap_otg_data), GFP_KERNEL); if (!cpcap) return -ENOMEM; cpcap->otg.dev = &pdev->dev; cpcap->otg.label = "cpcap-otg"; cpcap->otg.state = OTG_STATE_UNDEFINED; cpcap->otg.set_host = cpcap_otg_set_host; cpcap->otg.set_peripheral = cpcap_otg_set_peripheral; cpcap->otg.set_suspend = cpcap_otg_set_suspend; cpcap->otg.set_power = cpcap_otg_set_power; cpcap->host = pdev->dev.platform_data; wake_lock_init(&cpcap->wake_lock, WAKE_LOCK_SUSPEND, "cpcap_otg"); platform_set_drvdata(pdev, cpcap); cpcap->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(cpcap->clk)) { dev_err(&pdev->dev, "Can't get otg clock\n"); err = PTR_ERR(cpcap->clk); goto err_clk; } err = clk_enable(cpcap->clk); if (err) goto err_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 err_io; } cpcap->regs = ioremap(res->start, resource_size(res)); if (!cpcap->regs) { err = -ENOMEM; goto err_io; } val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); val |= TEGRA_VBUS_WAKEUP_SW_ENABLE | TEGRA_ID_SW_ENABLE; val |= TEGRA_ID_SW_VALUE; val &= ~(TEGRA_VBUS_WAKEUP_SW_VALUE); writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); clk_disable(cpcap->clk); cpcap->otg.state = OTG_STATE_A_SUSPEND; ATOMIC_INIT_NOTIFIER_HEAD(&cpcap->otg.notifier); cpcap->nb.notifier_call = cpcap_otg_notify; otg_register_notifier(&cpcap->otg, &cpcap->nb); err = otg_set_transceiver(&cpcap->otg); if (err) { dev_err(&pdev->dev, "can't register transceiver (%d)\n", err); goto err_otg; } return 0; err_otg: iounmap(cpcap->regs); err_io: clk_disable(cpcap->clk); err_clken: clk_put(cpcap->clk); err_clk: wake_lock_destroy(&cpcap->wake_lock); platform_set_drvdata(pdev, NULL); kfree(cpcap); return err; }
static int twl4030_usb_probe(struct platform_device *pdev) { struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); struct twl4030_usb *twl; struct phy *phy; int status, err; struct usb_otg *otg; struct device_node *np = pdev->dev.of_node; struct phy_provider *phy_provider; struct phy_init_data *init_data = NULL; twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); if (!twl) return -ENOMEM; if (np) of_property_read_u32(np, "usb_mode", (enum twl4030_usb_mode *)&twl->usb_mode); else if (pdata) { twl->usb_mode = pdata->usb_mode; init_data = pdata->init_data; } else { dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); return -EINVAL; } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) return -ENOMEM; twl->dev = &pdev->dev; twl->irq = platform_get_irq(pdev, 0); twl->vbus_supplied = false; twl->asleep = 1; twl->linkstat = OMAP_MUSB_UNKNOWN; twl->phy.dev = twl->dev; twl->phy.label = "twl4030"; twl->phy.otg = otg; twl->phy.type = USB_PHY_TYPE_USB2; otg->phy = &twl->phy; otg->set_host = twl4030_set_host; otg->set_peripheral = twl4030_set_peripheral; phy = devm_phy_create(twl->dev, NULL, &ops, init_data); if (IS_ERR(phy)) { dev_dbg(&pdev->dev, "Failed to create PHY\n"); return PTR_ERR(phy); } phy_set_drvdata(phy, twl); phy_provider = devm_of_phy_provider_register(twl->dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); /* init spinlock for workqueue */ spin_lock_init(&twl->lock); INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); err = twl4030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); return err; } usb_add_phy_dev(&twl->phy); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); /* Our job is to use irqs and status from the power module * to keep the transceiver disabled when nothing's connected. * * FIXME we actually shouldn't start enabling it until the * USB controller drivers have said they're ready, by calling * set_host() and/or set_peripheral() ... OTG_capable boards * need both handles, otherwise just one suffices. */ twl->irq_enabled = true; status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, twl4030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); return status; } dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); return 0; }
static int __devinit twl4030_usb_probe(struct platform_device *pdev) { struct twl4030_usb_data *pdata = pdev->dev.platform_data; struct twl4030_usb *twl; int status, err; struct usb_otg *otg; if (!pdata) { dev_dbg(&pdev->dev, "platform_data not available\n"); return -EINVAL; } twl = kzalloc(sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; otg = kzalloc(sizeof *otg, GFP_KERNEL); if (!otg) { kfree(twl); return -ENOMEM; } twl->dev = &pdev->dev; twl->irq = platform_get_irq(pdev, 0); twl->usb_mode = pdata->usb_mode; twl->vbus_supplied = false; twl->asleep = 1; twl->phy.dev = twl->dev; twl->phy.label = "twl4030"; twl->phy.otg = otg; twl->phy.set_suspend = twl4030_set_suspend; otg->phy = &twl->phy; otg->set_host = twl4030_set_host; otg->set_peripheral = twl4030_set_peripheral; spin_lock_init(&twl->lock); err = twl4030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); kfree(otg); kfree(twl); return err; } usb_set_transceiver(&twl->phy); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); twl->irq_enabled = true; status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl4030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); kfree(otg); kfree(twl); return status; } twl4030_usb_phy_init(twl); dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); return 0; }
static int __devinit twl6030_usb_probe(struct platform_device *pdev) { struct twl6030_usb *twl; int status, err; struct twl4030_usb_data *pdata; struct device *dev = &pdev->dev; pdata = dev->platform_data; twl = kzalloc(sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); twl->features = pdata->features; twl->otg.dev = twl->dev; twl->otg.label = "twl6030"; twl->otg.set_host = twl6030_set_host; twl->otg.set_peripheral = twl6030_set_peripheral; twl->otg.set_vbus = twl6030_set_vbus; twl->otg.init = twl6030_phy_init; twl->otg.shutdown = twl6030_phy_shutdown; twl->otg.set_suspend = twl6030_phy_suspend; twl->otg.start_srp = twl6030_start_srp; /* init spinlock for workqueue */ spin_lock_init(&twl->lock); err = twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); kfree(twl); return err; } otg_set_transceiver(&twl->otg); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); twl->irq_enabled = true; status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq1, status); device_remove_file(twl->dev, &dev_attr_vbus); kfree(twl); return status; } status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq2, status); free_irq(twl->irq1, twl); device_remove_file(twl->dev, &dev_attr_vbus); kfree(twl); return status; } twl->asleep = 0; pdata->phy_init(dev); twl6030_phy_suspend(&twl->otg, 0); twl6030_enable_irq(&twl->otg); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); return 0; }
static struct dwc_otg2 *dwc3_otg_alloc(struct device *dev) { struct dwc_otg2 *otg = NULL; struct usb_phy *usb_phy; int retval; otg = kzalloc(sizeof(*otg), GFP_KERNEL); if (!otg) { dev_err(dev, "Alloc otg failed\n"); return NULL; } the_transceiver = otg; otg->otg_data = dev->platform_data; usb_phy = &otg->usb2_phy; otg->otg.phy = usb_phy; otg->usb2_phy.otg = &otg->otg; otg->dev = dev; otg->usb3_phy.dev = otg->dev; otg->usb3_phy.label = "dwc-usb3-phy"; otg->usb3_phy.state = OTG_STATE_UNDEFINED; otg->usb3_phy.otg = &otg->otg; otg->usb2_phy.dev = otg->dev; otg->usb2_phy.label = "dwc-usb2-phy"; otg->usb2_phy.state = OTG_STATE_UNDEFINED; otg->usb2_phy.set_power = dwc3_otg_pdata->set_power; otg->usb2_phy.get_chrg_status = dwc_otg_get_chrg_status; otg->usb2_phy.io_ops = &dwc_otg_io_ops; otg->usb2_phy.otg = &otg->otg; otg->otg.set_host = dwc_otg2_set_host; otg->otg.set_peripheral = dwc_otg2_set_peripheral; ATOMIC_INIT_NOTIFIER_HEAD(&otg->usb2_phy.notifier); ATOMIC_INIT_NOTIFIER_HEAD(&otg->usb3_phy.notifier); otg->state = DWC_STATE_B_IDLE; spin_lock_init(&otg->lock); init_waitqueue_head(&otg->main_wq); /* Register otg notifier to monitor ID and VBus change events */ otg->nb.notifier_call = dwc_otg_handle_notification; usb_register_notifier(&otg->usb2_phy, &otg->nb); otg_dbg(otg, "Version: %s\n", VERSION); retval = usb_add_phy(&otg->usb2_phy, USB_PHY_TYPE_USB2); if (retval) { otg_err(otg, "can't register transceiver, err: %d\n", retval); goto err1; } retval = usb_add_phy(&otg->usb3_phy, USB_PHY_TYPE_USB3); if (retval) { otg_err(otg, "can't register transceiver, err: %d\n", retval); goto err2; } return otg; err2: usb_remove_phy(&otg->usb2_phy); err1: kfree(otg); otg = NULL; return otg; }
static int __devinit bcmpmu_otg_xceiv_probe(struct platform_device *pdev) { int error = 0; struct bcmpmu_otg_xceiv_data *xceiv_data; struct bcmpmu *bcmpmu = pdev->dev.platform_data; dev_info(&pdev->dev, "Probing started...\n"); xceiv_data = kzalloc(sizeof(*xceiv_data), GFP_KERNEL); if (!xceiv_data) { dev_warn(&pdev->dev, "Memory allocation failed\n"); return -ENOMEM; } /* REVISIT: Currently there isn't a way to obtain * regulator string associated with USB. Hardcode for now */ xceiv_data->bcm_hsotg_regulator = regulator_get(NULL, "usbldo_uc"); if (IS_ERR(xceiv_data->bcm_hsotg_regulator)) { dev_warn(&pdev->dev, "Failed to get regulator handle\n"); kfree(xceiv_data); return -ENODEV; } /* Enable USB LDO */ regulator_enable(xceiv_data->bcm_hsotg_regulator); xceiv_data->regulator_enabled = true; /* Give 2ms to ramp up USBLDO */ mdelay(USBLDO_RAMP_UP_DELAY_IN_MS); xceiv_data->dev = &pdev->dev; xceiv_data->bcmpmu = bcmpmu; xceiv_data->otg_xceiver.xceiver.dev = xceiv_data->dev; xceiv_data->otg_xceiver.xceiver.label = "bcmpmu_otg_xceiv"; xceiv_data->host = false; xceiv_data->vbus_enabled = false; /* Create a work queue for OTG work items */ xceiv_data->bcm_otg_work_queue = create_workqueue("bcm_otg_events"); if (xceiv_data->bcm_otg_work_queue == NULL) { dev_warn(&pdev->dev, "BCM OTG events work queue creation failed\n"); bcmpmu_otg_free_regulator(xceiv_data); kfree(xceiv_data); return -ENOMEM; } /* Create one work item per deferrable function */ INIT_WORK(&xceiv_data->bcm_otg_vbus_invalid_work, bcmpmu_otg_xceiv_vbus_invalid_handler); INIT_WORK(&xceiv_data->bcm_otg_vbus_valid_work, bcmpmu_otg_xceiv_vbus_valid_handler); INIT_WORK(&xceiv_data->bcm_otg_vbus_a_invalid_work, bcmpmu_otg_xceiv_vbus_a_invalid_handler); INIT_WORK(&xceiv_data->bcm_otg_vbus_a_valid_work, bcmpmu_otg_xceiv_vbus_a_valid_handler); INIT_WORK(&xceiv_data->bcm_otg_id_status_change_work, bcmpmu_otg_xceiv_id_change_handler); INIT_WORK(&xceiv_data->bcm_otg_chg_detect_work, bcmpmu_otg_xceiv_chg_detect_handler); INIT_WORK(&xceiv_data->bcm_otg_sess_end_srp_work, bcmpmu_otg_xceiv_sess_end_srp_handler); INIT_DELAYED_WORK(&xceiv_data->bcm_otg_delayed_adp_work, bcmpmu_otg_xceiv_delayed_adp_handler); /* Initial value for previous OTG ID value. * 0 means unsupported */ xceiv_data->prev_otg_id = 0; /* Charger type not known yet */ xceiv_data->usb_charger_type = PMU_USB_TYPE_NONE; xceiv_data->otg_xceiver.xceiver.state = OTG_STATE_UNDEFINED; xceiv_data->otg_xceiver.xceiver.set_vbus = bcmpmu_otg_xceiv_set_vbus; xceiv_data->otg_xceiver.xceiver.set_peripheral = bcmpmu_otg_xceiv_set_peripheral; xceiv_data->otg_xceiver.xceiver.set_host = bcmpmu_otg_xceiv_set_host; xceiv_data->otg_xceiver.xceiver.shutdown = bcmpmu_otg_xceiv_shutdown; xceiv_data->otg_xceiver.xceiver.init = bcmpmu_otg_xceiv_start; xceiv_data->otg_xceiver.xceiver.set_power = bcmpmu_otg_xceiv_set_vbus_power; xceiv_data->otg_xceiver.xceiver.set_delayed_adp = bcmpmu_otg_xceiv_set_delayed_adp; xceiv_data->otg_xceiver.xceiver.set_srp_reqd = bcmpmu_otg_xceiv_set_srp_reqd_handler; xceiv_data->otg_xceiver.xceiver.pullup_on = bcmpmu_otg_xceiv_pullup_on; xceiv_data->otg_xceiver.xceiver.set_otg_enable = bcmpmu_otg_xceiv_set_otg_enable; xceiv_data->otg_xceiver.xceiver.set_suspend = bcmpmu_otg_xceiv_set_suspend; ATOMIC_INIT_NOTIFIER_HEAD(&xceiv_data->otg_xceiver.xceiver.notifier); xceiv_data->bcm_otg_vbus_validity_notifier.notifier_call = bcmpmu_otg_xceiv_vbus_notif_handler; bcmpmu_add_notifier(BCMPMU_USB_EVENT_VBUS_VALID, &xceiv_data->bcm_otg_vbus_validity_notifier); xceiv_data->bcm_otg_vbus_invalidity_notifier.notifier_call = bcmpmu_otg_xceiv_vbus_invalid_notif_handler; bcmpmu_add_notifier(BCMPMU_USB_EVENT_VBUS_INVALID, &xceiv_data->bcm_otg_vbus_invalidity_notifier); bcmpmu_add_notifier(BCMPMU_USB_EVENT_SESSION_INVALID, &xceiv_data->bcm_otg_vbus_validity_notifier); xceiv_data->bcm_otg_id_chg_notifier.notifier_call = bcmpmu_otg_xceiv_id_chg_notif_handler; bcmpmu_add_notifier(BCMPMU_USB_EVENT_ID_CHANGE, &xceiv_data->bcm_otg_id_chg_notifier); xceiv_data->bcm_otg_chg_detection_notifier.notifier_call = bcmpmu_otg_xceiv_chg_detection_notif_handler; bcmpmu_add_notifier(BCMPMU_USB_EVENT_USB_DETECTION, &xceiv_data->bcm_otg_chg_detection_notifier); wake_lock_init(&xceiv_data->otg_xceiver.xceiver_wake_lock, WAKE_LOCK_SUSPEND, "otg_xcvr_wakelock"); #ifdef CONFIG_USB_OTG init_timer(&xceiv_data->otg_xceiver.srp_failure_timer); xceiv_data->otg_xceiver.srp_failure_timer.data = (unsigned long)xceiv_data; xceiv_data->otg_xceiver.srp_failure_timer.function = bcmpmu_otg_xceiv_srp_failure_handler; init_timer(&xceiv_data->otg_xceiver.sess_end_srp_timer); xceiv_data->otg_xceiver.sess_end_srp_timer.data = (unsigned long)xceiv_data; xceiv_data->otg_xceiver.sess_end_srp_timer.function = bcmpmu_otg_xceiv_sess_end_srp_timer_handler; error = bcm_otg_adp_init(xceiv_data); if (error) goto error_attr_host; #endif otg_set_transceiver(&xceiv_data->otg_xceiver.xceiver); local_otg_xceiver = &xceiv_data->otg_xceiver.xceiver; platform_set_drvdata(pdev, xceiv_data); error = device_create_file(&pdev->dev, &dev_attr_host); if (error) { dev_warn(&pdev->dev, "Failed to create HOST file\n"); goto error_attr_host;; } error = device_create_file(&pdev->dev, &dev_attr_vbus); if (error) { dev_warn(&pdev->dev, "Failed to create VBUS file\n"); goto error_attr_vbus; } error = device_create_file(&pdev->dev, &dev_attr_wake); if (error) { dev_warn(&pdev->dev, "Failed to create WAKE file\n"); goto error_attr_wake; } /* Save original ID value */ bcmpmu_usb_get(xceiv_data->bcmpmu, BCMPMU_USB_CTRL_GET_ID_VALUE, &xceiv_data->prev_otg_id); /* Check if we should default to A-device */ xceiv_data->otg_xceiver.xceiver.default_a = bcmpmu_otg_xceiv_check_id_gnd(xceiv_data) || bcmpmu_otg_xceiv_check_id_rid_a(xceiv_data); bcmpmu_otg_xceiv_set_def_state(xceiv_data, xceiv_data->otg_xceiver.xceiver.default_a); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); dev_info(&pdev->dev, "Probing successful\n"); return 0; error_attr_wake: device_remove_file(xceiv_data->dev, &dev_attr_vbus); error_attr_vbus: device_remove_file(xceiv_data->dev, &dev_attr_host); error_attr_host: wake_lock_destroy(&xceiv_data->otg_xceiver.xceiver_wake_lock); destroy_workqueue(xceiv_data->bcm_otg_work_queue); bcmpmu_otg_free_regulator(xceiv_data); kfree(xceiv_data); return error; }
int set_otg_notify(struct otg_notify *n) { int ret = 0; if (!u_notify) { ret = create_usb_notify(); if (ret) { pr_err("unable create_usb_notify\n"); goto err; } } if (u_notify->o_notify && n) { pr_err("error : already set o_notify\n"); goto err; } pr_info("registered otg_notify +\n"); if (!n) { pr_err("otg notify structure is null\n"); ret = -EFAULT; goto err1; } u_notify->o_notify = n; ATOMIC_INIT_NOTIFIER_HEAD(&u_notify->o_notify->otg_notifier); u_notify->otg_nb.notifier_call = otg_notifier_callback; ret = atomic_notifier_chain_register(&u_notify->o_notify->otg_notifier, &u_notify->otg_nb); if (ret < 0) { pr_err("atomic_notifier_chain_register failed\n"); goto err1; } BLOCKING_INIT_NOTIFIER_HEAD(&u_notify->o_notify->extra_notifier); u_notify->extra_nb.notifier_call = extra_notifier_callback; ret = blocking_notifier_chain_register (&u_notify->o_notify->extra_notifier, &u_notify->extra_nb); if (ret < 0) { pr_err("blocking_notifier_chain_register failed\n"); goto err2; } if (!n->unsupport_host) { u_notify->ndev.name = "usb_otg"; u_notify->ndev.set_booster = n->vbus_drive; ret = host_notify_dev_register(&u_notify->ndev); if (ret < 0) { pr_err("host_notify_dev_register is failed\n"); goto err3; } if (!n->vbus_drive) { pr_err("vbus_drive is null\n"); goto err4; } } if (gpio_is_valid(n->vbus_detect_gpio) || gpio_is_valid(n->redriver_en_gpio)) { ret = register_gpios(n); if (ret < 0) { pr_err("register_gpios is failed\n"); goto err4; } } if (n->is_wakelock) wake_lock_init(&u_notify->wlock, WAKE_LOCK_SUSPEND, "usb_notify"); if (n->booting_delay_sec) { INIT_DELAYED_WORK(&u_notify->b_delay.booting_work, reserve_state_check); schedule_delayed_work(&u_notify->b_delay.booting_work, n->booting_delay_sec*HZ); } register_usbdev_notify(); pr_info("registered otg_notify -\n"); return 0; err4: if (!n->unsupport_host) host_notify_dev_unregister(&u_notify->ndev); err3: blocking_notifier_chain_unregister(&u_notify->o_notify->extra_notifier, &u_notify->extra_nb); err2: atomic_notifier_chain_unregister(&u_notify->o_notify->otg_notifier, &u_notify->otg_nb); err1: u_notify->o_notify = NULL; err: return ret; }
static int nop_usb_xceiv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; struct nop_usb_xceiv *nop; enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; u32 clk_rate = 0; bool needs_vcc = false; bool needs_reset = false; nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); if (!nop) return -ENOMEM; nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), GFP_KERNEL); if (!nop->phy.otg) return -ENOMEM; if (dev->of_node) { struct device_node *node = dev->of_node; if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; needs_vcc = of_property_read_bool(node, "vcc-supply"); needs_reset = of_property_read_bool(node, "reset-supply"); } else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate; needs_vcc = pdata->needs_vcc; needs_reset = pdata->needs_reset; } nop->clk = devm_clk_get(&pdev->dev, "main_clk"); if (IS_ERR(nop->clk)) { dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", PTR_ERR(nop->clk)); } if (!IS_ERR(nop->clk) && clk_rate) { err = clk_set_rate(nop->clk, clk_rate); if (err) { dev_err(&pdev->dev, "Error setting clock rate\n"); return err; } } if (!IS_ERR(nop->clk)) { err = clk_prepare(nop->clk); if (err) { dev_err(&pdev->dev, "Error preparing clock\n"); return err; } } nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); if (IS_ERR(nop->vcc)) { dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", PTR_ERR(nop->vcc)); if (needs_vcc) return -EPROBE_DEFER; } nop->reset = devm_regulator_get(&pdev->dev, "reset"); if (IS_ERR(nop->reset)) { dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", PTR_ERR(nop->reset)); if (needs_reset) return -EPROBE_DEFER; } nop->dev = &pdev->dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; nop->phy.init = nop_init; nop->phy.shutdown = nop_shutdown; nop->phy.state = OTG_STATE_UNDEFINED; nop->phy.type = type; nop->phy.otg->phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; err = usb_add_phy_dev(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto err_add; } platform_set_drvdata(pdev, nop); ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; err_add: if (!IS_ERR(nop->clk)) clk_unprepare(nop->clk); return err; }
STATIC int hiusb_init_resource(struct lm_device *dev) { int ret = 0; struct lm_device *lm_dev; struct hiusb_info *hiusb_info; lm_dev = dev; hiusb_info = dev->hiusb_info; ATOMIC_INIT_NOTIFIER_HEAD(&hiusb_info->charger_type_notifier_head); spin_lock_init(&hiusb_info->intr_flag_lock); wake_lock_init(&hiusb_info->dev_wakelock, WAKE_LOCK_SUSPEND, "hiusb_dev_wakelock"); wake_lock_init(&hiusb_info->host_wakelock, WAKE_LOCK_SUSPEND, "hiusb_host_wakelock"); sema_init(&hiusb_info->hiusb_info_sema, 0); spin_lock_init(&hiusb_info->switch_lock); hiusb_info->charger_type = CHARGER_REMOVED; hiusb_info->hiusb_status = HIUSB_OFF; hiusb_info->gadget_enable = 0; get_hw_config_int("usb/otg_without_mhl", &hiusb_info->otg_without_mhl, NULL); dev_info(&lm_dev->dev, "otg_without_mhl:%d.\n", hiusb_info->otg_without_mhl); ret = get_hw_config_int("usb/gpio_otg_int", &hiusb_info->otg_int_gpio, NULL); dev_info(&lm_dev->dev, "gpio_otg_int:%d.\n", hiusb_info->otg_int_gpio); hiusb_info->usb_block = iomux_get_block("block_switch"); hiusb_info->usb_config = iomux_get_blockconfig("block_switch"); hiusb_info->clk_usbotg_off= clk_get(NULL, "clk_usbotg_off"); ret = IS_ERR(hiusb_info->clk_usbotg_off); if (ret) { dev_err(&lm_dev->dev, "get clk_usbotg_off failed!\n"); goto get_clk_usbotg_off_fail; } #if defined(CHIP_BB_HI6210)/*B020 Modify*/ #else hiusb_info->clk_picophy= clk_get(NULL, "clk_picophy"); ret = IS_ERR(hiusb_info->clk_picophy); if (ret) { dev_err(&lm_dev->dev, "get clk_picophy failed!\n"); goto get_clk_picophy_fail; } #endif switch_init(lm_dev); if (hiusb_info->vbus_pin != 0) { ret = gpio_request(hiusb_info->vbus_pin, "USB_VBUS"); if (ret < 0) { dev_err(&dev->dev, "%s usb vbus gpio error", __func__); goto request_vbus_pin_fail; } gpio_direction_output(hiusb_info->vbus_pin, 0); } if (hiusb_info->phy_reset_pin != 0) { ret = gpio_request(hiusb_info->phy_reset_pin, "USBPHY_REST"); if (ret < 0) { dev_err(&dev->dev, "%s usb phy reset gpio error", __func__); goto request_gpio_fail; } gpio_direction_output(hiusb_info->phy_reset_pin, 0); mdelay(100); gpio_direction_output(hiusb_info->phy_reset_pin, 1); } if (hiusb_info->otg_int_gpio != -1) { ret = gpio_request(hiusb_info->otg_int_gpio, "OTG_INT_GPIO"); if (ret < 0) { dev_err(&dev->dev, "%s usb otg int gpio error", __func__); goto request_gpio_fail; } gpio_direction_input(hiusb_info->otg_int_gpio); } /* init workqueue for usb insert/draw : only for debug */ INIT_DELAYED_WORK(&hiusb_info->otg_intr_work, hiusb_otg_intr_work); dev_info(&lm_dev->dev, "%s.\n", __func__); return 0; request_gpio_fail: if (hiusb_info->vbus_pin != 0) { gpio_free(hiusb_info->vbus_pin); } request_vbus_pin_fail: #if defined(CHIP_BB_HI6210)/*B020 Modify*/ #else clk_put(hiusb_info->clk_picophy); #endif get_clk_picophy_fail: clk_put(hiusb_info->clk_usbotg_off); get_clk_usbotg_off_fail: return ret; }
int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, enum usb_phy_type type, u32 clk_rate, bool needs_vcc) { int err; nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), GFP_KERNEL); if (!nop->phy.otg) return -ENOMEM; nop->clk = devm_clk_get(dev, "main_clk"); if (IS_ERR(nop->clk)) { dev_dbg(dev, "Can't get phy clock: %ld\n", PTR_ERR(nop->clk)); } if (!IS_ERR(nop->clk) && clk_rate) { err = clk_set_rate(nop->clk, clk_rate); if (err) { dev_err(dev, "Error setting clock rate\n"); return err; } } nop->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(nop->vcc)) { dev_dbg(dev, "Error getting vcc regulator: %ld\n", PTR_ERR(nop->vcc)); if (needs_vcc) return -EPROBE_DEFER; } if (gpio_is_valid(nop->gpio_reset)) { unsigned long gpio_flags; /* Assert RESET */ if (nop->reset_active_low) gpio_flags = GPIOF_OUT_INIT_LOW; else gpio_flags = GPIOF_OUT_INIT_HIGH; err = devm_gpio_request_one(dev, nop->gpio_reset, gpio_flags, dev_name(dev)); if (err) { dev_err(dev, "Error requesting RESET GPIO %d\n", nop->gpio_reset); return err; } } nop->dev = dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; nop->phy.state = OTG_STATE_UNDEFINED; nop->phy.type = type; nop->phy.otg->phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; }
int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, struct usb_phy_gen_xceiv_platform_data *pdata) { enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; u32 clk_rate = 0; bool needs_vcc = false; nop->reset_active_low = true; /* default behaviour */ if (dev->of_node) { struct device_node *node = dev->of_node; enum of_gpio_flags flags = 0; if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; needs_vcc = of_property_read_bool(node, "vcc-supply"); nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios", 0, &flags); if (nop->gpio_reset == -EPROBE_DEFER) return -EPROBE_DEFER; nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW; } else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate; needs_vcc = pdata->needs_vcc; nop->gpio_reset = pdata->gpio_reset; } else { nop->gpio_reset = -1; } nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), GFP_KERNEL); if (!nop->phy.otg) return -ENOMEM; nop->clk = devm_clk_get(dev, "main_clk"); if (IS_ERR(nop->clk)) { dev_dbg(dev, "Can't get phy clock: %ld\n", PTR_ERR(nop->clk)); } if (!IS_ERR(nop->clk) && clk_rate) { err = clk_set_rate(nop->clk, clk_rate); if (err) { dev_err(dev, "Error setting clock rate\n"); return err; } } nop->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(nop->vcc)) { dev_dbg(dev, "Error getting vcc regulator: %ld\n", PTR_ERR(nop->vcc)); if (needs_vcc) return -EPROBE_DEFER; } if (gpio_is_valid(nop->gpio_reset)) { unsigned long gpio_flags; /* Assert RESET */ if (nop->reset_active_low) gpio_flags = GPIOF_OUT_INIT_LOW; else gpio_flags = GPIOF_OUT_INIT_HIGH; err = devm_gpio_request_one(dev, nop->gpio_reset, gpio_flags, dev_name(dev)); if (err) { dev_err(dev, "Error requesting RESET GPIO %d\n", nop->gpio_reset); return err; } } nop->dev = dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; nop->phy.state = OTG_STATE_UNDEFINED; nop->phy.type = type; nop->phy.otg->phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; }
static int __init gpio_vbus_probe(struct platform_device *pdev) { struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; struct gpio_vbus_data *gpio_vbus; struct resource *res; int err, gpio, irq; if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) return -EINVAL; gpio = pdata->gpio_vbus; gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); if (!gpio_vbus) return -ENOMEM; gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); if (!gpio_vbus->phy.otg) { kfree(gpio_vbus); return -ENOMEM; } platform_set_drvdata(pdev, gpio_vbus); gpio_vbus->dev = &pdev->dev; gpio_vbus->phy.label = "gpio-vbus"; gpio_vbus->phy.set_power = gpio_vbus_set_power; gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; gpio_vbus->phy.state = OTG_STATE_UNDEFINED; gpio_vbus->phy.otg->phy = &gpio_vbus->phy; gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; err = gpio_request(gpio, "vbus_detect"); if (err) { dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", gpio, err); goto err_gpio; } gpio_direction_input(gpio); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res) { irq = res->start; res->flags &= IRQF_TRIGGER_MASK; res->flags |= IRQF_SAMPLE_RANDOM | IRQF_SHARED; } else irq = gpio_to_irq(gpio); /* if data line pullup is in use, initialize it to "not pulling up" */ gpio = pdata->gpio_pullup; if (gpio_is_valid(gpio)) { err = gpio_request(gpio, "udc_pullup"); if (err) { dev_err(&pdev->dev, "can't request pullup gpio %d, err: %d\n", gpio, err); gpio_free(pdata->gpio_vbus); goto err_gpio; } gpio_direction_output(gpio, pdata->gpio_pullup_inverted); } err = request_irq(irq, gpio_vbus_irq, VBUS_IRQ_FLAGS, "vbus_detect", pdev); if (err) { dev_err(&pdev->dev, "can't request irq %i, err: %d\n", irq, err); goto err_irq; } ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); INIT_WORK(&gpio_vbus->work, gpio_vbus_work); gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); if (IS_ERR(gpio_vbus->vbus_draw)) { dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", PTR_ERR(gpio_vbus->vbus_draw)); gpio_vbus->vbus_draw = NULL; } /* only active when a gadget is registered */ err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto err_otg; } return 0; err_otg: free_irq(irq, &pdev->dev); err_irq: if (gpio_is_valid(pdata->gpio_pullup)) gpio_free(pdata->gpio_pullup); gpio_free(pdata->gpio_vbus); err_gpio: platform_set_drvdata(pdev, NULL); kfree(gpio_vbus->phy.otg); kfree(gpio_vbus); return err; }