Merge "esoc: mdm-4x: Add support for mdm9x45 and apq8096"
This commit is contained in:
commit
a2c574ad5b
9 changed files with 332 additions and 29 deletions
|
@ -6,8 +6,8 @@ to be reset.
|
||||||
|
|
||||||
Required Properties:
|
Required Properties:
|
||||||
- compatible: The bus devices need to be compatible with
|
- compatible: The bus devices need to be compatible with
|
||||||
"qcom,mdm2-modem", "qcom,ext-mdm9x25", "qcom,ext-mdm9x35", "qcom, ext-mdm9x45",
|
"qcom,mdm2-modem", "qcom,ext-mdm9x25", "qcom,ext-mdm9x35", "qcom,ext-mdm9x45",
|
||||||
"qcom,ext-mdm9x55".
|
"qcom,ext-mdm9x55", "qcom,ext-apq8096".
|
||||||
|
|
||||||
Required named gpio properties:
|
Required named gpio properties:
|
||||||
- qcom,mdm2ap-errfatal-gpio: gpio for the external modem to indicate to the apps processor
|
- qcom,mdm2ap-errfatal-gpio: gpio for the external modem to indicate to the apps processor
|
||||||
|
|
|
@ -179,19 +179,37 @@ static int mdm_cmd_exe(enum esoc_cmd cmd, struct esoc_clink *esoc)
|
||||||
struct device *dev = mdm->dev;
|
struct device *dev = mdm->dev;
|
||||||
int ret;
|
int ret;
|
||||||
bool graceful_shutdown = false;
|
bool graceful_shutdown = false;
|
||||||
|
u32 status, err_fatal;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case ESOC_PWR_ON:
|
case ESOC_PWR_ON:
|
||||||
|
if (esoc->auto_boot) {
|
||||||
|
/*
|
||||||
|
* If esoc has already booted, we would have missed
|
||||||
|
* status change interrupt. Read status and err_fatal
|
||||||
|
* signals to arrive at the state of esoc.
|
||||||
|
*/
|
||||||
|
esoc->clink_ops->get_status(&status, esoc);
|
||||||
|
esoc->clink_ops->get_err_fatal(&err_fatal, esoc);
|
||||||
|
if (err_fatal)
|
||||||
|
return -EIO;
|
||||||
|
if (status && !mdm->ready) {
|
||||||
|
mdm->ready = true;
|
||||||
|
esoc->clink_ops->notify(ESOC_BOOT_DONE, esoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
|
gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
|
||||||
mdm_enable_irqs(mdm);
|
|
||||||
mdm->init = 1;
|
mdm->init = 1;
|
||||||
mdm_do_first_power_on(mdm);
|
mdm_do_first_power_on(mdm);
|
||||||
|
mdm_enable_irqs(mdm);
|
||||||
break;
|
break;
|
||||||
case ESOC_PWR_OFF:
|
case ESOC_PWR_OFF:
|
||||||
mdm_disable_irqs(mdm);
|
mdm_disable_irqs(mdm);
|
||||||
mdm->debug = 0;
|
mdm->debug = 0;
|
||||||
mdm->ready = false;
|
mdm->ready = false;
|
||||||
mdm->trig_cnt = 0;
|
mdm->trig_cnt = 0;
|
||||||
|
if (esoc->primary)
|
||||||
|
break;
|
||||||
graceful_shutdown = true;
|
graceful_shutdown = true;
|
||||||
ret = sysmon_send_shutdown(&esoc->subsys);
|
ret = sysmon_send_shutdown(&esoc->subsys);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -228,6 +246,8 @@ force_poff:
|
||||||
esoc->subsys.sysmon_shutdown_ret);
|
esoc->subsys.sysmon_shutdown_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esoc->primary)
|
||||||
|
break;
|
||||||
/*
|
/*
|
||||||
* Force a shutdown of the mdm. This is required in order
|
* Force a shutdown of the mdm. This is required in order
|
||||||
* to prevent the mdm from immediately powering back on
|
* to prevent the mdm from immediately powering back on
|
||||||
|
@ -249,9 +269,12 @@ force_poff:
|
||||||
*/
|
*/
|
||||||
mdm->ready = false;
|
mdm->ready = false;
|
||||||
cancel_delayed_work(&mdm->mdm2ap_status_check_work);
|
cancel_delayed_work(&mdm->mdm2ap_status_check_work);
|
||||||
gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
|
if (!mdm->esoc->auto_boot) {
|
||||||
dev_dbg(mdm->dev, "set ap2mdm errfatal to force reset\n");
|
gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
|
||||||
msleep(mdm->ramdump_delay_ms);
|
dev_dbg(mdm->dev,
|
||||||
|
"set ap2mdm errfatal to force reset\n");
|
||||||
|
msleep(mdm->ramdump_delay_ms);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ESOC_EXE_DEBUG:
|
case ESOC_EXE_DEBUG:
|
||||||
mdm->debug = 1;
|
mdm->debug = 1;
|
||||||
|
@ -378,6 +401,8 @@ static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc)
|
||||||
status_down = false;
|
status_down = false;
|
||||||
dev_dbg(dev, "signal apq err fatal for graceful restart\n");
|
dev_dbg(dev, "signal apq err fatal for graceful restart\n");
|
||||||
gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
|
gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
|
||||||
|
if (esoc->primary)
|
||||||
|
break;
|
||||||
timeout = local_clock();
|
timeout = local_clock();
|
||||||
do_div(timeout, NSEC_PER_MSEC);
|
do_div(timeout, NSEC_PER_MSEC);
|
||||||
timeout += MDM_MODEM_TIMEOUT;
|
timeout += MDM_MODEM_TIMEOUT;
|
||||||
|
@ -420,7 +445,7 @@ static irqreturn_t mdm_errfatal(int irq, void *dev_id)
|
||||||
goto mdm_pwroff_irq;
|
goto mdm_pwroff_irq;
|
||||||
esoc = mdm->esoc;
|
esoc = mdm->esoc;
|
||||||
dev_err(dev, "%s: mdm sent errfatal interrupt\n",
|
dev_err(dev, "%s: mdm sent errfatal interrupt\n",
|
||||||
__func__);
|
__func__);
|
||||||
/* disable irq ?*/
|
/* disable irq ?*/
|
||||||
esoc_clink_evt_notify(ESOC_ERR_FATAL, esoc);
|
esoc_clink_evt_notify(ESOC_ERR_FATAL, esoc);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@ -441,11 +466,25 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
dev = mdm->dev;
|
dev = mdm->dev;
|
||||||
esoc = mdm->esoc;
|
esoc = mdm->esoc;
|
||||||
|
/*
|
||||||
|
* On auto boot devices, there is a possibility of receiving
|
||||||
|
* status change interrupt before esoc_clink structure is
|
||||||
|
* initialized. Ignore them.
|
||||||
|
*/
|
||||||
|
if (!esoc)
|
||||||
|
return IRQ_HANDLED;
|
||||||
value = gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS));
|
value = gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS));
|
||||||
if (value == 0 && mdm->ready) {
|
if (value == 0 && mdm->ready) {
|
||||||
dev_err(dev, "unexpected reset external modem\n");
|
dev_err(dev, "unexpected reset external modem\n");
|
||||||
esoc_clink_evt_notify(ESOC_UNEXPECTED_RESET, esoc);
|
esoc_clink_evt_notify(ESOC_UNEXPECTED_RESET, esoc);
|
||||||
} else if (value == 1) {
|
} else if (value == 1) {
|
||||||
|
/*
|
||||||
|
* In auto_boot cases, bailout early if mdm
|
||||||
|
* is up already.
|
||||||
|
*/
|
||||||
|
if (esoc->auto_boot && mdm->ready)
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
cancel_delayed_work(&mdm->mdm2ap_status_check_work);
|
cancel_delayed_work(&mdm->mdm2ap_status_check_work);
|
||||||
dev_dbg(dev, "status = 1: mdm is now ready\n");
|
dev_dbg(dev, "status = 1: mdm is now ready\n");
|
||||||
mdm->ready = true;
|
mdm->ready = true;
|
||||||
|
@ -453,6 +492,8 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id)
|
||||||
queue_work(mdm->mdm_queue, &mdm->mdm_status_work);
|
queue_work(mdm->mdm_queue, &mdm->mdm_status_work);
|
||||||
if (mdm->get_restart_reason)
|
if (mdm->get_restart_reason)
|
||||||
queue_work(mdm->mdm_queue, &mdm->restart_reason_work);
|
queue_work(mdm->mdm_queue, &mdm->restart_reason_work);
|
||||||
|
if (esoc->auto_boot)
|
||||||
|
esoc->clink_ops->notify(ESOC_BOOT_DONE, esoc);
|
||||||
}
|
}
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -481,7 +522,7 @@ static irqreturn_t mdm_pblrdy_change(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdm_get_status(u32 *status, struct esoc_clink *esoc)
|
static void mdm_get_status(u32 *status, struct esoc_clink *esoc)
|
||||||
{
|
{
|
||||||
struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
|
struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
|
||||||
|
|
||||||
|
@ -489,7 +530,16 @@ static int mdm_get_status(u32 *status, struct esoc_clink *esoc)
|
||||||
*status = 0;
|
*status = 0;
|
||||||
else
|
else
|
||||||
*status = 1;
|
*status = 1;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
static void mdm_get_err_fatal(u32 *status, struct esoc_clink *esoc)
|
||||||
|
{
|
||||||
|
struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
|
||||||
|
|
||||||
|
if (gpio_get_value(MDM_GPIO(mdm, MDM2AP_ERRFATAL)) == 0)
|
||||||
|
*status = 0;
|
||||||
|
else
|
||||||
|
*status = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mdm_configure_debug(struct mdm_ctrl *mdm)
|
static void mdm_configure_debug(struct mdm_ctrl *mdm)
|
||||||
|
@ -573,13 +623,21 @@ static int mdm_configure_ipc(struct mdm_ctrl *mdm, struct platform_device *pdev)
|
||||||
&mdm->ramdump_delay_ms);
|
&mdm->ramdump_delay_ms);
|
||||||
if (ret)
|
if (ret)
|
||||||
mdm->ramdump_delay_ms = DEF_RAMDUMP_DELAY;
|
mdm->ramdump_delay_ms = DEF_RAMDUMP_DELAY;
|
||||||
/* Multilple gpio_request calls are allowed */
|
/*
|
||||||
|
* In certain scenarios, multiple esoc devices are monitoring
|
||||||
|
* same AP2MDM_STATUS line. But only one of them will have a
|
||||||
|
* successful gpio_request call. Initialize gpio only if request
|
||||||
|
* succeeds.
|
||||||
|
*/
|
||||||
if (gpio_request(MDM_GPIO(mdm, AP2MDM_STATUS), "AP2MDM_STATUS"))
|
if (gpio_request(MDM_GPIO(mdm, AP2MDM_STATUS), "AP2MDM_STATUS"))
|
||||||
dev_err(dev, "Failed to configure AP2MDM_STATUS gpio\n");
|
dev_err(dev, "Failed to configure AP2MDM_STATUS gpio\n");
|
||||||
/* Multilple gpio_request calls are allowed */
|
else
|
||||||
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 0);
|
||||||
if (gpio_request(MDM_GPIO(mdm, AP2MDM_ERRFATAL), "AP2MDM_ERRFATAL"))
|
if (gpio_request(MDM_GPIO(mdm, AP2MDM_ERRFATAL), "AP2MDM_ERRFATAL"))
|
||||||
dev_err(dev, "%s Failed to configure AP2MDM_ERRFATAL gpio\n",
|
dev_err(dev, "%s Failed to configure AP2MDM_ERRFATAL gpio\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
else
|
||||||
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
|
||||||
if (gpio_request(MDM_GPIO(mdm, MDM2AP_STATUS), "MDM2AP_STATUS")) {
|
if (gpio_request(MDM_GPIO(mdm, MDM2AP_STATUS), "MDM2AP_STATUS")) {
|
||||||
dev_err(dev, "%s Failed to configure MDM2AP_STATUS gpio\n",
|
dev_err(dev, "%s Failed to configure MDM2AP_STATUS gpio\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -612,9 +670,6 @@ static int mdm_configure_ipc(struct mdm_ctrl *mdm, struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 0);
|
|
||||||
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
|
|
||||||
|
|
||||||
if (gpio_is_valid(MDM_GPIO(mdm, AP2MDM_CHNLRDY)))
|
if (gpio_is_valid(MDM_GPIO(mdm, AP2MDM_CHNLRDY)))
|
||||||
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_CHNLRDY), 0);
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_CHNLRDY), 0);
|
||||||
|
|
||||||
|
@ -748,6 +803,7 @@ static int mdm9x25_setup_hw(struct mdm_ctrl *mdm,
|
||||||
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
||||||
return PTR_ERR(esoc);
|
return PTR_ERR(esoc);
|
||||||
}
|
}
|
||||||
|
esoc->pdev = pdev;
|
||||||
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
||||||
if (!mdm->mdm_queue) {
|
if (!mdm->mdm_queue) {
|
||||||
dev_err(mdm->dev, "could not create mdm_queue\n");
|
dev_err(mdm->dev, "could not create mdm_queue\n");
|
||||||
|
@ -818,6 +874,7 @@ static int mdm9x35_setup_hw(struct mdm_ctrl *mdm,
|
||||||
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
||||||
return PTR_ERR(esoc);
|
return PTR_ERR(esoc);
|
||||||
}
|
}
|
||||||
|
esoc->pdev = pdev;
|
||||||
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
||||||
if (!mdm->mdm_queue) {
|
if (!mdm->mdm_queue) {
|
||||||
dev_err(mdm->dev, "could not create mdm_queue\n");
|
dev_err(mdm->dev, "could not create mdm_queue\n");
|
||||||
|
@ -888,6 +945,80 @@ static int mdm9x35_setup_hw(struct mdm_ctrl *mdm,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mdm9x45_setup_hw(struct mdm_ctrl *mdm,
|
||||||
|
const struct mdm_ops *ops,
|
||||||
|
struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct esoc_clink *esoc;
|
||||||
|
const struct esoc_clink_ops *const clink_ops = ops->clink_ops;
|
||||||
|
const struct mdm_pon_ops *pon_ops = ops->pon_ops;
|
||||||
|
|
||||||
|
mdm->dev = &pdev->dev;
|
||||||
|
mdm->pon_ops = pon_ops;
|
||||||
|
esoc = devm_kzalloc(mdm->dev, sizeof(*esoc), GFP_KERNEL);
|
||||||
|
if (IS_ERR_OR_NULL(esoc)) {
|
||||||
|
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
||||||
|
return PTR_ERR(esoc);
|
||||||
|
}
|
||||||
|
esoc->pdev = pdev;
|
||||||
|
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
||||||
|
if (!mdm->mdm_queue) {
|
||||||
|
dev_err(mdm->dev, "could not create mdm_queue\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
mdm->irq_mask = 0;
|
||||||
|
mdm->ready = false;
|
||||||
|
ret = mdm_dt_parse_gpios(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_err(mdm->dev, "parsing gpio done\n");
|
||||||
|
ret = mdm_pon_dt_init(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "pon dt init done\n");
|
||||||
|
ret = mdm_pinctrl_init(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_err(mdm->dev, "pinctrl init done\n");
|
||||||
|
ret = mdm_pon_setup(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "pon setup done\n");
|
||||||
|
ret = mdm_configure_ipc(mdm, pdev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
mdm_configure_debug(mdm);
|
||||||
|
dev_err(mdm->dev, "ipc configure done\n");
|
||||||
|
esoc->name = MDM9x45_LABEL;
|
||||||
|
esoc->link_name = MDM9x45_PCIE;
|
||||||
|
esoc->clink_ops = clink_ops;
|
||||||
|
esoc->parent = mdm->dev;
|
||||||
|
esoc->owner = THIS_MODULE;
|
||||||
|
esoc->np = pdev->dev.of_node;
|
||||||
|
|
||||||
|
esoc->auto_boot = of_property_read_bool(esoc->np,
|
||||||
|
"qcom,mdm-auto-boot");
|
||||||
|
set_esoc_clink_data(esoc, mdm);
|
||||||
|
ret = esoc_clink_register(esoc);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(mdm->dev, "esoc registration failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
dev_dbg(mdm->dev, "esoc registration done\n");
|
||||||
|
init_completion(&mdm->debug_done);
|
||||||
|
INIT_WORK(&mdm->mdm_status_work, mdm_status_fn);
|
||||||
|
INIT_WORK(&mdm->restart_reason_work, mdm_get_restart_reason);
|
||||||
|
INIT_DELAYED_WORK(&mdm->mdm2ap_status_check_work, mdm2ap_status_check);
|
||||||
|
mdm->get_restart_reason = false;
|
||||||
|
mdm->debug_fail = false;
|
||||||
|
mdm->esoc = esoc;
|
||||||
|
mdm->init = 0;
|
||||||
|
if (esoc->auto_boot)
|
||||||
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mdm9x55_setup_hw(struct mdm_ctrl *mdm,
|
static int mdm9x55_setup_hw(struct mdm_ctrl *mdm,
|
||||||
const struct mdm_ops *ops,
|
const struct mdm_ops *ops,
|
||||||
struct platform_device *pdev)
|
struct platform_device *pdev)
|
||||||
|
@ -906,6 +1037,7 @@ static int mdm9x55_setup_hw(struct mdm_ctrl *mdm,
|
||||||
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
||||||
return PTR_ERR(esoc);
|
return PTR_ERR(esoc);
|
||||||
}
|
}
|
||||||
|
esoc->pdev = pdev;
|
||||||
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
||||||
if (!mdm->mdm_queue) {
|
if (!mdm->mdm_queue) {
|
||||||
dev_err(mdm->dev, "could not create mdm_queue\n");
|
dev_err(mdm->dev, "could not create mdm_queue\n");
|
||||||
|
@ -963,9 +1095,86 @@ static int mdm9x55_setup_hw(struct mdm_ctrl *mdm,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int apq8096_setup_hw(struct mdm_ctrl *mdm,
|
||||||
|
const struct mdm_ops *ops,
|
||||||
|
struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct device_node *node;
|
||||||
|
struct esoc_clink *esoc;
|
||||||
|
const struct esoc_clink_ops *const clink_ops = ops->clink_ops;
|
||||||
|
const struct mdm_pon_ops *pon_ops = ops->pon_ops;
|
||||||
|
|
||||||
|
mdm->dev = &pdev->dev;
|
||||||
|
mdm->pon_ops = pon_ops;
|
||||||
|
node = pdev->dev.of_node;
|
||||||
|
esoc = devm_kzalloc(mdm->dev, sizeof(*esoc), GFP_KERNEL);
|
||||||
|
if (IS_ERR_OR_NULL(esoc)) {
|
||||||
|
dev_err(mdm->dev, "cannot allocate esoc device\n");
|
||||||
|
return PTR_ERR(esoc);
|
||||||
|
}
|
||||||
|
esoc->pdev = pdev;
|
||||||
|
mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
|
||||||
|
if (!mdm->mdm_queue) {
|
||||||
|
dev_err(mdm->dev, "could not create mdm_queue\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
mdm->irq_mask = 0;
|
||||||
|
mdm->ready = false;
|
||||||
|
ret = mdm_dt_parse_gpios(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "parsing gpio done\n");
|
||||||
|
ret = mdm_pon_dt_init(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "pon dt init done\n");
|
||||||
|
ret = mdm_pinctrl_init(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "pinctrl init done\n");
|
||||||
|
ret = mdm_pon_setup(mdm);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "pon setup done\n");
|
||||||
|
ret = mdm_configure_ipc(mdm, pdev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
dev_dbg(mdm->dev, "ipc configure done\n");
|
||||||
|
esoc->name = APQ8096_LABEL;
|
||||||
|
esoc->link_name = APQ8096_PCIE;
|
||||||
|
esoc->clink_ops = clink_ops;
|
||||||
|
esoc->parent = mdm->dev;
|
||||||
|
esoc->owner = THIS_MODULE;
|
||||||
|
esoc->np = pdev->dev.of_node;
|
||||||
|
esoc->auto_boot = of_property_read_bool(esoc->np,
|
||||||
|
"qcom,mdm-auto-boot");
|
||||||
|
esoc->primary = of_property_read_bool(esoc->np,
|
||||||
|
"qcom,mdm-primary");
|
||||||
|
set_esoc_clink_data(esoc, mdm);
|
||||||
|
ret = esoc_clink_register(esoc);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(mdm->dev, "esoc registration failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
dev_dbg(mdm->dev, "esoc registration done\n");
|
||||||
|
init_completion(&mdm->debug_done);
|
||||||
|
INIT_WORK(&mdm->mdm_status_work, mdm_status_fn);
|
||||||
|
INIT_WORK(&mdm->restart_reason_work, mdm_get_restart_reason);
|
||||||
|
INIT_DELAYED_WORK(&mdm->mdm2ap_status_check_work, mdm2ap_status_check);
|
||||||
|
mdm->get_restart_reason = false;
|
||||||
|
mdm->debug_fail = false;
|
||||||
|
mdm->esoc = esoc;
|
||||||
|
mdm->init = 0;
|
||||||
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1);
|
||||||
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct esoc_clink_ops mdm_cops = {
|
static struct esoc_clink_ops mdm_cops = {
|
||||||
.cmd_exe = mdm_cmd_exe,
|
.cmd_exe = mdm_cmd_exe,
|
||||||
.get_status = mdm_get_status,
|
.get_status = mdm_get_status,
|
||||||
|
.get_err_fatal = mdm_get_err_fatal,
|
||||||
.notify = mdm_notify,
|
.notify = mdm_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -981,6 +1190,18 @@ static struct mdm_ops mdm9x35_ops = {
|
||||||
.pon_ops = &mdm9x35_pon_ops,
|
.pon_ops = &mdm9x35_pon_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct mdm_ops mdm9x45_ops = {
|
||||||
|
.clink_ops = &mdm_cops,
|
||||||
|
.config_hw = mdm9x45_setup_hw,
|
||||||
|
.pon_ops = &mdm9x45_pon_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mdm_ops apq8096_ops = {
|
||||||
|
.clink_ops = &mdm_cops,
|
||||||
|
.config_hw = apq8096_setup_hw,
|
||||||
|
.pon_ops = &apq8096_pon_ops,
|
||||||
|
};
|
||||||
|
|
||||||
static struct mdm_ops mdm9x55_ops = {
|
static struct mdm_ops mdm9x55_ops = {
|
||||||
.clink_ops = &mdm_cops,
|
.clink_ops = &mdm_cops,
|
||||||
.config_hw = mdm9x55_setup_hw,
|
.config_hw = mdm9x55_setup_hw,
|
||||||
|
@ -992,8 +1213,12 @@ static const struct of_device_id mdm_dt_match[] = {
|
||||||
.data = &mdm9x25_ops, },
|
.data = &mdm9x25_ops, },
|
||||||
{ .compatible = "qcom,ext-mdm9x35",
|
{ .compatible = "qcom,ext-mdm9x35",
|
||||||
.data = &mdm9x35_ops, },
|
.data = &mdm9x35_ops, },
|
||||||
|
{ .compatible = "qcom,ext-mdm9x45",
|
||||||
|
.data = &mdm9x45_ops, },
|
||||||
{ .compatible = "qcom,ext-mdm9x55",
|
{ .compatible = "qcom,ext-mdm9x55",
|
||||||
.data = &mdm9x55_ops, },
|
.data = &mdm9x55_ops, },
|
||||||
|
{ .compatible = "qcom,ext-apq8096",
|
||||||
|
.data = &apq8096_ops, },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, mdm_dt_match);
|
MODULE_DEVICE_TABLE(of, mdm_dt_match);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include "esoc.h"
|
#include "esoc.h"
|
||||||
#include "mdm-dbg.h"
|
#include "mdm-dbg.h"
|
||||||
|
|
||||||
|
@ -72,7 +73,14 @@ static void mdm_handle_clink_evt(enum esoc_evt evt,
|
||||||
break;
|
break;
|
||||||
case ESOC_UNEXPECTED_RESET:
|
case ESOC_UNEXPECTED_RESET:
|
||||||
case ESOC_ERR_FATAL:
|
case ESOC_ERR_FATAL:
|
||||||
if (mdm_drv->mode == CRASH)
|
/*
|
||||||
|
* Modem can crash while we are waiting for boot_done during
|
||||||
|
* a subsystem_get(). Setting mode to CRASH will prevent a
|
||||||
|
* subsequent subsystem_get() from entering poweron ops. Avoid
|
||||||
|
* this by seting mode to CRASH only if device was up and
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
if (mdm_drv->mode == CRASH || mdm_drv->mode != RUN)
|
||||||
return;
|
return;
|
||||||
mdm_drv->mode = CRASH;
|
mdm_drv->mode = CRASH;
|
||||||
queue_work(mdm_drv->mdm_queue, &mdm_drv->ssr_work);
|
queue_work(mdm_drv->mdm_queue, &mdm_drv->ssr_work);
|
||||||
|
@ -161,8 +169,9 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys)
|
||||||
subsys);
|
subsys);
|
||||||
struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink);
|
struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink);
|
||||||
const struct esoc_clink_ops const *clink_ops = esoc_clink->clink_ops;
|
const struct esoc_clink_ops const *clink_ops = esoc_clink->clink_ops;
|
||||||
|
int timeout = INT_MAX;
|
||||||
|
|
||||||
if (!esoc_req_eng_enabled(esoc_clink)) {
|
if (!esoc_clink->auto_boot && !esoc_req_eng_enabled(esoc_clink)) {
|
||||||
dev_dbg(&esoc_clink->dev, "Wait for req eng registration\n");
|
dev_dbg(&esoc_clink->dev, "Wait for req eng registration\n");
|
||||||
wait_for_completion(&mdm_drv->req_eng_wait);
|
wait_for_completion(&mdm_drv->req_eng_wait);
|
||||||
}
|
}
|
||||||
|
@ -187,8 +196,17 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wait_for_completion(&mdm_drv->boot_done);
|
|
||||||
if (mdm_drv->boot_fail) {
|
/*
|
||||||
|
* In autoboot case, it is possible that we can forever wait for
|
||||||
|
* boot completion, when esoc fails to boot. This is because there
|
||||||
|
* is no helper application which can alert esoc driver about boot
|
||||||
|
* failure. Prevent going to wait forever in such case.
|
||||||
|
*/
|
||||||
|
if (esoc_clink->auto_boot)
|
||||||
|
timeout = 10 * HZ;
|
||||||
|
ret = wait_for_completion_timeout(&mdm_drv->boot_done, timeout);
|
||||||
|
if (mdm_drv->boot_fail || ret <= 0) {
|
||||||
dev_err(&esoc_clink->dev, "booting failed\n");
|
dev_err(&esoc_clink->dev, "booting failed\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -216,10 +234,12 @@ static int mdm_subsys_ramdumps(int want_dumps,
|
||||||
|
|
||||||
static int mdm_register_ssr(struct esoc_clink *esoc_clink)
|
static int mdm_register_ssr(struct esoc_clink *esoc_clink)
|
||||||
{
|
{
|
||||||
esoc_clink->subsys.shutdown = mdm_subsys_shutdown;
|
struct subsys_desc *subsys = &esoc_clink->subsys;
|
||||||
esoc_clink->subsys.ramdump = mdm_subsys_ramdumps;
|
|
||||||
esoc_clink->subsys.powerup = mdm_subsys_powerup;
|
subsys->shutdown = mdm_subsys_shutdown;
|
||||||
esoc_clink->subsys.crash_shutdown = mdm_crash_shutdown;
|
subsys->ramdump = mdm_subsys_ramdumps;
|
||||||
|
subsys->powerup = mdm_subsys_powerup;
|
||||||
|
subsys->crash_shutdown = mdm_crash_shutdown;
|
||||||
return esoc_clink_register_ssr(esoc_clink);
|
return esoc_clink_register_ssr(esoc_clink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +306,14 @@ static struct esoc_compat compat_table[] = {
|
||||||
.name = "MDM9x55",
|
.name = "MDM9x55",
|
||||||
.data = NULL,
|
.data = NULL,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "MDM9x45",
|
||||||
|
.data = NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "APQ8096",
|
||||||
|
.data = NULL,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct esoc_drv esoc_ssr_drv = {
|
static struct esoc_drv esoc_ssr_drv = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -68,6 +68,9 @@ static int mdm4x_do_first_power_on(struct mdm_ctrl *mdm)
|
||||||
struct device *dev = mdm->dev;
|
struct device *dev = mdm->dev;
|
||||||
|
|
||||||
dev_dbg(dev, "Powering on modem for the first time\n");
|
dev_dbg(dev, "Powering on modem for the first time\n");
|
||||||
|
if (mdm->esoc->auto_boot)
|
||||||
|
return 0;
|
||||||
|
|
||||||
mdm_toggle_soft_reset(mdm, false);
|
mdm_toggle_soft_reset(mdm, false);
|
||||||
/* Add a delay to allow PON sequence to complete*/
|
/* Add a delay to allow PON sequence to complete*/
|
||||||
msleep(50);
|
msleep(50);
|
||||||
|
@ -134,6 +137,9 @@ static int mdm9x55_power_down(struct mdm_ctrl *mdm)
|
||||||
|
|
||||||
static void mdm4x_cold_reset(struct mdm_ctrl *mdm)
|
static void mdm4x_cold_reset(struct mdm_ctrl *mdm)
|
||||||
{
|
{
|
||||||
|
if (!gpio_is_valid(MDM_GPIO(mdm, AP2MDM_SOFT_RESET)))
|
||||||
|
return;
|
||||||
|
|
||||||
dev_dbg(mdm->dev, "Triggering mdm cold reset");
|
dev_dbg(mdm->dev, "Triggering mdm cold reset");
|
||||||
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
|
gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
|
||||||
!!mdm->soft_reset_inverted);
|
!!mdm->soft_reset_inverted);
|
||||||
|
@ -152,6 +158,11 @@ static void mdm9x55_cold_reset(struct mdm_ctrl *mdm)
|
||||||
!mdm->soft_reset_inverted);
|
!mdm->soft_reset_inverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int apq8096_pon_dt_init(struct mdm_ctrl *mdm)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mdm4x_pon_dt_init(struct mdm_ctrl *mdm)
|
static int mdm4x_pon_dt_init(struct mdm_ctrl *mdm)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
|
@ -183,6 +194,21 @@ static int mdm4x_pon_setup(struct mdm_ctrl *mdm)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function can be called from atomic context. */
|
||||||
|
static int apq8096_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int apq8096_power_down(struct mdm_ctrl *mdm)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void apq8096_cold_reset(struct mdm_ctrl *mdm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
struct mdm_pon_ops mdm9x25_pon_ops = {
|
struct mdm_pon_ops mdm9x25_pon_ops = {
|
||||||
.pon = mdm4x_do_first_power_on,
|
.pon = mdm4x_do_first_power_on,
|
||||||
.soft_reset = mdm4x_toggle_soft_reset,
|
.soft_reset = mdm4x_toggle_soft_reset,
|
||||||
|
@ -218,3 +244,12 @@ struct mdm_pon_ops mdm9x55_pon_ops = {
|
||||||
.dt_init = mdm4x_pon_dt_init,
|
.dt_init = mdm4x_pon_dt_init,
|
||||||
.setup = mdm4x_pon_setup,
|
.setup = mdm4x_pon_setup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mdm_pon_ops apq8096_pon_ops = {
|
||||||
|
.pon = mdm4x_do_first_power_on,
|
||||||
|
.soft_reset = apq8096_toggle_soft_reset,
|
||||||
|
.poff_force = apq8096_power_down,
|
||||||
|
.cold_reset = apq8096_cold_reset,
|
||||||
|
.dt_init = apq8096_pon_dt_init,
|
||||||
|
.setup = mdm4x_pon_setup,
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -37,6 +37,8 @@
|
||||||
#define MDM9x45_PCIE "PCIe"
|
#define MDM9x45_PCIE "PCIe"
|
||||||
#define MDM9x55_LABEL "MDM9x55"
|
#define MDM9x55_LABEL "MDM9x55"
|
||||||
#define MDM9x55_PCIE "PCIe"
|
#define MDM9x55_PCIE "PCIe"
|
||||||
|
#define APQ8096_LABEL "APQ8096"
|
||||||
|
#define APQ8096_PCIE "PCIe"
|
||||||
#define MDM2AP_STATUS_TIMEOUT_MS 120000L
|
#define MDM2AP_STATUS_TIMEOUT_MS 120000L
|
||||||
#define MDM_MODEM_TIMEOUT 3000
|
#define MDM_MODEM_TIMEOUT 3000
|
||||||
#define DEF_RAMDUMP_TIMEOUT 120000
|
#define DEF_RAMDUMP_TIMEOUT 120000
|
||||||
|
@ -153,4 +155,5 @@ extern struct mdm_pon_ops mdm9x25_pon_ops;
|
||||||
extern struct mdm_pon_ops mdm9x35_pon_ops;
|
extern struct mdm_pon_ops mdm9x35_pon_ops;
|
||||||
extern struct mdm_pon_ops mdm9x45_pon_ops;
|
extern struct mdm_pon_ops mdm9x45_pon_ops;
|
||||||
extern struct mdm_pon_ops mdm9x55_pon_ops;
|
extern struct mdm_pon_ops mdm9x55_pon_ops;
|
||||||
|
extern struct mdm_pon_ops apq8096_pon_ops;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct esoc_eng {
|
||||||
* @link_info: additional info about the physical link.
|
* @link_info: additional info about the physical link.
|
||||||
* @parent: parent device.
|
* @parent: parent device.
|
||||||
* @dev: device for userspace interface.
|
* @dev: device for userspace interface.
|
||||||
|
* @pdev: platform device to interface with SSR driver.
|
||||||
* @id: id of the external device.
|
* @id: id of the external device.
|
||||||
* @owner: owner of the device.
|
* @owner: owner of the device.
|
||||||
* @clink_ops: control operations for the control link
|
* @clink_ops: control operations for the control link
|
||||||
|
@ -59,6 +60,9 @@ struct esoc_eng {
|
||||||
* @subsys_desc: descriptor for subsystem restart
|
* @subsys_desc: descriptor for subsystem restart
|
||||||
* @subsys_dev: ssr device handle.
|
* @subsys_dev: ssr device handle.
|
||||||
* @np: device tree node for esoc_clink.
|
* @np: device tree node for esoc_clink.
|
||||||
|
* @auto_boot: boots independently.
|
||||||
|
* @primary: primary esoc controls(reset/poweroff) all secondary
|
||||||
|
* esocs, but not otherway around.
|
||||||
*/
|
*/
|
||||||
struct esoc_clink {
|
struct esoc_clink {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -66,6 +70,7 @@ struct esoc_clink {
|
||||||
const char *link_info;
|
const char *link_info;
|
||||||
struct device *parent;
|
struct device *parent;
|
||||||
struct device dev;
|
struct device dev;
|
||||||
|
struct platform_device *pdev;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
const struct esoc_clink_ops const *clink_ops;
|
const struct esoc_clink_ops const *clink_ops;
|
||||||
|
@ -77,17 +82,21 @@ struct esoc_clink {
|
||||||
struct subsys_desc subsys;
|
struct subsys_desc subsys;
|
||||||
struct subsys_device *subsys_dev;
|
struct subsys_device *subsys_dev;
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
bool auto_boot;
|
||||||
|
bool primary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct esoc_clink_ops: Operations to control external soc
|
* struct esoc_clink_ops: Operations to control external soc
|
||||||
* @cmd_exe: Execute control command
|
* @cmd_exe: Execute control command
|
||||||
* @get_status: Get current status, or response to previous command
|
* @get_status: Get current status, or response to previous command
|
||||||
|
* @get_err_fatal: Get status of err fatal signal
|
||||||
* @notify_esoc: notify external soc of events
|
* @notify_esoc: notify external soc of events
|
||||||
*/
|
*/
|
||||||
struct esoc_clink_ops {
|
struct esoc_clink_ops {
|
||||||
int (*cmd_exe)(enum esoc_cmd cmd, struct esoc_clink *dev);
|
int (*cmd_exe)(enum esoc_cmd cmd, struct esoc_clink *dev);
|
||||||
int (*get_status)(u32 *status, struct esoc_clink *dev);
|
void (*get_status)(u32 *status, struct esoc_clink *dev);
|
||||||
|
void (*get_err_fatal)(u32 *status, struct esoc_clink *dev);
|
||||||
void (*notify)(enum esoc_notify notify, struct esoc_clink *dev);
|
void (*notify)(enum esoc_notify notify, struct esoc_clink *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ int esoc_clink_register_ssr(struct esoc_clink *esoc_clink)
|
||||||
snprintf(subsys_name, len, "esoc%d", esoc_clink->id);
|
snprintf(subsys_name, len, "esoc%d", esoc_clink->id);
|
||||||
esoc_clink->subsys.name = subsys_name;
|
esoc_clink->subsys.name = subsys_name;
|
||||||
esoc_clink->dev.of_node = esoc_clink->np;
|
esoc_clink->dev.of_node = esoc_clink->np;
|
||||||
esoc_clink->subsys.dev = &esoc_clink->dev;
|
esoc_clink->subsys.dev = &esoc_clink->pdev->dev;
|
||||||
esoc_clink->subsys_dev = subsys_register(&esoc_clink->subsys);
|
esoc_clink->subsys_dev = subsys_register(&esoc_clink->subsys);
|
||||||
if (IS_ERR_OR_NULL(esoc_clink->subsys_dev)) {
|
if (IS_ERR_OR_NULL(esoc_clink->subsys_dev)) {
|
||||||
dev_err(&esoc_clink->dev, "failed to register ssr node\n");
|
dev_err(&esoc_clink->dev, "failed to register ssr node\n");
|
||||||
|
|
|
@ -224,9 +224,11 @@ static long esoc_dev_ioctl(struct file *file, unsigned int cmd,
|
||||||
clink_ops->notify(esoc_cmd, esoc_clink);
|
clink_ops->notify(esoc_cmd, esoc_clink);
|
||||||
break;
|
break;
|
||||||
case ESOC_GET_STATUS:
|
case ESOC_GET_STATUS:
|
||||||
err = clink_ops->get_status(&status, esoc_clink);
|
clink_ops->get_status(&status, esoc_clink);
|
||||||
if (err)
|
put_user(status, (unsigned int __user *)uarg);
|
||||||
return err;
|
break;
|
||||||
|
case ESOC_GET_ERR_FATAL:
|
||||||
|
clink_ops->get_err_fatal(&status, esoc_clink);
|
||||||
put_user(status, (unsigned int __user *)uarg);
|
put_user(status, (unsigned int __user *)uarg);
|
||||||
break;
|
break;
|
||||||
case ESOC_WAIT_FOR_CRASH:
|
case ESOC_WAIT_FOR_CRASH:
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define ESOC_WAIT_FOR_REQ _IOR(ESOC_CODE, 2, unsigned int)
|
#define ESOC_WAIT_FOR_REQ _IOR(ESOC_CODE, 2, unsigned int)
|
||||||
#define ESOC_NOTIFY _IOW(ESOC_CODE, 3, unsigned int)
|
#define ESOC_NOTIFY _IOW(ESOC_CODE, 3, unsigned int)
|
||||||
#define ESOC_GET_STATUS _IOR(ESOC_CODE, 4, unsigned int)
|
#define ESOC_GET_STATUS _IOR(ESOC_CODE, 4, unsigned int)
|
||||||
|
#define ESOC_GET_ERR_FATAL _IOR(ESOC_CODE, 5, unsigned int)
|
||||||
#define ESOC_WAIT_FOR_CRASH _IOR(ESOC_CODE, 6, unsigned int)
|
#define ESOC_WAIT_FOR_CRASH _IOR(ESOC_CODE, 6, unsigned int)
|
||||||
#define ESOC_REG_REQ_ENG _IO(ESOC_CODE, 7)
|
#define ESOC_REG_REQ_ENG _IO(ESOC_CODE, 7)
|
||||||
#define ESOC_REG_CMD_ENG _IO(ESOC_CODE, 8)
|
#define ESOC_REG_CMD_ENG _IO(ESOC_CODE, 8)
|
||||||
|
|
Loading…
Add table
Reference in a new issue