Exemple #1
0
static int __exit hsi_remove(struct platform_device *pd)
{
	struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd);

	if (!hsi_ctrl)
		return 0;

	unregister_hsi_devices(hsi_ctrl);
	hsi_debug_remove_ctrl(hsi_ctrl);
	hsi_controller_exit(hsi_ctrl);
	kfree(hsi_ctrl);

	return 0;
}
Exemple #2
0
static int __exit hsi_platform_device_remove(struct platform_device *pd)
{
    struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd);

    dev_dbg(&pd->dev, "HSI DRIVER : hsi_platform_device_remove\n");

    if (!hsi_ctrl)
        return 0;

    unregister_hsi_devices(hsi_ctrl);

    /* From here no need for HSI HW access */
    pm_runtime_disable(hsi_ctrl->dev);

    hsi_debug_remove_ctrl(hsi_ctrl);
    hsi_controller_exit(hsi_ctrl);

    kfree(hsi_ctrl);

    return 0;
}
Exemple #3
0
/* HSI Platform Device probing & hsi_device registration */
static int __init hsi_platform_device_probe(struct platform_device *pd)
{
    struct hsi_platform_data *pdata = pd->dev.platform_data;
    struct hsi_dev *hsi_ctrl;
    u32 revision;
    int err;

    dev_dbg(&pd->dev, "HSI DRIVER : hsi_platform_device_probe\n");

    dev_dbg(&pd->dev, "The platform device probed is an %s\n",
            hsi_driver_device_is_hsi(pd) ? "HSI" : "SSI");

    if (!pdata) {
        dev_err(&pd->dev, "No platform_data found on hsi device\n");
        return -ENXIO;
    }

    hsi_ctrl = kzalloc(sizeof(*hsi_ctrl), GFP_KERNEL);
    if (hsi_ctrl == NULL) {
        dev_err(&pd->dev, "Could not allocate memory for"
                " struct hsi_dev\n");
        return -ENOMEM;
    }

    platform_set_drvdata(pd, hsi_ctrl);
    err = hsi_controller_init(hsi_ctrl, pd);
    if (err < 0) {
        dev_err(&pd->dev, "Could not initialize hsi controller:"
                " %d\n", err);
        goto rollback1;
    }
    /* Wakeup dependency was disabled for HSI <-> MPU PM_L3INIT_HSI_WKDEP */
#if 0
    omap_writel(0x141, 0x4A307338);
#endif
    pm_runtime_enable(hsi_ctrl->dev);
    pm_runtime_irq_safe(hsi_ctrl->dev);
    hsi_clocks_enable(hsi_ctrl->dev, __func__);

    /* Non critical SW Reset */
    err = hsi_softreset(hsi_ctrl);
    if (err < 0)
        goto rollback2;

    hsi_set_pm_force_hsi_on(hsi_ctrl);

    /* Configure HSI ports */
    hsi_set_ports_default(hsi_ctrl, pd);

    /* Gather info from registers for the driver.(REVISION) */
    revision = hsi_inl(hsi_ctrl->base, HSI_SYS_REVISION_REG);
    if (hsi_driver_device_is_hsi(pd))
        dev_info(hsi_ctrl->dev, "HSI Hardware REVISION 0x%x\n",
                 revision);
    else
        dev_info(hsi_ctrl->dev, "SSI Hardware REVISION %d.%d\n",
                 (revision & HSI_SSI_REV_MAJOR) >> 4,
                 (revision & HSI_SSI_REV_MINOR));

    err = hsi_debug_add_ctrl(hsi_ctrl);
    if (err < 0) {
        dev_err(&pd->dev,
                "Could not add hsi controller to debugfs: %d\n", err);
        goto rollback2;
    }

    err = register_hsi_devices(hsi_ctrl);
    if (err < 0) {
        dev_err(&pd->dev, "Could not register hsi_devices: %d\n", err);
        goto rollback3;
    }

    /* Allow HSI to wake up the platform */
    device_init_wakeup(hsi_ctrl->dev, true);

    /* Set the HSI FCLK to default. */
    if (!pdata->device_scale) {
        dev_err(&pd->dev, "%s: No platform device_scale function\n",
                __func__);
        err = -ENXIO;
        goto rollback3;
    }
    err = pdata->device_scale(hsi_ctrl->dev, hsi_ctrl->dev,
                              pdata->default_hsi_fclk);
    if (err == -EBUSY) {
        dev_warn(&pd->dev, "Cannot set HSI FClk to default value: %ld. "
                 "Will retry on next open\n",
                 pdata->default_hsi_fclk);
    } else if (err) {
        dev_err(&pd->dev, "%s: Error %d setting HSI FClk to %ld.\n",
                __func__, err, pdata->default_hsi_fclk);
        goto rollback3;
    } else {
        hsi_ctrl->clock_rate = pdata->default_hsi_fclk;
    }

    /* From here no need for HSI HW access */
    hsi_clocks_disable(hsi_ctrl->dev, __func__);

    return 0;

rollback3:
    hsi_debug_remove_ctrl(hsi_ctrl);
rollback2:
    hsi_controller_exit(hsi_ctrl);

    /* From here no need for HSI HW access */
    hsi_clocks_disable(hsi_ctrl->dev, __func__);

rollback1:
    kfree(hsi_ctrl);
    return err;
}
Exemple #4
0
/* HSI Platform Device probing & hsi_device registration */
static int __init hsi_platform_device_probe(struct platform_device *pd)
{
	struct hsi_platform_data *pdata = pd->dev.platform_data;
	struct hsi_dev *hsi_ctrl;
	u32 revision;
	int err;

	dev_dbg(&pd->dev, "HSI DRIVER : hsi_platform_device_probe\n");

	dev_dbg(&pd->dev, "The platform device probed is an %s\n",
		hsi_driver_device_is_hsi(pd) ? "HSI" : "SSI");

	if (!pdata) {
		pr_err(LOG_NAME "No platform_data found on hsi device\n");
		return -ENXIO;
	}

	hsi_ctrl = kzalloc(sizeof(*hsi_ctrl), GFP_KERNEL);
	if (hsi_ctrl == NULL) {
		dev_err(&pd->dev, "Could not allocate memory for"
			" struct hsi_dev\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pd, hsi_ctrl);
	err = hsi_controller_init(hsi_ctrl, pd);
	if (err < 0) {
		dev_err(&pd->dev, "Could not initialize hsi controller:"
			" %d\n", err);
		goto rollback1;
	}

	pm_runtime_enable(hsi_ctrl->dev);
	hsi_clocks_enable(hsi_ctrl->dev, __func__);

	/* Non critical SW Reset */
	err = hsi_softreset(hsi_ctrl);
	if (err < 0)
		goto rollback2;

	hsi_set_pm_default(hsi_ctrl);

	/* Configure HSI ports */
	hsi_set_ports_default(hsi_ctrl, pd);

	/* Gather info from registers for the driver.(REVISION) */
	revision = hsi_inl(hsi_ctrl->base, HSI_SYS_REVISION_REG);
	if (hsi_driver_device_is_hsi(pd))
		dev_info(hsi_ctrl->dev, "HSI Hardware REVISION 0x%x\n",
			 revision);
	else
		dev_info(hsi_ctrl->dev, "SSI Hardware REVISION %d.%d\n",
			 (revision & HSI_SSI_REV_MAJOR) >> 4,
			 (revision & HSI_SSI_REV_MINOR));

	err = hsi_debug_add_ctrl(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev,
			"Could not add hsi controller to debugfs: %d\n", err);
		goto rollback2;
	}

	err = register_hsi_devices(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev, "Could not register hsi_devices: %d\n", err);
		goto rollback3;
	}

	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

	/* Allow HSI to wake up the platform */
	device_init_wakeup(hsi_ctrl->dev, 1);

	/* Set the HSI FCLK to default. */
	err = omap_device_set_rate(hsi_ctrl->dev, hsi_ctrl->dev,
					pdata->default_hsi_fclk);
	if (err)
		dev_err(&pd->dev, "Cannot set HSI FClk to default value: %ld\n",
			pdata->default_hsi_fclk);

	return err;

rollback3:
	hsi_debug_remove_ctrl(hsi_ctrl);
rollback2:
	hsi_controller_exit(hsi_ctrl);

	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

rollback1:
	kfree(hsi_ctrl);
	return err;
}
/* HSI Platform Device probing & hsi_device registration */
static int __init hsi_platform_device_probe(struct platform_device *pd)
{
	struct hsi_platform_data *pdata = dev_get_platdata(&pd->dev);
	struct hsi_dev *hsi_ctrl;
	u32 revision;
	int err;

	dev_dbg(&pd->dev, "HSI DRIVER : hsi_platform_device_probe\n");

	dev_dbg(&pd->dev, "The platform device probed is an %s\n",
		hsi_driver_device_is_hsi(pd) ? "HSI" : "SSI");

	if (!pdata) {
		dev_err(&pd->dev, "No platform_data found on hsi device\n");
		return -ENXIO;
	}

	/* Check if mandatory board functions are populated */
	if (!pdata->device_scale) {
		dev_err(&pd->dev, "Missing platform device_scale function\n");
		return -ENOSYS;
	}

	hsi_ctrl = kzalloc(sizeof(*hsi_ctrl), GFP_KERNEL);
	if (hsi_ctrl == NULL) {
		dev_err(&pd->dev, "Could not allocate memory for"
			" struct hsi_dev\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pd, hsi_ctrl);
	err = hsi_controller_init(hsi_ctrl, pd);
	if (err < 0) {
		dev_err(&pd->dev, "Could not initialize hsi controller:"
			" %d\n", err);
		goto rollback1;
	}

	pm_runtime_enable(hsi_ctrl->dev);
	pm_runtime_irq_safe(hsi_ctrl->dev);
	hsi_clocks_enable(hsi_ctrl->dev, __func__);

	/* Non critical SW Reset */
	err = hsi_softreset(hsi_ctrl);
	if (err < 0)
		goto rollback2;

	hsi_set_pm_force_hsi_on(hsi_ctrl);

	/* Configure HSI ports */
	hsi_set_ports_default(hsi_ctrl, pd);

	/* Gather info from registers for the driver.(REVISION) */
	revision = hsi_inl(hsi_ctrl->base, HSI_SYS_REVISION_REG);
	if (hsi_driver_device_is_hsi(pd))
		dev_info(hsi_ctrl->dev, "HSI Hardware REVISION 0x%x\n",
			 revision);
	else
		dev_info(hsi_ctrl->dev, "SSI Hardware REVISION %d.%d\n",
			 (revision & HSI_SSI_REV_MAJOR) >> 4,
			 (revision & HSI_SSI_REV_MINOR));

	err = hsi_debug_add_ctrl(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev,
			"Could not add hsi controller to debugfs: %d\n", err);
		goto rollback2;
	}

	err = register_hsi_devices(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev, "Could not register hsi_devices: %d\n", err);
		goto rollback3;
	}

	/* Allow HSI to wake up the platform */
	device_init_wakeup(hsi_ctrl->dev, true);

	/* Set the HSI FCLK to default. */
	hsi_ctrl->hsi_fclk_req = pdata->default_hsi_fclk;
	err = pdata->device_scale(hsi_ctrl->dev, hsi_ctrl->dev,
				  pdata->default_hsi_fclk);
	if (err == -EBUSY) {
		/* PM framework init is late_initcall, so it may not yet be */
		/* initialized, so be prepared to retry later on open. */
		dev_warn(&pd->dev, "Cannot set HSI FClk to default value: %ld. "
			 "Will retry on next open\n", pdata->default_hsi_fclk);
	} else if (err) {
		dev_err(&pd->dev, "%s: Error %d setting HSI FClk to %ld.\n",
				__func__, err, pdata->default_hsi_fclk);
		goto rollback3;
	} else {
		hsi_ctrl->hsi_fclk_current = pdata->default_hsi_fclk;
	}
	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

	return 0;

rollback3:
	hsi_debug_remove_ctrl(hsi_ctrl);
rollback2:
	hsi_controller_exit(hsi_ctrl);

	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

rollback1:
	kfree(hsi_ctrl);
	return err;
}
static int __init hsi_platform_device_probe(struct platform_device *pd)
{
	struct hsi_platform_data *pdata = dev_get_platdata(&pd->dev);
	struct hsi_dev *hsi_ctrl;
	u32 revision;
	int err;

	dev_dbg(&pd->dev, "HSI DRIVER : hsi_platform_device_probe\n");

	dev_dbg(&pd->dev, "The platform device probed is an %s\n",
		hsi_driver_device_is_hsi(pd) ? "HSI" : "SSI");

	if (!pdata) {
		dev_err(&pd->dev, "No platform_data found on hsi device\n");
		return -ENXIO;
	}

	/* Check if mandatory board functions are populated */
	if (!pdata->device_scale) {
		dev_err(&pd->dev, "Missing platform device_scale function\n");
		return -ENOSYS;
	}

	hsi_ctrl = kzalloc(sizeof(*hsi_ctrl), GFP_KERNEL);
	if (hsi_ctrl == NULL) {
		dev_err(&pd->dev, "Could not allocate memory for"
			" struct hsi_dev\n");
		return -ENOMEM;
	}
//mo2haewoon.you => [START]
#if defined (HSI_SEND_ATCOMMAND_TO_CAWAKE)
	INIT_WORK(&hsi_ctrl->ifx_work,ifx_check_handle_work);
	hsi_ctrl->ifx_wq = create_singlethread_workqueue("ifx_wq");
    if(!hsi_ctrl->ifx_wq){
		printk("Failed to setup workqueue - ifx_wq \n");          
    }
#endif
//mo2haewoon.you => [END]

	platform_set_drvdata(pd, hsi_ctrl);
	err = hsi_controller_init(hsi_ctrl, pd);
	if (err < 0) {
		dev_err(&pd->dev, "Could not initialize hsi controller:"
			" %d\n", err);
		goto rollback1;
	}

	pm_runtime_enable(hsi_ctrl->dev);
	pm_runtime_irq_safe(hsi_ctrl->dev);
	hsi_clocks_enable(hsi_ctrl->dev, __func__);

	/* Non critical SW Reset */
	err = hsi_softreset(hsi_ctrl);
	if (err < 0)
		goto rollback2;

	hsi_set_pm_force_hsi_on(hsi_ctrl);

	/* Configure HSI ports */
	hsi_set_ports_default(hsi_ctrl, pd);

	/* Gather info from registers for the driver.(REVISION) */
	revision = hsi_inl(hsi_ctrl->base, HSI_SYS_REVISION_REG);
	if (hsi_driver_device_is_hsi(pd))
		dev_info(hsi_ctrl->dev, "HSI Hardware REVISION 0x%x\n",
			 revision);
	else
		dev_info(hsi_ctrl->dev, "SSI Hardware REVISION %d.%d\n",
			 (revision & HSI_SSI_REV_MAJOR) >> 4,
			 (revision & HSI_SSI_REV_MINOR));

	err = hsi_debug_add_ctrl(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev,
			"Could not add hsi controller to debugfs: %d\n", err);
		goto rollback2;
	}

	err = register_hsi_devices(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev, "Could not register hsi_devices: %d\n", err);
		goto rollback3;
	}

