static int da8xx_rproc_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rproc *rproc = platform_get_drvdata(pdev); struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv; /* * It's important to place the DSP in reset before going away, * since a subsequent insmod of this module may enable the DSP's * clock before its program/boot-address has been loaded and * before this module's probe has had a chance to reset the DSP. * Without the reset, the DSP can lockup permanently when it * begins executing garbage. */ reset_assert(dev); /* * The devm subsystem might end up releasing things before * freeing the irq, thus allowing an interrupt to sneak in while * the device is being removed. This should prevent that. */ disable_irq(drproc->irq); devm_clk_put(dev, drproc->dsp_clk); rproc_del(rproc); rproc_put(rproc); return 0; }
static int hi6401_irq_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct hi6401_irq *irq = platform_get_drvdata(pdev); if(irq->pll_delay_wq) { cancel_delayed_work(&irq->pll_delay_work); flush_workqueue(irq->pll_delay_wq); destroy_workqueue(irq->pll_delay_wq); } if(irq->hi6401_irq_delay_wq) { cancel_delayed_work(&irq->hi6401_irq_delay_work); flush_workqueue(irq->hi6401_irq_delay_wq); destroy_workqueue(irq->hi6401_irq_delay_wq); } free_irq(irq->irq, irq); gpio_free(irq->gpio); clk_disable_unprepare(irq->pmu_audio_clk); devm_clk_put(dev, irq->pmu_audio_clk); clk_disable_unprepare(irq->codec_ssi_clk); devm_clk_put(dev, irq->codec_ssi_clk); codec_ssi_iomux_idle(irq->pctrl); pinctrl_put(irq->pctrl); devm_iounmap(dev, irq->reg_base_addr); devm_release_mem_region(dev, irq->res->start, resource_size(irq->res)); devm_kfree(dev, irq); platform_set_drvdata(pdev, NULL); if (g_dump_buf) { kfree(g_dump_buf); g_dump_buf = NULL; } return 0; }
static int uart_clps711x_remove(struct platform_device *pdev) { struct clps711x_port *s = platform_get_drvdata(pdev); int i; for (i = 0; i < UART_CLPS711X_NR; i++) uart_remove_one_port(&s->uart, &s->port[i]); devm_clk_put(&pdev->dev, s->uart_clk); uart_unregister_driver(&s->uart); platform_set_drvdata(pdev, NULL); return 0; }
/************************************************* Function: bluetooth_power_probe Description: bluetooth power driver probe function Calls: bluetooth_power_rfkill_probe Input: platform_device *pdev Output: Return: int ret Others: NA *************************************************/ static int bluetooth_power_probe(struct platform_device *pdev){ struct device *bluetooth_power_dev = &pdev->dev; struct device_node *np = bluetooth_power_dev->of_node; struct bluetooth_power_private_data *pdev_bluetooth_power_data = NULL; int ret; pdev_bluetooth_power_data = devm_kzalloc(bluetooth_power_dev, sizeof(struct bluetooth_power_private_data), GFP_KERNEL); if ( pdev_bluetooth_power_data == NULL ) { dev_err(bluetooth_power_dev, "failed to allocate bluetooth_power_private_data\n"); return -ENOMEM; } printk(KERN_INFO "bluetooth_power probe in \n"); of_property_read_u32(np, "huawei,bt_en", &(pdev_bluetooth_power_data->gpio_enable.gpio)); of_property_read_u32(np, "huawei,bt_wake_host", &(pdev_bluetooth_power_data->gpio_bt_wake_host.gpio)); of_property_read_u32(np, "huawei,host_wake_bt", &(pdev_bluetooth_power_data->gpio_host_wake_bt.gpio)); printk(KERN_INFO "devm clk get \n"); pdev_bluetooth_power_data->clk = devm_clk_get(bluetooth_power_dev, NULL); printk(KERN_INFO "clk is 0x%x\n", (int)pdev_bluetooth_power_data->clk); if (IS_ERR( pdev_bluetooth_power_data->clk)) { printk(KERN_INFO "Get bt 32k clk failed\n"); ret = PTR_ERR( pdev_bluetooth_power_data->clk ); goto err_free_clk_ret; } /*printk(KERN_INFO "regulator_get in\n"); pdev_bluetooth_power_data->vdd = regulator_get(bluetooth_power_dev,"huawei,bt_power"); // regulator is ldo14 if (IS_ERR( pdev_bluetooth_power_data->vdd )) { printk(KERN_INFO "bt regulator_get failed\n"); pdev_bluetooth_power_data->vdd = NULL; ret = -ENOMEM; goto err_free_clk_ret; // free memory } printk(KERN_INFO "regulator_get out\n");*/ ret = gpio_request( pdev_bluetooth_power_data->gpio_enable.gpio , "bt_gpio_enable" ); if (ret < 0) { pr_err("%s: gpio_request %d failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_enable.gpio ,ret); goto err_free_clk_ret; } ret = gpio_request( pdev_bluetooth_power_data->gpio_host_wake_bt.gpio , "host_wake_bt" ); if (ret < 0) { pr_err("%s: gpio_request %d failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_host_wake_bt.gpio ,ret); goto err_free_clk_ret; } ret = gpio_request( pdev_bluetooth_power_data->gpio_bt_wake_host.gpio , "bt_wake_host" ); if (ret < 0) { pr_err("%s: gpio_request %d failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_bt_wake_host.gpio ,ret); goto err_free_clk_ret; } ret = gpio_direction_output( pdev_bluetooth_power_data->gpio_enable.gpio , 0); if (ret < 0) { pr_err("%s: gpio_direction_output %d failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_enable.gpio ,ret); goto err_free_clk_ret; } ret = gpio_direction_output( pdev_bluetooth_power_data->gpio_host_wake_bt.gpio , 0); if (ret < 0) { pr_err("%s: gpio_direction_output %d failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_host_wake_bt.gpio ,ret); goto err_free_clk_ret; } ret = gpio_direction_input( pdev_bluetooth_power_data->gpio_bt_wake_host.gpio); if (ret < 0) { pr_err("%s: gpio_direction_output %d failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_bt_wake_host.gpio ,ret); goto err_free_clk_ret; } /* set bluetooth vddio voltage to 1.8V */ /*printk(KERN_INFO "regulator_set_voltage in\n"); ret = regulator_set_voltage( pdev_bluetooth_power_data->vdd, BT_VDDIO_LDO_18V, BT_VDDIO_LDO_18V ); printk(KERN_INFO "regulator_set_voltage out\n"); if (ret) { dev_err(&pdev->dev, "%s: bluetooth regulator_set_voltage err %d\n", __func__, ret); goto err_free_clk_ret; }*/ ret = bluetooth_power_rfkill_probe(pdev, pdev_bluetooth_power_data); if (ret) { dev_err(&pdev->dev, "bluetooth_power_rfkill_probe failed, ret:%d\n", ret); goto err_free_clk_ret; } // other code platform_set_drvdata(pdev, pdev_bluetooth_power_data); printk(KERN_INFO "bluetooth_power probe out \n"); return ret; err_free_clk_ret: devm_clk_put(&pdev->dev, pdev_bluetooth_power_data->clk); return ret; }
static int kirkwood_i2s_dev_probe(struct platform_device *pdev) { struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; struct kirkwood_dma_data *priv; struct resource *mem; struct device_node *np = pdev->dev.of_node; int err; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "allocation failed\n"); return -ENOMEM; } dev_set_drvdata(&pdev->dev, priv); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->io = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(priv->io)) return PTR_ERR(priv->io); priv->irq = platform_get_irq(pdev, 0); if (priv->irq <= 0) { dev_err(&pdev->dev, "platform_get_irq failed\n"); return -ENXIO; } if (np) { priv->burst = 128; /* might be 32 or 128 */ } else if (data) { priv->burst = data->burst; } else { dev_err(&pdev->dev, "no DT nor platform data ?!\n"); return -EINVAL; } priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL); if (IS_ERR(priv->clk)) { dev_err(&pdev->dev, "no clock\n"); return PTR_ERR(priv->clk); } err = clk_prepare_enable(priv->clk); if (err < 0) return err; priv->extclk = devm_clk_get(&pdev->dev, "extclk"); if (IS_ERR(priv->extclk)) { if (PTR_ERR(priv->extclk) == -EPROBE_DEFER) return -EPROBE_DEFER; } else { if (priv->extclk == priv->clk) { devm_clk_put(&pdev->dev, priv->extclk); priv->extclk = ERR_PTR(-EINVAL); } else { dev_info(&pdev->dev, "found external clock\n"); clk_prepare_enable(priv->extclk); soc_dai = kirkwood_i2s_dai_extclk; } } /* Some sensible defaults - this reflects the powerup values */ priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; /* Select the burst size */ if (priv->burst == 32) { priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; } else { priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; } err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component, soc_dai, 2); if (err) { dev_err(&pdev->dev, "snd_soc_register_component failed\n"); goto err_component; } err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform); if (err) { dev_err(&pdev->dev, "snd_soc_register_platform failed\n"); goto err_platform; } kirkwood_i2s_init(priv); return 0; err_platform: snd_soc_unregister_component(&pdev->dev); err_component: if (!IS_ERR(priv->extclk)) clk_disable_unprepare(priv->extclk); clk_disable_unprepare(priv->clk); return err; }
static int sp2529_sensor_power(struct device *dev, int on) { int cam_enable, cam_reset; int ret; /* Get the regulators and never put it */ /* * The regulators is for sensor and should be in sensor driver * As SoC camera does not support device tree, leave it here */ mclk = devm_clk_get(dev, "SC2MCLK"); if (IS_ERR(mclk)) return PTR_ERR(mclk); if (!avdd_2v8) { avdd_2v8 = regulator_get(dev, "avdd_2v8"); if (IS_ERR(avdd_2v8)) { dev_warn(dev, "Failed to get regulator avdd_2v8\n"); avdd_2v8 = NULL; } } if (!dovdd_1v8) { dovdd_1v8 = regulator_get(dev, "dovdd_1v8"); if (IS_ERR(dovdd_1v8)) { dev_warn(dev, "Failed to get regulator dovdd_1v8\n"); dovdd_1v8 = NULL; } } if (!af_2v8) { af_2v8 = regulator_get(dev, "af_2v8"); if (IS_ERR(af_2v8)) { dev_warn(dev, "Failed to get regulator af_2v8\n"); af_2v8 = NULL; } } if (!dvdd_1v2) { dvdd_1v2 = regulator_get(dev, "dvdd_1v2"); if (IS_ERR(dvdd_1v2)) { dev_warn(dev, "Failed to get regulator dvdd_1v2\n"); dvdd_1v2 = NULL; } } cam_enable = of_get_named_gpio(dev->of_node, "pwdn-gpios", 0); if (gpio_is_valid(cam_enable)) { if (gpio_request(cam_enable, "CAM2_POWER")) { dev_err(dev, "Request GPIO %d failed\n", cam_enable); goto cam_enable_failed; } } else { dev_err(dev, "invalid pwdn gpio %d\n", cam_enable); goto cam_enable_failed; } cam_reset = of_get_named_gpio(dev->of_node, "reset-gpios", 0); if (gpio_is_valid(cam_reset)) { if (gpio_request(cam_reset, "CAM2_RESET")) { dev_err(dev, "Request GPIO %d failed\n", cam_reset); goto cam_reset_failed; } } else { dev_err(dev, "invalid pwdn gpio %d\n", cam_reset); goto cam_reset_failed; } if (on) { gpio_direction_output(cam_enable, 0); usleep_range(500, 1000); if (avdd_2v8) { regulator_set_voltage(avdd_2v8, 2800000, 2800000); ret = regulator_enable(avdd_2v8); if (ret) goto cam_regulator_enable_failed; } if (af_2v8) { regulator_set_voltage(af_2v8, 2800000, 2800000); ret = regulator_enable(af_2v8); if (ret) goto cam_regulator_enable_failed; } usleep_range(500, 1000); if (dovdd_1v8) { regulator_set_voltage(dovdd_1v8, 1800000, 1800000); ret = regulator_enable(dovdd_1v8); if (ret) goto cam_regulator_enable_failed; } if (dvdd_1v2) { regulator_set_voltage(dvdd_1v2, 1200000, 1200000); ret = regulator_enable(dvdd_1v2); if (ret) goto cam_regulator_enable_failed; } clk_set_rate(mclk, 26000000); clk_prepare_enable(mclk); gpio_direction_output(cam_reset, 0); usleep_range(5000, 20000); gpio_direction_output(cam_enable, 1); usleep_range(5000, 20000); gpio_direction_output(cam_enable, 0); usleep_range(5000, 20000); gpio_direction_output(cam_reset, 1); usleep_range(5000, 20000); } else { gpio_direction_output(cam_reset, 0); usleep_range(5000, 20000); gpio_direction_output(cam_enable, 0); usleep_range(5000, 20000); gpio_direction_output(cam_enable, 1); clk_disable_unprepare(mclk); devm_clk_put(dev, mclk); if (dovdd_1v8) regulator_disable(dovdd_1v8); if (dvdd_1v2) regulator_disable(dvdd_1v2); if (avdd_2v8) regulator_disable(avdd_2v8); if (af_2v8) regulator_disable(af_2v8); } gpio_free(cam_enable); gpio_free(cam_reset); return 0; cam_reset_failed: gpio_free(cam_enable); cam_enable_failed: ret = -EIO; cam_regulator_enable_failed: if (dvdd_1v2) regulator_put(dvdd_1v2); dvdd_1v2 = NULL; if (af_2v8) regulator_put(af_2v8); af_2v8 = NULL; if (dovdd_1v8) regulator_put(dovdd_1v8); dovdd_1v8 = NULL; if (avdd_2v8) regulator_put(avdd_2v8); avdd_2v8 = NULL; return ret; }
static int uart_clps711x_probe(struct platform_device *pdev) { struct clps711x_port *s; int ret, i; s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL); if (!s) { dev_err(&pdev->dev, "Error allocating port structure\n"); return -ENOMEM; } platform_set_drvdata(pdev, s); s->uart_clk = devm_clk_get(&pdev->dev, "uart"); if (IS_ERR(s->uart_clk)) { dev_err(&pdev->dev, "Can't get UART clocks\n"); ret = PTR_ERR(s->uart_clk); goto err_out; } s->uart.owner = THIS_MODULE; s->uart.dev_name = "ttyCL"; s->uart.major = UART_CLPS711X_MAJOR; s->uart.minor = UART_CLPS711X_MINOR; s->uart.nr = UART_CLPS711X_NR; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE s->uart.cons = &s->console; s->uart.cons->device = uart_console_device; s->uart.cons->write = uart_clps711x_console_write; s->uart.cons->setup = uart_clps711x_console_setup; s->uart.cons->flags = CON_PRINTBUFFER; s->uart.cons->index = -1; s->uart.cons->data = s; strcpy(s->uart.cons->name, "ttyCL"); #endif ret = uart_register_driver(&s->uart); if (ret) { dev_err(&pdev->dev, "Registering UART driver failed\n"); devm_clk_put(&pdev->dev, s->uart_clk); goto err_out; } for (i = 0; i < UART_CLPS711X_NR; i++) { s->port[i].line = i; s->port[i].dev = &pdev->dev; s->port[i].irq = TX_IRQ(&s->port[i]); s->port[i].iobase = SYSCON(&s->port[i]); s->port[i].type = PORT_CLPS711X; s->port[i].fifosize = 16; s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; s->port[i].uartclk = clk_get_rate(s->uart_clk); s->port[i].ops = &uart_clps711x_ops; WARN_ON(uart_add_one_port(&s->uart, &s->port[i])); } return 0; err_out: platform_set_drvdata(pdev, NULL); return ret; }
static int mmphw_probe(struct platform_device *pdev) { struct mmp_mach_plat_info *mi; struct resource *res; int ret, i, size, irq; struct mmphw_path_plat *path_plat; struct mmphw_ctrl *ctrl = NULL; /* get resources from platform data */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "%s: no IO memory defined\n", __func__); ret = -ENOENT; goto failed; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "%s: no IRQ defined\n", __func__); ret = -ENOENT; goto failed; } /* get configs from platform data */ mi = pdev->dev.platform_data; if (mi == NULL || !mi->path_num || !mi->paths) { dev_err(&pdev->dev, "%s: no platform data defined\n", __func__); ret = -EINVAL; goto failed; } /* allocate */ size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) * mi->path_num; ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!ctrl) { ret = -ENOMEM; goto failed; } ctrl->name = mi->name; ctrl->path_num = mi->path_num; ctrl->dev = &pdev->dev; ctrl->irq = irq; platform_set_drvdata(pdev, ctrl); mutex_init(&ctrl->access_ok); /* map registers.*/ if (!devm_request_mem_region(ctrl->dev, res->start, resource_size(res), ctrl->name)) { dev_err(ctrl->dev, "can't request region for resource %pR\n", res); ret = -EINVAL; goto failed; } ctrl->reg_base = devm_ioremap_nocache(ctrl->dev, res->start, resource_size(res)); if (ctrl->reg_base == NULL) { dev_err(ctrl->dev, "%s: res %x - %x map failed\n", __func__, res->start, res->end); ret = -ENOMEM; goto failed; } /* request irq */ ret = devm_request_irq(ctrl->dev, ctrl->irq, ctrl_handle_irq, IRQF_SHARED, "lcd_controller", ctrl); if (ret < 0) { dev_err(ctrl->dev, "%s unable to request IRQ %d\n", __func__, ctrl->irq); ret = -ENXIO; goto failed; } /* get clock */ ctrl->clk = devm_clk_get(ctrl->dev, mi->clk_name); if (IS_ERR(ctrl->clk)) { dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name); ret = -ENOENT; goto failed_get_clk; } clk_prepare_enable(ctrl->clk); /* init global regs */ ctrl_set_default(ctrl); /* init pathes from machine info and register them */ for (i = 0; i < ctrl->path_num; i++) { /* get from config and machine info */ path_plat = &ctrl->path_plats[i]; path_plat->id = i; path_plat->ctrl = ctrl; /* path init */ if (!path_init(path_plat, &mi->paths[i])) { ret = -EINVAL; goto failed_path_init; } } #ifdef CONFIG_MMP_DISP_SPI ret = lcd_spi_register(ctrl); if (ret < 0) goto failed_path_init; #endif dev_info(ctrl->dev, "device init done\n"); return 0; failed_path_init: for (i = 0; i < ctrl->path_num; i++) { path_plat = &ctrl->path_plats[i]; path_deinit(path_plat); } if (ctrl->clk) { devm_clk_put(ctrl->dev, ctrl->clk); clk_disable_unprepare(ctrl->clk); } failed_get_clk: devm_free_irq(ctrl->dev, ctrl->irq, ctrl); failed: if (ctrl) { if (ctrl->reg_base) devm_iounmap(ctrl->dev, ctrl->reg_base); devm_release_mem_region(ctrl->dev, res->start, resource_size(res)); devm_kfree(ctrl->dev, ctrl); } platform_set_drvdata(pdev, NULL); dev_err(&pdev->dev, "device init failed\n"); return ret; }
int es705_enable_ext_clk(struct device *dev, int enable) { static struct clk *es705_codec_clk = NULL; int rc = 0; dev_info(dev, "%s: clk enable=%d\n", __func__, enable); #ifdef CONFIG_ARCH_EXYNOS if (enable) { if (es705_codec_clk) { dev_info(dev, "%s: clk is already On", __func__); return 0; } es705_codec_clk = devm_clk_get(dev, "mclk"); if (IS_ERR(es705_codec_clk)) { dev_err(dev, "%s: Device tree node not found for mclk", __func__); es705_codec_clk = NULL; } if(es705_codec_clk) { rc = clk_prepare_enable(es705_codec_clk); if (rc) { dev_err(dev, "%s: Failed to prepare or enable clock, err=%d\n", __func__, rc); goto err; } } else exynos5_audio_set_mclk(true, 0); } else { if(es705_codec_clk) { clk_disable_unprepare(es705_codec_clk); devm_clk_put(dev, es705_codec_clk); es705_codec_clk = NULL; } else exynos5_audio_set_mclk(false, 0); } return 0; err: devm_clk_put(dev, es705_codec_clk); es705_codec_clk = NULL; #else es705_codec_clk = clk_get(dev, "osr_clk"); if (!es705_codec_clk) { dev_err(dev, "%s: clk_get osr_clk FAIL\n", __func__); return -ENODEV; } if (enable) { rc = clk_prepare_enable(es705_codec_clk); if (rc) { dev_err(dev, "Failed to prepare or enable clock, err=%d\n", rc); goto err; } } else { clk_disable_unprepare(es705_codec_clk); clk_put(es705_codec_clk); } return 0; err: clk_put(es705_codec_clk); #endif return rc; }
static int __init sata_phy_probe(struct platform_device *pdev) { struct exynos_sata_phy *sataphy; struct sata_phy *phy; struct resource *res; struct device *dev = &pdev->dev; int ret = 0; phy = kzalloc(sizeof(struct sata_phy), GFP_KERNEL); if (!phy) { dev_err(&pdev->dev, "failed to allocate memory\n"); ret = -ENOMEM; goto out; } sataphy = kzalloc(sizeof(struct exynos_sata_phy), GFP_KERNEL); if (!sataphy) { dev_err(dev, "failed to allocate memory\n"); ret = -ENOMEM; goto err0; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "Could not find IO resource\n"); ret = -EINVAL; goto err1; } sataphy->mem = devm_request_mem_region(dev, res->start, resource_size(res), pdev->name); if (!sataphy->mem) { dev_err(dev, "Could not request IO resource\n"); ret = -EINVAL; goto err1; } sataphy->mmio = devm_ioremap(dev, res->start, resource_size(res)); if (!sataphy->mmio) { dev_err(dev, "failed to remap IO\n"); ret = -ENOMEM; goto err2; } sataphy->clk = devm_clk_get(dev, "sata-phy"); if (IS_ERR(sataphy->clk)) { dev_err(dev, "failed to get clk for PHY\n"); ret = PTR_ERR(sataphy->clk); goto err3; } phy->init = sataphy_init; phy->shutdown = sataphy_shutdown; phy->priv_data = (void *)sataphy; phy->dev = dev; ret = sata_add_phy(phy, SATA_PHY_GENERATION3); if (ret < 0) goto err4; ret = i2c_add_driver(&sataphy_i2c_driver); if (ret < 0) goto err5; platform_set_drvdata(pdev, phy); return ret; err5: sata_remove_phy(phy); err4: clk_disable(sataphy->clk); devm_clk_put(dev, sataphy->clk); err3: devm_iounmap(dev, sataphy->mmio); err2: devm_release_mem_region(dev, res->start, resource_size(res)); err1: kfree(sataphy); err0: kfree(phy); out: return ret; }
static int hi6401_irq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct hi6401_irq *irq = NULL; enum of_gpio_flags flags; unsigned int virq; int ret = 0; int i; irq = devm_kzalloc(dev, sizeof(*irq), GFP_KERNEL); if (!irq) { dev_err(dev, "cannot allocate hi6401_irq device info\n"); return -ENOMEM; } platform_set_drvdata(pdev, irq); /* get resources */ irq->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!irq->res) { dev_err(dev, "platform_get_resource err\n"); goto err_exit; } if (!devm_request_mem_region(dev, irq->res->start, resource_size(irq->res), pdev->name)) { dev_err(dev, "cannot claim register memory\n"); goto err_exit; } irq->reg_base_addr = devm_ioremap(dev, irq->res->start, resource_size(irq->res)); if (!irq->reg_base_addr) { dev_err(dev, "cannot map register memory\n"); goto ioremap_err; } /* get pinctrl */ irq->pctrl = devm_pinctrl_get(dev); if (IS_ERR(irq->pctrl)) { dev_err(dev, "could not get pinctrl\n"); goto codec_ssi_get_err; } ret = codec_ssi_iomux_default(irq->pctrl); if (0 != ret) goto codec_ssi_iomux_err; /* get codec ssi clk */ irq->codec_ssi_clk = devm_clk_get(dev, "clk_codecssi"); if (IS_ERR(irq->codec_ssi_clk)) { pr_err("clk_get: codecssi clk not found!\n"); ret = PTR_ERR(irq->codec_ssi_clk); goto codec_ssi_clk_err; } ret = clk_prepare_enable(irq->codec_ssi_clk); if (0 != ret) { pr_err("codec_ssi_clk :clk prepare enable failed !\n"); goto codec_ssi_clk_enable_err; } /* get pmu audio clk */ irq->pmu_audio_clk = devm_clk_get(dev, "clk_pmuaudioclk"); if (IS_ERR(irq->pmu_audio_clk)) { pr_err("_clk_get: pmu_audio_clk not found!\n"); ret = PTR_ERR(irq->pmu_audio_clk); goto pmu_audio_clk_err; } ret = clk_prepare_enable(irq->pmu_audio_clk); if (0 != ret) { pr_err("pmu_audio_clk :clk prepare enable failed !\n"); goto pmu_audio_clk_enable_err; } spin_lock_init(&irq->lock); spin_lock_init(&irq->rw_lock); mutex_init(&irq->sr_mutex); mutex_init(&irq->pll_mutex); wake_lock_init(&irq->wake_lock, WAKE_LOCK_SUSPEND, "hi6401-irq"); irq->dev = dev; /* clear IRQ status */ hi6401_irq_write(irq, HI6401_REG_IRQ_0, 0xFF); hi6401_irq_write(irq, HI6401_REG_IRQ_1, 0xFF); /* mask all irqs */ hi6401_irq_write(irq, HI6401_REG_IRQM_0, 0xFF); hi6401_irq_write(irq, HI6401_REG_IRQM_1, 0xFF); irq->gpio = of_get_gpio_flags(np, 0, &flags); if (0 > irq->gpio) { dev_err(dev, "get gpio flags error\n"); ret = irq->gpio; goto get_gpio_err; } if (!gpio_is_valid(irq->gpio)) { dev_err(dev, "gpio is invalid\n"); ret = -EINVAL; goto get_gpio_err; } ret = gpio_request_one(irq->gpio, GPIOF_IN, "hi6401_irq"); if (0 > ret) { dev_err(dev, "failed to request gpio%d\n", irq->gpio); goto get_gpio_err; } irq->irq = gpio_to_irq(irq->gpio); irq->domain = irq_domain_add_simple(np, HI6401_MAX_IRQS, 0, &hi6401_domain_ops, irq); if (!irq->domain) { dev_err(dev, "irq domain error\n"); ret = -ENODEV; goto gpio_err; } for (i = 0; i < HI6401_MAX_IRQS; i++) { virq = irq_create_mapping(irq->domain, i); if (virq == NO_IRQ) { dev_err(dev, "Failed mapping hwirq\n"); ret = -ENOSPC; goto gpio_err; } irq->irqs[i] = virq; } ret = request_irq(irq->irq, hi6401_irq_handler, IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, "hi6401_irq", irq); if (0 > ret) { dev_err(dev, "could not claim irq %d\n", ret); ret = -ENODEV; goto gpio_err; } irq->hi6401_irq_delay_wq = create_singlethread_workqueue("hi6401_irq_delay_wq"); if (!(irq->hi6401_irq_delay_wq)) { pr_err("%s(%u) : workqueue create failed", __FUNCTION__,__LINE__); ret = -ENOMEM; goto irq_delay_wq_err; } INIT_DELAYED_WORK(&irq->hi6401_irq_delay_work, hi6401_irq_work_func); irq->pll_delay_wq = create_singlethread_workqueue("pll_delay_wq"); if (!(irq->pll_delay_wq)) { pr_err("%s : pll_delay_wq create failed", __FUNCTION__); ret = -ENOMEM; goto pll_delay_wq_err; } INIT_DELAYED_WORK(&irq->pll_delay_work, hi6401_pll_work_func); g_dump_buf = (char*)kmalloc(sizeof(char)*Hi6401_SIZE_MAX, GFP_KERNEL); if (!g_dump_buf) { pr_err("%s : couldn't malloc buffer.\n",__FUNCTION__); ret = -ENOMEM; goto g_dump_buf_kmalloc_err; } memset(g_dump_buf, 0, Hi6401_SIZE_MAX); /* populate sub nodes */ of_platform_populate(np, of_hi6401_irq_child_match_tbl, NULL, dev); if (!hi6401_client) { hi6401_client = dsm_register_client(&dsm_hi6401); } return 0; g_dump_buf_kmalloc_err: if(irq->pll_delay_wq) { cancel_delayed_work(&irq->pll_delay_work); flush_workqueue(irq->pll_delay_wq); destroy_workqueue(irq->pll_delay_wq); } pll_delay_wq_err: if(irq->hi6401_irq_delay_wq) { cancel_delayed_work(&irq->hi6401_irq_delay_work); flush_workqueue(irq->hi6401_irq_delay_wq); destroy_workqueue(irq->hi6401_irq_delay_wq); } irq_delay_wq_err: free_irq(irq->irq, irq); gpio_err: gpio_free(irq->gpio); get_gpio_err: clk_disable_unprepare(irq->pmu_audio_clk); pmu_audio_clk_enable_err: devm_clk_put(dev, irq->pmu_audio_clk); pmu_audio_clk_err: clk_disable_unprepare(irq->codec_ssi_clk); codec_ssi_clk_enable_err: devm_clk_put(dev, irq->codec_ssi_clk); codec_ssi_clk_err: codec_ssi_iomux_idle(irq->pctrl); codec_ssi_iomux_err: pinctrl_put(irq->pctrl); codec_ssi_get_err: devm_iounmap(dev, irq->reg_base_addr); ioremap_err: devm_release_mem_region(dev, irq->res->start, resource_size(irq->res)); err_exit: devm_kfree(dev, irq); return ret; }
static int __init exynos_sata_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ata_port_info pi = ahci_port_info; const struct ata_port_info *ppi[] = { &pi, NULL }; struct ahci_host_priv *hpriv; struct exynos_sata *sata; struct ata_host *host; struct resource *mem; int n_ports, i, ret; sata = devm_kzalloc(dev, sizeof(*sata), GFP_KERNEL); if (!sata) { dev_err(dev, "can't alloc sata\n"); return -EINVAL; } hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) { dev_err(dev, "can't alloc ahci_host_priv\n"); ret = -ENOMEM; goto err1; } hpriv->flags |= (unsigned long)pi.private_data; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(dev, "no mmio space\n"); ret = -EINVAL; goto err2; } sata->irq = platform_get_irq(pdev, 0); if (sata->irq <= 0) { dev_err(dev, "no irq\n"); ret = -EINVAL; goto err2; } hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); if (!hpriv->mmio) { dev_err(dev, "can't map %pR\n", mem); ret = -ENOMEM; goto err2; } exynos_sata_parse_dt(dev->of_node, sata); if (!sata->freq) { dev_err(dev, "can't determine sata frequency \n"); ret = -ENOMEM; goto err2; } sata->sclk = devm_clk_get(dev, "sclk_sata"); if (IS_ERR(sata->sclk)) { dev_err(dev, "failed to get sclk_sata\n"); ret = PTR_ERR(sata->sclk); goto err3; } clk_enable(sata->sclk); clk_set_rate(sata->sclk, sata->freq * MHZ); sata->clk = devm_clk_get(dev, "sata"); if (IS_ERR(sata->clk)) { dev_err(dev, "failed to get sata clock\n"); ret = PTR_ERR(sata->clk); goto err4; } clk_enable(sata->clk); /* Get a gen 3 PHY controller */ sata->phy = sata_get_phy(SATA_PHY_GENERATION3); if (!sata->phy) { dev_err(dev, "failed to get sata phy\n"); ret = -EPROBE_DEFER; goto err5; } /* Initialize the controller */ ret = sata_init_phy(sata->phy); if (ret < 0) { dev_err(dev, "failed to initialize sata phy\n"); goto err6; } ahci_save_initial_config(dev, hpriv, 0, 0); /* prepare host */ if (hpriv->cap & HOST_CAP_NCQ) pi.flags |= ATA_FLAG_NCQ; if (hpriv->cap & HOST_CAP_PMP) pi.flags |= ATA_FLAG_PMP; ahci_set_em_messages(hpriv, &pi); /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at * both CAP.NP and port_map. */ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); host = ata_host_alloc_pinfo(dev, ppi, n_ports); if (!host) { ret = -ENOMEM; goto err7; } host->private_data = hpriv; if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) host->flags |= ATA_HOST_PARALLEL_SCAN; else pr_info(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; ata_port_desc(ap, "mmio %pR", mem); ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); /* set enclosure management message type */ if (ap->flags & ATA_FLAG_EM) ap->em_message_type = hpriv->em_msg_type; /* disabled/not-implemented port */ if (!(hpriv->port_map & (1 << i))) ap->ops = &ata_dummy_port_ops; } ret = ahci_reset_controller(host); if (ret) goto err7; ahci_init_controller(host); ahci_print_info(host, "platform"); ret = ata_host_activate(host, sata->irq, ahci_interrupt, IRQF_SHARED, &ahci_platform_sht); if (ret) goto err7; platform_set_drvdata(pdev, sata); return 0; err7: sata_shutdown_phy(sata->phy); err6: sata_put_phy(sata->phy); err5: clk_disable(sata->clk); devm_clk_put(dev, sata->clk); err4: clk_disable(sata->sclk); devm_clk_put(dev, sata->sclk); err3: devm_iounmap(dev, hpriv->mmio); err2: devm_kfree(dev, hpriv); err1: devm_kfree(dev, sata); return ret; }