static int smsc_hub_remove(struct platform_device *pdev) { const struct smsc_hub_platform_data *pdata; if (!smsc_hub) return 0; pdata = smsc_hub->pdata; if (pdata->model_id == SMSC3502_ID) device_remove_file(&pdev->dev, &dev_attr_enable); if (smsc_hub->client) { i2c_unregister_device(smsc_hub->client); smsc_hub->client = NULL; i2c_del_driver(&hsic_hub_driver); } pm_runtime_disable(&pdev->dev); if (!IS_ERR_OR_NULL(smsc_hub->hub_vbus_reg)) regulator_disable(smsc_hub->hub_vbus_reg); msm_hsic_hub_init_gpio(smsc_hub, 0); msm_hsic_hub_init_clock(smsc_hub, 0); msm_hsic_hub_init_vdd(smsc_hub, 0); return 0; }
static int smsc_hub_remove(struct platform_device *pdev) { const struct smsc_hub_platform_data *pdata; pdata = pdev->dev.platform_data; if (smsc_hub->client) { i2c_unregister_device(smsc_hub->client); smsc_hub->client = NULL; i2c_del_driver(&hsic_hub_driver); } pm_runtime_disable(&pdev->dev); regulator_disable(smsc_hub->hub_vbus_reg); msm_hsic_hub_init_gpio(smsc_hub, 0); msm_hsic_hub_init_clock(smsc_hub, 0); msm_hsic_hub_init_vdd(smsc_hub, 0); return 0; }
static int __devinit smsc_hub_probe(struct platform_device *pdev) { int ret = 0; struct smsc_hub_platform_data *pdata; struct device_node *node = pdev->dev.of_node; struct i2c_adapter *i2c_adap; struct i2c_board_info i2c_info; struct of_dev_auxdata *hsic_host_auxdata = NULL; if (pdev->dev.of_node) { dev_dbg(&pdev->dev, "device tree enabled\n"); pdata = msm_hub_dt_to_pdata(pdev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } else { pdata = pdev->dev.platform_data; } hsic_host_auxdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "No platform data\n"); return -ENODEV; } if (pdata->model_id == 0) { dev_dbg(&pdev->dev, "standalone HSIC config enabled\n"); return of_platform_populate(node, NULL, hsic_host_auxdata, &pdev->dev); } if (!pdata->hub_reset) return -EINVAL; smsc_hub = devm_kzalloc(&pdev->dev, sizeof(*smsc_hub), GFP_KERNEL); if (!smsc_hub) return -ENOMEM; smsc_hub->dev = &pdev->dev; smsc_hub->pdata = pdata; if (of_get_property(pdev->dev.of_node, "hub-vbus-supply", NULL)) { smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub-vbus"); ret = PTR_ERR(smsc_hub->hub_vbus_reg); if (ret == -EPROBE_DEFER) { dev_dbg(&pdev->dev, "failed to get hub_vbus\n"); return ret; } } ret = msm_hsic_hub_init_vdd(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub VDD\n"); return ret; } ret = msm_hsic_hub_init_clock(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub clock\n"); goto uninit_vdd; } ret = msm_hsic_hub_init_gpio(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub gpios\n"); goto uninit_clock; } if (pdata->model_id == SMSC3502_ID) { ret = device_create_file(&pdev->dev, &dev_attr_enable); if (ret < 0) { dev_err(&pdev->dev, "fail to create sysfs file\n"); goto uninit_gpio; } pm_runtime_forbid(&pdev->dev); goto done; } gpio_direction_output(pdata->hub_reset, 0); udelay(5); gpio_direction_output(pdata->hub_reset, 1); if (!IS_ERR_OR_NULL(smsc_hub->hub_vbus_reg)) { ret = regulator_enable(smsc_hub->hub_vbus_reg); if (ret) { dev_err(&pdev->dev, "unable to enable hub_vbus\n"); goto uninit_gpio; } } ret = i2c_add_driver(&hsic_hub_driver); if (ret < 0) { dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n"); goto i2c_add_fail; } usleep_range(10000, 12000); i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID); if (!i2c_adap) { dev_err(&pdev->dev, "failed to get i2c adapter\n"); i2c_del_driver(&hsic_hub_driver); goto i2c_add_fail; } memset(&i2c_info, 0, sizeof(struct i2c_board_info)); strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE); msleep(250); switch (pdata->model_id) { case SMSC3503_ID: normal_i2c[0] = SMSC3503_I2C_ADDR; break; case SMSC4604_ID: normal_i2c[0] = SMSC4604_I2C_ADDR; break; default: dev_err(&pdev->dev, "unsupported SMSC model-id\n"); i2c_put_adapter(i2c_adap); i2c_del_driver(&hsic_hub_driver); goto uninit_gpio; } smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info, normal_i2c, NULL); i2c_put_adapter(i2c_adap); i2c_add_fail: ret = of_platform_populate(node, NULL, hsic_host_auxdata, &pdev->dev); if (ret) { dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret); goto uninit_gpio; } smsc_hub->enabled = true; if (!smsc_hub->client) dev_err(&pdev->dev, "failed to connect to smsc_hub through I2C\n"); done: pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; uninit_gpio: msm_hsic_hub_init_gpio(smsc_hub, 0); uninit_clock: msm_hsic_hub_init_clock(smsc_hub, 0); uninit_vdd: msm_hsic_hub_init_vdd(smsc_hub, 0); return ret; }
static int __devinit smsc_hub_probe(struct platform_device *pdev) { int ret = 0; struct smsc_hub_platform_data *pdata; struct device_node *node = pdev->dev.of_node; struct i2c_adapter *i2c_adap; struct i2c_board_info i2c_info; struct of_dev_auxdata *hsic_host_auxdata = NULL; if (pdev->dev.of_node) { dev_dbg(&pdev->dev, "device tree enabled\n"); hsic_host_auxdata = dev_get_platdata(&pdev->dev); pdata = msm_hub_dt_to_pdata(pdev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } else { pdata = pdev->dev.platform_data; } if (!pdata) { dev_err(&pdev->dev, "No platform data\n"); return -ENODEV; } if (!pdata->hub_reset) return -EINVAL; smsc_hub = devm_kzalloc(&pdev->dev, sizeof(*smsc_hub), GFP_KERNEL); if (!smsc_hub) return -ENOMEM; smsc_hub->dev = &pdev->dev; smsc_hub->pdata = pdata; smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub_vbus"); ret = PTR_ERR(smsc_hub->hub_vbus_reg); if (ret == -EPROBE_DEFER) { dev_dbg(&pdev->dev, "failed to get hub_vbus\n"); return ret; } ret = msm_hsic_hub_init_vdd(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub VDD\n"); return ret; } ret = msm_hsic_hub_init_clock(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub clock\n"); goto uninit_vdd; } ret = msm_hsic_hub_init_gpio(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub gpios\n"); goto uninit_clock; } gpio_direction_output(pdata->hub_reset, 0); /* * Hub reset should be asserted for minimum 2microsec * before deasserting. */ udelay(5); gpio_direction_output(pdata->hub_reset, 1); if (!IS_ERR(smsc_hub->hub_vbus_reg)) { ret = regulator_enable(smsc_hub->hub_vbus_reg); if (ret) { dev_err(&pdev->dev, "unable to enable hub_vbus\n"); goto uninit_gpio; } } ret = i2c_add_driver(&hsic_hub_driver); if (ret < 0) { dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n"); goto i2c_add_fail; } usleep_range(10000, 12000); i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID); if (!i2c_adap) { dev_err(&pdev->dev, "failed to get i2c adapter\n"); i2c_del_driver(&hsic_hub_driver); goto i2c_add_fail; } memset(&i2c_info, 0, sizeof(struct i2c_board_info)); strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE); /* 250ms delay is required for SMSC4604 HUB to get I2C up */ msleep(250); /* Assign I2C slave address per SMSC model */ switch (pdata->model_id) { case SMSC3503_ID: normal_i2c[0] = SMSC3503_I2C_ADDR; break; case SMSC4604_ID: normal_i2c[0] = SMSC4604_I2C_ADDR; break; default: dev_err(&pdev->dev, "unsupported SMSC model-id\n"); i2c_put_adapter(i2c_adap); i2c_del_driver(&hsic_hub_driver); goto uninit_gpio; } smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info, normal_i2c, NULL); i2c_put_adapter(i2c_adap); i2c_add_fail: ret = of_platform_populate(node, NULL, hsic_host_auxdata, &pdev->dev); if (ret) { dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret); goto uninit_gpio; } if (!smsc_hub->client) dev_err(&pdev->dev, "failed to connect to smsc_hub through I2C\n"); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; uninit_gpio: msm_hsic_hub_init_gpio(smsc_hub, 0); uninit_clock: msm_hsic_hub_init_clock(smsc_hub, 0); uninit_vdd: msm_hsic_hub_init_vdd(smsc_hub, 0); return ret; }
static int __devinit smsc_hub_probe(struct platform_device *pdev) { int ret = 0; const struct smsc_hub_platform_data *pdata; struct device_node *node = pdev->dev.of_node; struct i2c_adapter *i2c_adap; struct i2c_board_info i2c_info; if (pdev->dev.of_node) { dev_dbg(&pdev->dev, "device tree enabled\n"); pdev->dev.platform_data = msm_hub_dt_to_pdata(pdev); if (IS_ERR(pdev->dev.platform_data)) return PTR_ERR(pdev->dev.platform_data); dev_set_name(&pdev->dev, smsc_hub_driver.driver.name); } if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "No platform data\n"); return -ENODEV; } pdata = pdev->dev.platform_data; if (!pdata->hub_reset) return -EINVAL; smsc_hub = devm_kzalloc(&pdev->dev, sizeof(*smsc_hub), GFP_KERNEL); if (!smsc_hub) return -ENOMEM; smsc_hub->dev = &pdev->dev; smsc_hub->pdata = pdev->dev.platform_data; smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub_vbus"); ret = PTR_ERR(smsc_hub->hub_vbus_reg); if (ret == -EPROBE_DEFER) { dev_dbg(&pdev->dev, "failed to get hub_vbus\n"); return ret; } ret = msm_hsic_hub_init_vdd(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub VDD\n"); return ret; } ret = msm_hsic_hub_init_clock(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub clock\n"); goto uninit_vdd; } ret = msm_hsic_hub_init_gpio(smsc_hub, 1); if (ret) { dev_err(&pdev->dev, "failed to init hub gpios\n"); goto uninit_clock; } gpio_direction_output(pdata->hub_reset, 0); /* Hub reset should be asserted for minimum 2microsec * before deasserting. */ udelay(5); gpio_direction_output(pdata->hub_reset, 1); ret = of_platform_populate(node, NULL, NULL, &pdev->dev); if (ret) { dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret); goto uninit_gpio; } if (!IS_ERR(smsc_hub->hub_vbus_reg)) { ret = regulator_enable(smsc_hub->hub_vbus_reg); if (ret) { dev_err(&pdev->dev, "unable to enable hub_vbus\n"); goto uninit_gpio; } } ret = i2c_add_driver(&hsic_hub_driver); if (ret < 0) { dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n"); goto i2c_add_fail; } usleep_range(10000, 12000); i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID); if (!i2c_adap) { dev_err(&pdev->dev, "failed to get i2c adapter\n"); i2c_del_driver(&hsic_hub_driver); goto i2c_add_fail; } memset(&i2c_info, 0, sizeof(struct i2c_board_info)); strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE); smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info, normal_i2c, NULL); i2c_put_adapter(i2c_adap); if (!smsc_hub->client) dev_err(&pdev->dev, "failed to connect to smsc_hub" "through I2C\n"); i2c_add_fail: pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; uninit_gpio: msm_hsic_hub_init_gpio(smsc_hub, 0); uninit_clock: msm_hsic_hub_init_clock(smsc_hub, 0); uninit_vdd: msm_hsic_hub_init_vdd(smsc_hub, 0); return ret; }