536 lines
14 KiB
C
536 lines
14 KiB
C
/* arch/arm/mach-msm/smd_init_plat.c
|
|
*
|
|
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
#ifndef CONFIG_OF
|
|
#include <linux/platform_device.h>
|
|
#include <linux/module.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/io.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <mach/msm_iomap.h>
|
|
#include <mach/msm_ipc_logging.h>
|
|
#include <smd_private.h>
|
|
|
|
#define MODULE_NAME "msm_smd"
|
|
#define IPC_LOG(level, x...) do { \
|
|
if (smd_log_ctx) \
|
|
ipc_log_string(smd_log_ctx, x); \
|
|
else \
|
|
printk(level x); \
|
|
} while (0)
|
|
|
|
#if defined(CONFIG_MSM_SMD_DEBUG)
|
|
#define SMD_DBG(x...) do { \
|
|
if (msm_smd_debug_mask & MSM_SMD_DEBUG) \
|
|
IPC_LOG(KERN_DEBUG, x); \
|
|
} while (0)
|
|
|
|
#define SMD_INFO(x...) do { \
|
|
if (msm_smd_debug_mask & MSM_SMD_INFO) \
|
|
IPC_LOG(KERN_INFO, x); \
|
|
} while (0)
|
|
#else
|
|
#define SMD_DBG(x...) do { } while (0)
|
|
#define SMD_INFO(x...) do { } while (0)
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM8X60) \
|
|
|| defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_FSM9XXX) \
|
|
|| defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_APQ8064)
|
|
#define CONFIG_QDSP6 1
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960) \
|
|
|| defined(CONFIG_ARCH_APQ8064)
|
|
#define CONFIG_DSPS 1
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_MSM8960) \
|
|
|| defined(CONFIG_ARCH_APQ8064)
|
|
#define CONFIG_WCNSS 1
|
|
#define CONFIG_DSPS_SMSM 1
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_MSM7X30)
|
|
#define MSM_CFG_A2M_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_MODEM, 1 << 0, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_Q6, 1 << 8, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2M_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_MODEM, 1 << 5, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_Q6, 1 << 8, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2DSPS_SMD_INT
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#elif defined(CONFIG_ARCH_MSM8X60)
|
|
#define MSM_CFG_A2M_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_MODEM, 1 << 3, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_Q6, 1 << 15, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2M_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_MODEM, 1 << 4, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_Q6, 1 << 14, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2DSPS_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_DSPS, 1, \
|
|
MSM_SIC_NON_SECURE_BASE + 0x4080))
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#elif defined(CONFIG_ARCH_MSM9615)
|
|
#define MSM_CFG_A2M_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_MODEM, 1 << 3, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_Q6, 1 << 15, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2M_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_MODEM, 1 << 4, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_Q6, 1 << 14, MSM_APCS_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2DSPS_SMD_INT
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#elif defined(CONFIG_ARCH_FSM9XXX)
|
|
#define MSM_CFG_A2Q6_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_Q6, 1 << 10, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2Q6_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_Q6, 1 << 10, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2M_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_MODEM, 1 << 0, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2M_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_MODEM, 1 << 5, MSM_GCC_BASE + 0x8))
|
|
#define MSM_CFG_A2DSPS_SMD_INT
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#elif defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7x25)
|
|
#define MSM_CFG_A2M_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_MODEM, 1, MSM_CSR_BASE + 0x400 + (0) * 4))
|
|
#define MSM_CFG_A2Q6_SMD_INT
|
|
#define MSM_CFG_A2M_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_MODEM, 1, \
|
|
MSM_CSR_BASE + 0x400 + (5) * 4))
|
|
#define MSM_CFG_A2Q6_SMSM_INT
|
|
#define MSM_CFG_A2DSPS_SMD_INT
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#elif defined(CONFIG_ARCH_MSM7X27) || defined(CONFIG_ARCH_MSM7X27A)
|
|
#define MSM_CFG_A2M_SMD_INT \
|
|
(smd_cfg_smd_intr(SMD_MODEM, 1, MSM_CSR_BASE + 0x400 + (0) * 4))
|
|
#define MSM_CFG_A2Q6_SMD_INT
|
|
#define MSM_CFG_A2M_SMSM_INT \
|
|
(smd_cfg_smsm_intr(SMD_MODEM, 1, \
|
|
MSM_CSR_BASE + 0x400 + (5) * 4))
|
|
#define MSM_CFG_A2Q6_SMSM_INT
|
|
#define MSM_CFG_A2DSPS_SMD_INT
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#else /* use platform device / device tree configuration */
|
|
#define MSM_CFG_A2M_SMD_INT
|
|
#define MSM_CFG_A2Q6_SMD_INT
|
|
#define MSM_CFG_A2M_SMSM_INT
|
|
#define MSM_CFG_A2Q6_SMSM_INT
|
|
#define MSM_CFG_A2DSPS_SMD_INT
|
|
#define MSM_CFG_A2DSPS_SMSM_INT
|
|
#define MSM_CFG_A2WCNSS_SMD_INT
|
|
#define MSM_CFG_A2WCNSS_SMSM_INT
|
|
#endif
|
|
|
|
/*
|
|
* stub out legacy macros if they are not being used so that the legacy
|
|
* code compiles even though it is not used
|
|
*
|
|
* these definitions should not be used in active code and will cause
|
|
* an early failure
|
|
*/
|
|
#ifndef INT_A9_M2A_0
|
|
#define INT_A9_M2A_0 -1
|
|
#endif
|
|
#ifndef INT_A9_M2A_5
|
|
#define INT_A9_M2A_5 -1
|
|
#endif
|
|
#ifndef INT_ADSP_A11
|
|
#define INT_ADSP_A11 -1
|
|
#endif
|
|
#ifndef INT_ADSP_A11_SMSM
|
|
#define INT_ADSP_A11_SMSM -1
|
|
#endif
|
|
#ifndef INT_DSPS_A11
|
|
#define INT_DSPS_A11 -1
|
|
#endif
|
|
#ifndef INT_DSPS_A11_SMSM
|
|
#define INT_DSPS_A11_SMSM -1
|
|
#endif
|
|
#ifndef INT_WCNSS_A11
|
|
#define INT_WCNSS_A11 -1
|
|
#endif
|
|
#ifndef INT_WCNSS_A11_SMSM
|
|
#define INT_WCNSS_A11_SMSM -1
|
|
#endif
|
|
|
|
static int intr_init(struct interrupt_config_item *private_irq,
|
|
struct smd_irq_config *platform_irq,
|
|
struct platform_device *pdev
|
|
)
|
|
{
|
|
int irq_id;
|
|
int ret;
|
|
int ret_wake;
|
|
|
|
private_irq->out_bit_pos = platform_irq->out_bit_pos;
|
|
private_irq->out_offset = platform_irq->out_offset;
|
|
private_irq->out_base = platform_irq->out_base;
|
|
|
|
irq_id = platform_get_irq_byname(
|
|
pdev,
|
|
platform_irq->irq_name
|
|
);
|
|
SMD_DBG("smd: %s: register irq: %s id: %d\n", __func__,
|
|
platform_irq->irq_name, irq_id);
|
|
ret = request_irq(irq_id,
|
|
private_irq->irq_handler,
|
|
platform_irq->flags,
|
|
platform_irq->device_name,
|
|
(void *)platform_irq->dev_id
|
|
);
|
|
if (ret < 0) {
|
|
platform_irq->irq_id = ret;
|
|
private_irq->irq_id = ret;
|
|
} else {
|
|
platform_irq->irq_id = irq_id;
|
|
private_irq->irq_id = irq_id;
|
|
ret_wake = enable_irq_wake(irq_id);
|
|
if (ret_wake < 0) {
|
|
pr_err("smd: enable_irq_wake failed on %s",
|
|
platform_irq->irq_name);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int smd_core_init(void)
|
|
{
|
|
int r;
|
|
unsigned long flags = IRQF_TRIGGER_RISING;
|
|
SMD_INFO("smd_core_init()\n");
|
|
|
|
MSM_CFG_A2M_SMD_INT;
|
|
MSM_CFG_A2Q6_SMD_INT;
|
|
MSM_CFG_A2M_SMSM_INT;
|
|
MSM_CFG_A2Q6_SMSM_INT;
|
|
MSM_CFG_A2DSPS_SMD_INT;
|
|
MSM_CFG_A2DSPS_SMSM_INT;
|
|
MSM_CFG_A2WCNSS_SMD_INT;
|
|
MSM_CFG_A2WCNSS_SMSM_INT;
|
|
|
|
r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
|
|
flags, "smd_dev", 0);
|
|
if (r < 0)
|
|
return r;
|
|
interrupt_stats[SMD_MODEM].smd_interrupt_id = INT_A9_M2A_0;
|
|
r = enable_irq_wake(INT_A9_M2A_0);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_A9_M2A_0\n",
|
|
__func__);
|
|
|
|
r = request_irq(INT_A9_M2A_5, smsm_modem_irq_handler,
|
|
flags, "smsm_dev", 0);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
return r;
|
|
}
|
|
interrupt_stats[SMD_MODEM].smsm_interrupt_id = INT_A9_M2A_5;
|
|
r = enable_irq_wake(INT_A9_M2A_5);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_A9_M2A_5\n",
|
|
__func__);
|
|
|
|
#if defined(CONFIG_QDSP6)
|
|
#if (INT_ADSP_A11 == INT_ADSP_A11_SMSM)
|
|
flags |= IRQF_SHARED;
|
|
#endif
|
|
r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
|
|
flags, "smd_dev", smd_dsp_irq_handler);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
free_irq(INT_A9_M2A_5, 0);
|
|
return r;
|
|
}
|
|
|
|
interrupt_stats[SMD_Q6].smd_interrupt_id = INT_ADSP_A11;
|
|
r = request_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler,
|
|
flags, "smsm_dev", smsm_dsp_irq_handler);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
free_irq(INT_A9_M2A_5, 0);
|
|
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
|
|
return r;
|
|
}
|
|
|
|
interrupt_stats[SMD_Q6].smsm_interrupt_id = INT_ADSP_A11_SMSM;
|
|
r = enable_irq_wake(INT_ADSP_A11);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_ADSP_A11\n",
|
|
__func__);
|
|
|
|
#if (INT_ADSP_A11 != INT_ADSP_A11_SMSM)
|
|
r = enable_irq_wake(INT_ADSP_A11_SMSM);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_ADSP_A11_SMSM\n",
|
|
__func__);
|
|
#endif
|
|
flags &= ~IRQF_SHARED;
|
|
#endif
|
|
|
|
#if defined(CONFIG_DSPS)
|
|
r = request_irq(INT_DSPS_A11, smd_dsps_irq_handler,
|
|
flags, "smd_dev", smd_dsps_irq_handler);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
free_irq(INT_A9_M2A_5, 0);
|
|
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
|
|
free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
|
|
return r;
|
|
}
|
|
|
|
interrupt_stats[SMD_DSPS].smd_interrupt_id = INT_DSPS_A11;
|
|
r = enable_irq_wake(INT_DSPS_A11);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_ADSP_A11\n",
|
|
__func__);
|
|
#endif
|
|
|
|
#if defined(CONFIG_WCNSS)
|
|
r = request_irq(INT_WCNSS_A11, smd_wcnss_irq_handler,
|
|
flags, "smd_dev", smd_wcnss_irq_handler);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
free_irq(INT_A9_M2A_5, 0);
|
|
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
|
|
free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
|
|
free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
|
|
return r;
|
|
}
|
|
|
|
interrupt_stats[SMD_WCNSS].smd_interrupt_id = INT_WCNSS_A11;
|
|
r = enable_irq_wake(INT_WCNSS_A11);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_WCNSS_A11\n",
|
|
__func__);
|
|
|
|
r = request_irq(INT_WCNSS_A11_SMSM, smsm_wcnss_irq_handler,
|
|
flags, "smsm_dev", smsm_wcnss_irq_handler);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
free_irq(INT_A9_M2A_5, 0);
|
|
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
|
|
free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
|
|
free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
|
|
free_irq(INT_WCNSS_A11, smd_wcnss_irq_handler);
|
|
return r;
|
|
}
|
|
|
|
interrupt_stats[SMD_WCNSS].smsm_interrupt_id = INT_WCNSS_A11_SMSM;
|
|
r = enable_irq_wake(INT_WCNSS_A11_SMSM);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_WCNSS_A11_SMSM\n",
|
|
__func__);
|
|
#endif
|
|
|
|
#if defined(CONFIG_DSPS_SMSM)
|
|
r = request_irq(INT_DSPS_A11_SMSM, smsm_dsps_irq_handler,
|
|
flags, "smsm_dev", smsm_dsps_irq_handler);
|
|
if (r < 0) {
|
|
free_irq(INT_A9_M2A_0, 0);
|
|
free_irq(INT_A9_M2A_5, 0);
|
|
free_irq(INT_ADSP_A11, smd_dsp_irq_handler);
|
|
free_irq(INT_ADSP_A11_SMSM, smsm_dsp_irq_handler);
|
|
free_irq(INT_DSPS_A11, smd_dsps_irq_handler);
|
|
free_irq(INT_WCNSS_A11, smd_wcnss_irq_handler);
|
|
free_irq(INT_WCNSS_A11_SMSM, smsm_wcnss_irq_handler);
|
|
return r;
|
|
}
|
|
|
|
interrupt_stats[SMD_DSPS].smsm_interrupt_id = INT_DSPS_A11_SMSM;
|
|
r = enable_irq_wake(INT_DSPS_A11_SMSM);
|
|
if (r < 0)
|
|
pr_err("%s: enable_irq_wake failed for INT_DSPS_A11_SMSM\n",
|
|
__func__);
|
|
#endif
|
|
SMD_INFO("smd_core_init() done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int smd_core_platform_init(struct platform_device *pdev)
|
|
{
|
|
int i;
|
|
int ret;
|
|
uint32_t num_ss;
|
|
struct smd_platform *smd_platform_data;
|
|
struct smd_subsystem_config *smd_ss_config_list;
|
|
struct smd_subsystem_config *cfg;
|
|
struct interrupt_config *private_intr_config;
|
|
int err_ret = 0;
|
|
|
|
smd_platform_data = pdev->dev.platform_data;
|
|
num_ss = smd_platform_data->num_ss_configs;
|
|
smd_ss_config_list = smd_platform_data->smd_ss_configs;
|
|
|
|
if (smd_platform_data->smd_ssr_config)
|
|
disable_smsm_reset_handshake = smd_platform_data->
|
|
smd_ssr_config->disable_smsm_reset_handshake;
|
|
|
|
for (i = 0; i < num_ss; i++) {
|
|
cfg = &smd_ss_config_list[i];
|
|
private_intr_config = smd_get_intr_config(cfg->edge);
|
|
if (!private_intr_config) {
|
|
pr_err("%s: invalid edge\n", __func__);
|
|
goto intr_failed;
|
|
}
|
|
|
|
ret = intr_init(
|
|
&private_intr_config->smd,
|
|
&cfg->smd_int,
|
|
pdev
|
|
);
|
|
|
|
if (ret < 0) {
|
|
err_ret = ret;
|
|
pr_err("smd: register irq failed on %s\n",
|
|
cfg->smd_int.irq_name);
|
|
goto intr_failed;
|
|
}
|
|
|
|
interrupt_stats[cfg->irq_config_id].smd_interrupt_id
|
|
= cfg->smd_int.irq_id;
|
|
/* only init smsm structs if this edge supports smsm */
|
|
if (cfg->smsm_int.irq_id)
|
|
ret = intr_init(
|
|
&private_intr_config->smsm,
|
|
&cfg->smsm_int,
|
|
pdev
|
|
);
|
|
|
|
if (ret < 0) {
|
|
err_ret = ret;
|
|
pr_err("smd: register irq failed on %s\n",
|
|
cfg->smsm_int.irq_name);
|
|
goto intr_failed;
|
|
}
|
|
|
|
if (cfg->smsm_int.irq_id)
|
|
interrupt_stats[cfg->irq_config_id].smsm_interrupt_id
|
|
= cfg->smsm_int.irq_id;
|
|
if (cfg->subsys_name)
|
|
smd_set_edge_subsys_name(cfg->edge, cfg->subsys_name);
|
|
|
|
smd_set_edge_initialized(cfg->edge);
|
|
}
|
|
|
|
SMD_INFO("smd_core_platform_init() done\n");
|
|
|
|
return 0;
|
|
|
|
intr_failed:
|
|
pr_err("smd: deregistering IRQs\n");
|
|
for (i = 0; i < num_ss; ++i) {
|
|
cfg = &smd_ss_config_list[i];
|
|
|
|
if (cfg->smd_int.irq_id >= 0)
|
|
free_irq(cfg->smd_int.irq_id,
|
|
(void *)cfg->smd_int.dev_id
|
|
);
|
|
if (cfg->smsm_int.irq_id >= 0)
|
|
free_irq(cfg->smsm_int.irq_id,
|
|
(void *)cfg->smsm_int.dev_id
|
|
);
|
|
}
|
|
return err_ret;
|
|
}
|
|
|
|
static int msm_smd_probe_legacy(struct platform_device *pdev)
|
|
{
|
|
int ret;
|
|
|
|
if (!smem_initialized_check())
|
|
return -ENODEV;
|
|
|
|
SMD_INFO("smd probe\n");
|
|
if (pdev) {
|
|
if (pdev->dev.of_node) {
|
|
pr_err("%s: invalid device tree init\n", __func__);
|
|
return -ENODEV;
|
|
} else if (pdev->dev.platform_data) {
|
|
ret = smd_core_platform_init(pdev);
|
|
if (ret) {
|
|
pr_err(
|
|
"SMD: smd_core_platform_init() failed\n");
|
|
return -ENODEV;
|
|
}
|
|
} else {
|
|
ret = smd_core_init();
|
|
if (ret) {
|
|
pr_err("smd_core_init() failed\n");
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
} else {
|
|
pr_err("SMD: PDEV not found\n");
|
|
return -ENODEV;
|
|
}
|
|
|
|
ret = smsm_post_init();
|
|
if (ret) {
|
|
pr_err("smd_post_init() failed ret = %d\n", ret);
|
|
return ret;
|
|
}
|
|
smd_post_init(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct platform_driver msm_smd_driver_legacy = {
|
|
.probe = msm_smd_probe_legacy,
|
|
.driver = {
|
|
.name = MODULE_NAME,
|
|
.owner = THIS_MODULE,
|
|
},
|
|
};
|
|
|
|
int msm_smd_driver_register(void)
|
|
{
|
|
|
|
int rc;
|
|
|
|
rc = platform_driver_register(&msm_smd_driver_legacy);
|
|
if (rc) {
|
|
pr_err("%s: smd_driver register failed %d\n",
|
|
__func__, rc);
|
|
return rc;
|
|
}
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(msm_smd_driver_register);
|
|
|
|
MODULE_DESCRIPTION("MSM SMD Legacy/Platform Device Init");
|
|
MODULE_LICENSE("GPL v2");
|
|
#endif
|