/*
 * Translate OpenFirmware node properties into platform_data
 */
static int gpio_keys_get_devtree_pdata(struct device *dev,
			    struct gpio_keys_platform_data *pdata)
{
	struct device_node *node, *pp;
	int i;
	struct gpio_keys_button *buttons;
	struct regulator *vddo_vreg;
	u32 reg;

	node = dev->of_node;
	if (node == NULL)
		return -ENODEV;

	memset(pdata, 0, sizeof *pdata);

	pdata->rep = !!of_get_property(node, "autorepeat", NULL);
	pdata->name = of_get_property(node, "input-name", NULL);

	vddo_vreg = devm_regulator_get(dev, "vddo");
	if (IS_ERR(vddo_vreg))
	dev_err(dev, "[Keys] no regulator: ignoring\n");
	else{
		if(!of_property_read_u32(node, "vddo-voltage", &reg))
		regulator_set_voltage(vddo_vreg, reg*1000, reg*1000);
		if(regulator_enable(vddo_vreg))
			return -EINVAL;
	}
	/* First count the subnodes */
	pdata->nbuttons = 0;
	pp = NULL;
	while ((pp = of_get_next_child(node, pp)))
		pdata->nbuttons++;

	if (pdata->nbuttons == 0)
		return -ENODEV;

	buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL);
	if (!buttons)
		return -ENOMEM;

	pp = NULL;
	i = 0;
	while ((pp = of_get_next_child(node, pp))) {
		enum of_gpio_flags flags;

		if (!of_find_property(pp, "gpios", NULL)) {
			pdata->nbuttons--;
			dev_warn(dev, "Found button without gpios\n");
			continue;
		}
		buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags);
		buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW;

		if (of_property_read_u32(pp, "linux,code", &reg)) {
			dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio);
			goto out_fail;
		}
		buttons[i].code = reg;

		buttons[i].desc = of_get_property(pp, "label", NULL);
#ifdef CONFIG_SENSORS_HALL
		if ((buttons[i].code == SW_FLIP) || (buttons[i].code == SW_LID)) {
			pdata->gpio_flip_cover = buttons[i].gpio;
			pdata->flip_code = buttons[i].code;
			pdata->nbuttons--;
#ifdef CONFIG_SENSORS_HALL_IRQ_CTRL
			pdata->workaround_set = (of_property_read_bool(pp, "hall_wa_disable") ? false : true);
#endif
			dev_info(dev, "[Hall_IC] device tree was founded\n");
			continue;
		}
#endif
		if (of_property_read_u32(pp, "linux,input-type", &reg) == 0)
			buttons[i].type = reg;
		else
			buttons[i].type = EV_KEY;

		buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);

		if (of_property_read_u32(pp, "debounce-interval", &reg) == 0)
			buttons[i].debounce_interval = reg;
		else
			buttons[i].debounce_interval = 5;

		dev_info(dev, "%s: label:%s, gpio:%d, code:%d, type:%d, debounce:%d\n",
				__func__, buttons[i].desc, buttons[i].gpio,
				buttons[i].code, buttons[i].type,
				buttons[i].debounce_interval);
		i++;
	}

	pdata->buttons = buttons;

	return 0;

out_fail:
	kfree(buttons);
	return -ENODEV;
}
/*
 * Translate OpenFirmware node properties into platform_data
 */
static int gpio_keys_get_devtree_pdata(struct device *dev,
			    struct gpio_keys_platform_data *pdata)
{
	struct device_node *node, *pp;
	int i;
	struct gpio_keys_button *buttons;
	u32 reg;

	node = dev->of_node;
	if (node == NULL)
		return -ENODEV;

	memset(pdata, 0, sizeof *pdata);

	pdata->rep = !!of_get_property(node, "autorepeat", NULL);
	pdata->name = of_get_property(node, "input-name", NULL);

	/* First count the subnodes */
	pdata->nbuttons = 0;
	pp = NULL;
	while ((pp = of_get_next_child(node, pp)))
		pdata->nbuttons++;

	if (pdata->nbuttons == 0)
		return -ENODEV;

	buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL);
	if (!buttons)
		return -ENOMEM;

	pp = NULL;
	i = 0;
	while ((pp = of_get_next_child(node, pp))) {
		enum of_gpio_flags flags;

		if (!of_find_property(pp, "gpios", NULL)) {
			pdata->nbuttons--;
			dev_warn(dev, "Found button without gpios\n");
			continue;
		}
		buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags);
		buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW;

		if (of_property_read_u32(pp, "linux,code", &reg)) {
			dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio);
			goto out_fail;
		}
		buttons[i].code = reg;

		buttons[i].desc = of_get_property(pp, "label", NULL);

		if (of_property_read_u32(pp, "linux,input-type", &reg) == 0)
			buttons[i].type = reg;
		else
			buttons[i].type = EV_KEY;

		buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);

		if (of_property_read_u32(pp, "debounce-interval", &reg) == 0)
			buttons[i].debounce_interval = reg;
		else
			buttons[i].debounce_interval = 5;

		i++;
	}

	pdata->buttons = buttons;

	return 0;

out_fail:
	kfree(buttons);
	return -ENODEV;
}
static int serial_omap_probe(struct platform_device *pdev)
{
	struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev);
	struct uart_omap_port *up;
	struct resource *mem;
	void __iomem *base;
	int uartirq = 0;
	int wakeirq = 0;
	int ret;
	enum of_gpio_flags flags;
	int gpio_sel;
	unsigned long gpio_flags;

	/* The optional wakeirq may be specified in the board dts file */
	if (pdev->dev.of_node) {
		uartirq = irq_of_parse_and_map(pdev->dev.of_node, 0);
		if (!uartirq)
			return -EPROBE_DEFER;
		wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1);
		omap_up_info = of_get_uart_port_info(&pdev->dev);
		pdev->dev.platform_data = omap_up_info;
	} else {
		uartirq = platform_get_irq(pdev, 0);
		if (uartirq < 0)
			return -EPROBE_DEFER;
	}

	/* Check if the UART needs to be selected */
	gpio_sel = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
	if (gpio_is_valid(gpio_sel)) {
		dev_dbg(&pdev->dev, "using gpio %d for uart%d_sel\n",
			gpio_sel, pdev->id);
		gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ?
			GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
		ret = devm_gpio_request_one(&pdev->dev, gpio_sel,
					    gpio_flags, "uart_sel");
		if (ret) {
			dev_err(&pdev->dev, "gpio%d request failed, ret %d\n",
				gpio_sel, ret);
			return ret;
		}
	} else if (gpio_sel == -EPROBE_DEFER) {
		return -EPROBE_DEFER;
	}

	up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL);
	if (!up)
		return -ENOMEM;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(base))
		return PTR_ERR(base);

	up->dev = &pdev->dev;
	up->port.dev = &pdev->dev;
	up->port.type = PORT_OMAP;
	up->port.iotype = UPIO_MEM;
	up->port.irq = uartirq;
	up->wakeirq = wakeirq;
	if (!up->wakeirq)
		dev_info(up->port.dev, "no wakeirq for uart%d\n",
			 up->port.line);

	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;
	}

	if (up->port.line >= OMAP_MAX_HSUART_PORTS) {
		dev_err(&pdev->dev, "uart ID %d >  MAX %d.\n", up->port.line,
			OMAP_MAX_HSUART_PORTS);
		ret = -ENXIO;
		goto err_port_line;
	}

	ret = serial_omap_probe_rs485(up, pdev->dev.of_node);
	if (ret < 0)
		goto err_rs485;

	sprintf(up->name, "OMAP UART%d", up->port.line);
	up->port.mapbase = mem->start;
	up->port.membase = base;
	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);
	INIT_WORK(&up->qos_work, serial_omap_uart_qos_work);

	platform_set_drvdata(pdev, up);
	if (omap_up_info->autosuspend_timeout == 0)
		omap_up_info->autosuspend_timeout = -1;

	device_init_wakeup(up->dev, true);
	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_enable(&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_rs485:
err_port_line:
	dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
				pdev->id, __func__, ret);
	return ret;
}
Example #4
0
/*
 * Translate OpenFirmware node properties into platform_data
 */