//mo2haewoon.you => [START]
#if defined (HSI_SEND_ATCOMMAND_TO_CAWAKE)
	/* Set the ts_gpio pin mux */
	err = gpio_request(OMAP_SEND, "gpio_122");
	gpio_direction_input(OMAP_SEND);
	irq_num_122 = gpio_to_irq(OMAP_SEND);
	
	err = request_irq(irq_num_122,ifx_check_handle_srdy_irq, IRQF_TRIGGER_RISING,HSI_MODULENAME, hsi_ctrl);
	if (err < 0) {
		pr_err("Modem-wait-check: couldn't request gpio interrupt 122\n");
	}
#endif
//mo2haewoon.you => [END]

	/* Allow HSI to wake up the platform */
	device_init_wakeup(hsi_ctrl->dev, true);

	/* Set the HSI FCLK to default. */
	hsi_ctrl->hsi_fclk_req = pdata->default_hsi_fclk;
	err = pdata->device_scale(hsi_ctrl->dev, hsi_ctrl->dev,
				  pdata->default_hsi_fclk);
	if (err == -EBUSY) {
		/* PM framework init is late_initcall, so it may not yet be */
		/* initialized, so be prepared to retry later on open. */
		dev_warn(&pd->dev, "Cannot set HSI FClk to default value: %ld. "
			 "Will retry on next open\n", pdata->default_hsi_fclk);
	} else if (err) {
		dev_err(&pd->dev, "%s: Error %d setting HSI FClk to %ld.\n",
				__func__, err, pdata->default_hsi_fclk);
		goto rollback3;
	} else {
		hsi_ctrl->hsi_fclk_current = pdata->default_hsi_fclk;
	}
	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

