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; 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_smsm_probe(struct platform_device *pdev) { uint32_t edge; char *key; int ret; uint32_t irq_offset; uint32_t irq_bitmask; uint32_t irq_line; struct interrupt_config_item *private_irq; struct device_node *node; void *irq_out_base; resource_size_t irq_out_size; struct platform_device *parent_pdev; struct resource *r; struct interrupt_config *private_intr_config; uint32_t remote_pid; disable_smsm_reset_handshake = 1; node = pdev->dev.of_node; if (!pdev->dev.parent) { pr_err("%s: missing link to parent device\n", __func__); return -ENODEV; } parent_pdev = to_platform_device(pdev->dev.parent); key = "irq-reg-base"; r = platform_get_resource_byname(parent_pdev, IORESOURCE_MEM, key); if (!r) goto missing_key; irq_out_size = resource_size(r); irq_out_base = ioremap_nocache(r->start, irq_out_size); if (!irq_out_base) { pr_err("%s: ioremap_nocache() of irq_out_base addr:%pr size:%pr\n", __func__, &r->start, &irq_out_size); return -ENOMEM; } SMSM_DBG("%s: %s = %p", __func__, key, irq_out_base); key = "qcom,smsm-edge"; ret = of_property_read_u32(node, key, &edge); if (ret) goto missing_key; SMSM_DBG("%s: %s = %d", __func__, key, edge); key = "qcom,smsm-irq-offset"; ret = of_property_read_u32(node, key, &irq_offset); if (ret) goto missing_key; SMSM_DBG("%s: %s = %x", __func__, key, irq_offset); key = "qcom,smsm-irq-bitmask"; ret = of_property_read_u32(node, key, &irq_bitmask); if (ret) goto missing_key; SMSM_DBG("%s: %s = %x", __func__, key, irq_bitmask); key = "interrupts"; irq_line = irq_of_parse_and_map(node, 0); if (!irq_line) goto missing_key; SMSM_DBG("%s: %s = %d", __func__, key, irq_line); private_intr_config = smd_get_intr_config(edge); if (!private_intr_config) { pr_err("%s: invalid edge\n", __func__); return -ENODEV; } private_irq = &private_intr_config->smsm; private_irq->out_bit_pos = irq_bitmask; private_irq->out_offset = irq_offset; private_irq->out_base = irq_out_base; private_irq->irq_id = irq_line; remote_pid = smd_edge_to_remote_pid(edge); interrupt_stats[remote_pid].smsm_interrupt_id = irq_line; ret = request_irq(irq_line, private_irq->irq_handler, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "smsm_dev", NULL); if (ret < 0) { pr_err("%s: request_irq() failed on %d\n", __func__, irq_line); return ret; } else { ret = enable_irq_wake(irq_line); if (ret < 0) pr_err("%s: enable_irq_wake() failed on %d\n", __func__, irq_line); } ret = smsm_post_init(); if (ret) { pr_err("smd_post_init() failed ret=%d\n", ret); return ret; } return 0; missing_key: pr_err("%s: missing key: %s", __func__, key); return -ENODEV; }