static struct gpio_keys_platform_data *
gpio_keys_get_devtree_pdata(struct device *dev)
{
    struct device_node *node, *pp;
    struct gpio_keys_platform_data *pdata;
    struct gpio_keys_button *button;
    int error;
    int nbuttons;
    int i;

    node = dev->of_node;
    if (!node)
        return ERR_PTR(-ENODEV);

    nbuttons = of_get_child_count(node);
    if (nbuttons == 0)
        return ERR_PTR(-ENODEV);

    pdata = devm_kzalloc(dev,
                         sizeof(*pdata) + nbuttons * sizeof(*button),
                         GFP_KERNEL);
    if (!pdata)
        return ERR_PTR(-ENOMEM);

    pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
    pdata->nbuttons = nbuttons;

    pdata->rep = !!of_get_property(node, "autorepeat", NULL);

    i = 0;
    for_each_child_of_node(node, pp) {
        enum of_gpio_flags flags;

        button = &pdata->buttons[i++];

        button->gpio = of_get_gpio_flags(pp, 0, &flags);
        if (button->gpio < 0) {
            error = button->gpio;
            if (error != -ENOENT) {
                if (error != -EPROBE_DEFER)
                    dev_err(dev,
                            "Failed to get gpio flags, error: %d\n",
                            error);
                return ERR_PTR(error);
            }
        } else {
            button->active_low = flags & OF_GPIO_ACTIVE_LOW;
        }

        button->irq = irq_of_parse_and_map(pp, 0);

        if (!gpio_is_valid(button->gpio) && !button->irq) {
            dev_err(dev, "Found button without gpios or irqs\n");
            return ERR_PTR(-EINVAL);
        }

        if (of_property_read_u32(pp, "linux,code", &button->code)) {
            dev_err(dev, "Button without keycode: 0x%x\n",
                    button->gpio);
            return ERR_PTR(-EINVAL);
        }

        button->desc = of_get_property(pp, "label", NULL);

        if (of_property_read_u32(pp, "linux,input-type", &button->type))
            button->type = EV_KEY;

        button->wakeup = of_property_read_bool(pp, "wakeup-source") ||
                         /* legacy name */
                         of_property_read_bool(pp, "gpio-key,wakeup");

        button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL);

        if (of_property_read_u32(pp, "debounce-interval",
                                 &button->debounce_interval))
            button->debounce_interval = 5;
    }

    if (pdata->nbuttons == 0)
        return ERR_PTR(-EINVAL);

    return pdata;
}
static int of_isp1760_probe(struct platform_device *dev)
{
	struct isp1760 *drvdata;
	struct device_node *dp = dev->dev.of_node;
	struct resource *res;
	struct resource memory;
	struct of_irq oirq;
	int virq;
	resource_size_t res_len;
	int ret;
	unsigned int devflags = 0;
	enum of_gpio_flags gpio_flags;
	u32 bus_width = 0;

	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	ret = of_address_to_resource(dp, 0, &memory);
	if (ret) {
		ret = -ENXIO;
		goto free_data;
	}

	res_len = resource_size(&memory);

	res = request_mem_region(memory.start, res_len, dev_name(&dev->dev));
	if (!res) {
		ret = -EBUSY;
		goto free_data;
	}

	if (of_irq_map_one(dp, 0, &oirq)) {
		ret = -ENODEV;
		goto release_reg;
	}

	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
			oirq.size);

	if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
		devflags |= ISP1760_FLAG_ISP1761;

	/* Some systems wire up only 16 of the 32 data lines */
	of_property_read_u32(dp, "bus-width", &bus_width);
	if (bus_width == 16)
		devflags |= ISP1760_FLAG_BUS_WIDTH_16;

	if (of_get_property(dp, "port1-otg", NULL) != NULL)
		devflags |= ISP1760_FLAG_OTG_EN;

	if (of_get_property(dp, "analog-oc", NULL) != NULL)
		devflags |= ISP1760_FLAG_ANALOG_OC;

	if (of_get_property(dp, "dack-polarity", NULL) != NULL)
		devflags |= ISP1760_FLAG_DACK_POL_HIGH;

	if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
		devflags |= ISP1760_FLAG_DREQ_POL_HIGH;

	drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags);
	if (gpio_is_valid(drvdata->rst_gpio)) {
		ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev));
		if (!ret) {
			if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) {
				devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH;
				gpio_direction_output(drvdata->rst_gpio, 0);
			} else {
				gpio_direction_output(drvdata->rst_gpio, 1);
			}
		} else {
			drvdata->rst_gpio = ret;
		}
	}

	drvdata->hcd = isp1760_register(memory.start, res_len, virq,
					IRQF_SHARED, drvdata->rst_gpio,
					&dev->dev, dev_name(&dev->dev),
					devflags);
	if (IS_ERR(drvdata->hcd)) {
		ret = PTR_ERR(drvdata->hcd);
		goto free_gpio;
	}

	dev_set_drvdata(&dev->dev, drvdata);
	return ret;

free_gpio:
	if (gpio_is_valid(drvdata->rst_gpio))
		gpio_free(drvdata->rst_gpio);
release_reg:
	release_mem_region(memory.start, res_len);
free_data:
	kfree(drvdata);
	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;
}