// LGE_CHANGE [MIPI-HSI] [email protected] [START]
#if defined(CONFIG_MACH_LGE_COSMOPOLITAN)
	/* Set IMC CP core dump */
	IFX_CP_CRASH_DUMP_INIT();
#endif

#if defined(CONFIG_MACH_LGE_COSMO)
	/* Notify active/sleep status of AP to CP*/
	ifx_init_modem_send();
#endif
// LGE_CHANGE [MIPI-HSI] [email protected] [END]

	return 0;

rollback3:
	hsi_debug_remove_ctrl(hsi_ctrl);
rollback2:
	hsi_controller_exit(hsi_ctrl);

	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

rollback1:
	kfree(hsi_ctrl);
	return err;
}
Exemple #7
0
/* HSI Platform Device probing & hsi_device registration */
static int __init hsi_platform_device_probe(struct platform_device *pd)
{
	struct hsi_platform_data *pdata = dev_get_platdata(&pd->dev);
	struct hsi_dev *hsi_ctrl;
	u32 revision;
	int err;

	dev_dbg(&pd->dev, "HSI DRIVER : hsi_platform_device_probe\n");

	dev_dbg(&pd->dev, "The platform device probed is an %s\n",
		hsi_driver_device_is_hsi(pd) ? "HSI" : "SSI");

	if (!pdata) {
		dev_err(&pd->dev, "No platform_data found on hsi device\n");
		return -ENXIO;
	}

	if (!pdata->device_enable || !pdata->device_idle ||
	    !pdata->device_set_rate || !pdata->wakeup_enable ||
	    !pdata->wakeup_disable || !pdata->wakeup_is_from_hsi ||
	    !pdata->board_suspend) {
		dev_err(&pd->dev, "Missing platform function pointers\n");
		return -EINVAL;
	}

	hsi_ctrl = kzalloc(sizeof(*hsi_ctrl), GFP_KERNEL);
	if (hsi_ctrl == NULL) {
		dev_err(&pd->dev, "Could not allocate memory for"
			" struct hsi_dev\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pd, hsi_ctrl);
	err = hsi_controller_init(hsi_ctrl, pd);
	if (err < 0) {
		dev_err(&pd->dev, "Could not initialize hsi controller:"
			" %d\n", err);
		goto rollback1;
	}

#ifdef USE_PM_RUNTIME_FOR_HSI
	pm_runtime_enable(hsi_ctrl->dev);
#endif
	err = hsi_clocks_enable(hsi_ctrl->dev, __func__);
	if (err < 0) {
		dev_err(&pd->dev, "Could not enable clocks for hsi: %d\n", err);
		goto rollback1;
	}

	/* Non critical SW Reset */
	err = hsi_softreset(hsi_ctrl);
	if (err < 0)
		goto rollback2;

	hsi_set_pm_force_hsi_on(hsi_ctrl);

	/* Configure HSI ports */
	hsi_set_ports_default(hsi_ctrl, pd);

	/* Gather info from registers for the driver.(REVISION) */
	revision = hsi_inl(hsi_ctrl->base, HSI_SYS_REVISION_REG);
	if (hsi_driver_device_is_hsi(pd))
		dev_info(hsi_ctrl->dev, "HSI Hardware REVISION 0x%x\n",
			 revision);
	else
		dev_info(hsi_ctrl->dev, "SSI Hardware REVISION %d.%d\n",
			 (revision & HSI_SSI_REV_MAJOR) >> 4,
			 (revision & HSI_SSI_REV_MINOR));

	err = hsi_debug_add_ctrl(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev,
			"Could not add hsi controller to debugfs: %d\n", err);
		goto rollback2;
	}

	err = register_hsi_devices(hsi_ctrl);
	if (err < 0) {
		dev_err(&pd->dev, "Could not register hsi_devices: %d\n", err);
		goto rollback3;
	}

	/* Allow HSI to wake up the platform */
	device_init_wakeup(hsi_ctrl->dev, true);

	/* Set the HSI FCLK to default. */
	err = pdata->device_set_rate(hsi_ctrl->dev, hsi_ctrl->dev,
					pdata->default_hsi_fclk);
	if (err)
		dev_err(&pd->dev, "Cannot set HSI FClk to default value: %ld\n",
			pdata->default_hsi_fclk);

	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

#if defined(CONFIG_MACH_LGE_COSMOPOLITAN)
	/* Set IMC CP core dump */
	IFX_CP_CRASH_DUMP_INIT();

	/* Notify active/sleep status of AP to CP*/
	ifx_init_modem_send();
#endif

#if defined(HSI_GPIO_CAWKAE_NOTIFY_ENABLE)
	ifx_init_gpio_cawake_notify(hsi_ctrl);
#endif

	return err;

rollback3:
	hsi_debug_remove_ctrl(hsi_ctrl);
rollback2:
	hsi_controller_exit(hsi_ctrl);

	/* From here no need for HSI HW access */
	hsi_clocks_disable(hsi_ctrl->dev, __func__);

rollback1:
	kfree(hsi_ctrl);
	return err;
}
Exemple #8
0
static int __init hsi_probe(struct platform_device *pd)
{
	struct hsi_platform_data *pdata = pd->dev.platform_data;
	struct hsi_dev *hsi_ctrl;
	u32 revision;
	int err;

	dev_dbg(&pd->dev, "The platform device probed is an %s\n",
			hsi_driver_device_is_hsi(pd) ? "HSI" : "SSI");

	if (!pdata) {
		pr_err(LOG_NAME "No platform_data found on hsi device\n");
		return -ENXIO;
	}

	hsi_ctrl = kzalloc(sizeof(*hsi_ctrl), GFP_KERNEL);
	if (hsi_ctrl == NULL) {
		dev_err(&pd->dev, "Could not allocate memory for"
			" struct hsi_dev\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pd, hsi_ctrl);
	err = hsi_controller_init(hsi_ctrl, pd);
	if (err < 0) {
		dev_err(&pd->dev, "Could not initialize hsi controller:"
			" %d\n", err);
		goto rollback1;
	}

	err = hsi_softreset(hsi_ctrl);
	if (err < 0)
		goto rollback2;

	/* Set default PM settings */
	hsi_outl((HSI_AUTOIDLE | HSI_SIDLEMODE_SMART | HSI_MIDLEMODE_SMART),
		 hsi_ctrl->base, HSI_SYS_SYSCONFIG_REG);
	hsi_outl(HSI_CLK_AUTOGATING_ON, hsi_ctrl->base, HSI_GDD_GCR_REG);

	/* Configure HSI ports */
	set_hsi_ports_default(hsi_ctrl, pd);

	/* Gather info from registers for the driver.(REVISION) */
	revision = hsi_inl(hsi_ctrl->base, HSI_SYS_REVISION_REG);
	if (hsi_driver_device_is_hsi(pd))
		dev_info(hsi_ctrl->dev, "HSI Hardware REVISION 0x%x\n",
								revision);
	else
		dev_info(hsi_ctrl->dev, "SSI Hardware REVISION %d.%d\n",
					(revision & HSI_SSI_REV_MAJOR) >> 4,
					(revision & HSI_SSI_REV_MINOR));


	err = hsi_debug_add_ctrl(hsi_ctrl);
	if (err < 0)
		goto rollback2;

	err = register_hsi_devices(hsi_ctrl);
	if (err < 0)
		goto rollback3;

	return err;

rollback3:
	hsi_debug_remove_ctrl(hsi_ctrl);
rollback2:
	hsi_controller_exit(hsi_ctrl);
rollback1:
	kfree(hsi_ctrl);
	return err;
}