0001
0002
0003
0004
0005
0006
0007 #include <linux/types.h>
0008 #include <linux/atomic.h>
0009 #include <linux/bitfield.h>
0010 #include <linux/device.h>
0011 #include <linux/bug.h>
0012 #include <linux/io.h>
0013 #include <linux/firmware.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_device.h>
0017 #include <linux/of_address.h>
0018 #include <linux/pm_runtime.h>
0019 #include <linux/qcom_scm.h>
0020 #include <linux/soc/qcom/mdt_loader.h>
0021
0022 #include "ipa.h"
0023 #include "ipa_power.h"
0024 #include "ipa_data.h"
0025 #include "ipa_endpoint.h"
0026 #include "ipa_resource.h"
0027 #include "ipa_cmd.h"
0028 #include "ipa_reg.h"
0029 #include "ipa_mem.h"
0030 #include "ipa_table.h"
0031 #include "ipa_smp2p.h"
0032 #include "ipa_modem.h"
0033 #include "ipa_uc.h"
0034 #include "ipa_interrupt.h"
0035 #include "gsi_trans.h"
0036 #include "ipa_sysfs.h"
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #define IPA_FW_PATH_DEFAULT "ipa_fws.mdt"
0074 #define IPA_PAS_ID 15
0075
0076
0077 #define DPL_TIMESTAMP_SHIFT 14
0078 #define TAG_TIMESTAMP_SHIFT 14
0079 #define NAT_TIMESTAMP_SHIFT 24
0080
0081
0082 #define IPA_XO_CLOCK_DIVIDER 192
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 int ipa_setup(struct ipa *ipa)
0096 {
0097 struct ipa_endpoint *exception_endpoint;
0098 struct ipa_endpoint *command_endpoint;
0099 struct device *dev = &ipa->pdev->dev;
0100 int ret;
0101
0102 ret = gsi_setup(&ipa->gsi);
0103 if (ret)
0104 return ret;
0105
0106 ret = ipa_power_setup(ipa);
0107 if (ret)
0108 goto err_gsi_teardown;
0109
0110 ipa_endpoint_setup(ipa);
0111
0112
0113
0114
0115 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX];
0116 ret = ipa_endpoint_enable_one(command_endpoint);
0117 if (ret)
0118 goto err_endpoint_teardown;
0119
0120 ret = ipa_mem_setup(ipa);
0121 if (ret)
0122 goto err_command_disable;
0123
0124 ret = ipa_table_setup(ipa);
0125 if (ret)
0126 goto err_command_disable;
0127
0128
0129
0130
0131 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
0132 ret = ipa_endpoint_enable_one(exception_endpoint);
0133 if (ret)
0134 goto err_command_disable;
0135
0136 ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id);
0137
0138
0139 ret = ipa_qmi_setup(ipa);
0140 if (ret)
0141 goto err_default_route_clear;
0142
0143 ipa->setup_complete = true;
0144
0145 dev_info(dev, "IPA driver setup completed successfully\n");
0146
0147 return 0;
0148
0149 err_default_route_clear:
0150 ipa_endpoint_default_route_clear(ipa);
0151 ipa_endpoint_disable_one(exception_endpoint);
0152 err_command_disable:
0153 ipa_endpoint_disable_one(command_endpoint);
0154 err_endpoint_teardown:
0155 ipa_endpoint_teardown(ipa);
0156 ipa_power_teardown(ipa);
0157 err_gsi_teardown:
0158 gsi_teardown(&ipa->gsi);
0159
0160 return ret;
0161 }
0162
0163
0164
0165
0166
0167 static void ipa_teardown(struct ipa *ipa)
0168 {
0169 struct ipa_endpoint *exception_endpoint;
0170 struct ipa_endpoint *command_endpoint;
0171
0172
0173 ipa->setup_complete = false;
0174
0175 ipa_qmi_teardown(ipa);
0176 ipa_endpoint_default_route_clear(ipa);
0177 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
0178 ipa_endpoint_disable_one(exception_endpoint);
0179 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX];
0180 ipa_endpoint_disable_one(command_endpoint);
0181 ipa_endpoint_teardown(ipa);
0182 ipa_power_teardown(ipa);
0183 gsi_teardown(&ipa->gsi);
0184 }
0185
0186
0187 static void ipa_hardware_config_comp(struct ipa *ipa)
0188 {
0189 u32 val;
0190
0191
0192 if (ipa->version < IPA_VERSION_4_0)
0193 return;
0194
0195 val = ioread32(ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET);
0196
0197 if (ipa->version == IPA_VERSION_4_0) {
0198 val &= ~IPA_QMB_SELECT_CONS_EN_FMASK;
0199 val &= ~IPA_QMB_SELECT_PROD_EN_FMASK;
0200 val &= ~IPA_QMB_SELECT_GLOBAL_EN_FMASK;
0201 } else if (ipa->version < IPA_VERSION_4_5) {
0202 val |= GSI_MULTI_AXI_MASTERS_DIS_FMASK;
0203 } else {
0204
0205 }
0206
0207 val |= GSI_MULTI_INORDER_RD_DIS_FMASK;
0208 val |= GSI_MULTI_INORDER_WR_DIS_FMASK;
0209
0210 iowrite32(val, ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET);
0211 }
0212
0213
0214 static void
0215 ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data)
0216 {
0217 const struct ipa_qsb_data *data0;
0218 const struct ipa_qsb_data *data1;
0219 u32 val;
0220
0221
0222 data0 = &data->qsb_data[IPA_QSB_MASTER_DDR];
0223 if (data->qsb_count > 1)
0224 data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE];
0225
0226
0227 val = u32_encode_bits(data0->max_writes, GEN_QMB_0_MAX_WRITES_FMASK);
0228 if (data->qsb_count > 1)
0229 val |= u32_encode_bits(data1->max_writes,
0230 GEN_QMB_1_MAX_WRITES_FMASK);
0231 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_WRITES_OFFSET);
0232
0233
0234 val = u32_encode_bits(data0->max_reads, GEN_QMB_0_MAX_READS_FMASK);
0235 if (ipa->version >= IPA_VERSION_4_0)
0236 val |= u32_encode_bits(data0->max_reads_beats,
0237 GEN_QMB_0_MAX_READS_BEATS_FMASK);
0238 if (data->qsb_count > 1) {
0239 val |= u32_encode_bits(data1->max_reads,
0240 GEN_QMB_1_MAX_READS_FMASK);
0241 if (ipa->version >= IPA_VERSION_4_0)
0242 val |= u32_encode_bits(data1->max_reads_beats,
0243 GEN_QMB_1_MAX_READS_BEATS_FMASK);
0244 }
0245 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_READS_OFFSET);
0246 }
0247
0248
0249 #define TIMER_FREQUENCY 32000
0250
0251
0252
0253
0254
0255
0256
0257 static __always_inline u32 ipa_aggr_granularity_val(u32 usec)
0258 {
0259 return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1;
0260 }
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 static void ipa_qtime_config(struct ipa *ipa)
0280 {
0281 u32 val;
0282
0283
0284 iowrite32(0, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET);
0285
0286
0287 val = u32_encode_bits(DPL_TIMESTAMP_SHIFT, DPL_TIMESTAMP_LSB_FMASK);
0288 val |= u32_encode_bits(1, DPL_TIMESTAMP_SEL_FMASK);
0289
0290 val |= u32_encode_bits(TAG_TIMESTAMP_SHIFT, TAG_TIMESTAMP_LSB_FMASK);
0291 val |= u32_encode_bits(NAT_TIMESTAMP_SHIFT, NAT_TIMESTAMP_LSB_FMASK);
0292 iowrite32(val, ipa->reg_virt + IPA_REG_QTIME_TIMESTAMP_CFG_OFFSET);
0293
0294
0295 val = u32_encode_bits(IPA_GRAN_100_US, GRAN_0_FMASK);
0296 val |= u32_encode_bits(IPA_GRAN_1_MS, GRAN_1_FMASK);
0297 val |= u32_encode_bits(IPA_GRAN_1_MS, GRAN_2_FMASK);
0298 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_PULSE_GRAN_CFG_OFFSET);
0299
0300
0301 val = u32_encode_bits(IPA_XO_CLOCK_DIVIDER - 1, DIV_VALUE_FMASK);
0302 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET);
0303
0304
0305 val |= u32_encode_bits(1, DIV_ENABLE_FMASK);
0306 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET);
0307 }
0308
0309 static void ipa_idle_indication_cfg(struct ipa *ipa,
0310 u32 enter_idle_debounce_thresh,
0311 bool const_non_idle_enable)
0312 {
0313 u32 offset;
0314 u32 val;
0315
0316 val = u32_encode_bits(enter_idle_debounce_thresh,
0317 ENTER_IDLE_DEBOUNCE_THRESH_FMASK);
0318 if (const_non_idle_enable)
0319 val |= CONST_NON_IDLE_ENABLE_FMASK;
0320
0321 offset = ipa_reg_idle_indication_cfg_offset(ipa->version);
0322 iowrite32(val, ipa->reg_virt + offset);
0323 }
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 static void ipa_hardware_dcd_config(struct ipa *ipa)
0334 {
0335
0336 ipa_idle_indication_cfg(ipa, 256, false);
0337 }
0338
0339 static void ipa_hardware_dcd_deconfig(struct ipa *ipa)
0340 {
0341
0342 ipa_idle_indication_cfg(ipa, 0, true);
0343 }
0344
0345
0346
0347
0348
0349
0350 static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data)
0351 {
0352 enum ipa_version version = ipa->version;
0353 u32 granularity;
0354 u32 val;
0355
0356
0357 if (version < IPA_VERSION_4_5) {
0358 val = data->backward_compat;
0359 iowrite32(val, ipa->reg_virt + IPA_REG_BCR_OFFSET);
0360 }
0361
0362
0363 if (version >= IPA_VERSION_4_0 && version < IPA_VERSION_4_5) {
0364
0365 val = ioread32(ipa->reg_virt + IPA_REG_TX_CFG_OFFSET);
0366 val &= ~PA_MASK_EN_FMASK;
0367 iowrite32(val, ipa->reg_virt + IPA_REG_TX_CFG_OFFSET);
0368
0369
0370 val = GLOBAL_FMASK | GLOBAL_2X_CLK_FMASK;
0371 } else if (version == IPA_VERSION_3_1) {
0372 val = MISC_FMASK;
0373 } else {
0374 val = 0;
0375 }
0376 if (val)
0377 iowrite32(val, ipa->reg_virt + IPA_REG_CLKON_CFG_OFFSET);
0378
0379 ipa_hardware_config_comp(ipa);
0380
0381
0382 ipa_hardware_config_qsb(ipa, data);
0383
0384 if (version < IPA_VERSION_4_5) {
0385
0386 granularity = ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY);
0387 val = u32_encode_bits(granularity, AGGR_GRANULARITY_FMASK);
0388 iowrite32(val, ipa->reg_virt + IPA_REG_COUNTER_CFG_OFFSET);
0389 } else {
0390 ipa_qtime_config(ipa);
0391 }
0392
0393
0394 if (version == IPA_VERSION_4_2) {
0395 u32 offset = ipa_reg_filt_rout_hash_en_offset(version);
0396
0397 iowrite32(0, ipa->reg_virt + offset);
0398 }
0399
0400
0401 ipa_hardware_dcd_config(ipa);
0402 }
0403
0404
0405
0406
0407
0408
0409
0410 static void ipa_hardware_deconfig(struct ipa *ipa)
0411 {
0412
0413 ipa_hardware_dcd_deconfig(ipa);
0414 }
0415
0416
0417
0418
0419
0420
0421
0422
0423 static int ipa_config(struct ipa *ipa, const struct ipa_data *data)
0424 {
0425 int ret;
0426
0427 ipa_hardware_config(ipa, data);
0428
0429 ret = ipa_mem_config(ipa);
0430 if (ret)
0431 goto err_hardware_deconfig;
0432
0433 ipa->interrupt = ipa_interrupt_config(ipa);
0434 if (IS_ERR(ipa->interrupt)) {
0435 ret = PTR_ERR(ipa->interrupt);
0436 ipa->interrupt = NULL;
0437 goto err_mem_deconfig;
0438 }
0439
0440 ipa_uc_config(ipa);
0441
0442 ret = ipa_endpoint_config(ipa);
0443 if (ret)
0444 goto err_uc_deconfig;
0445
0446 ipa_table_config(ipa);
0447
0448
0449 ret = ipa_resource_config(ipa, data->resource_data);
0450 if (ret)
0451 goto err_endpoint_deconfig;
0452
0453 ret = ipa_modem_config(ipa);
0454 if (ret)
0455 goto err_endpoint_deconfig;
0456
0457 return 0;
0458
0459 err_endpoint_deconfig:
0460 ipa_endpoint_deconfig(ipa);
0461 err_uc_deconfig:
0462 ipa_uc_deconfig(ipa);
0463 ipa_interrupt_deconfig(ipa->interrupt);
0464 ipa->interrupt = NULL;
0465 err_mem_deconfig:
0466 ipa_mem_deconfig(ipa);
0467 err_hardware_deconfig:
0468 ipa_hardware_deconfig(ipa);
0469
0470 return ret;
0471 }
0472
0473
0474
0475
0476
0477 static void ipa_deconfig(struct ipa *ipa)
0478 {
0479 ipa_modem_deconfig(ipa);
0480 ipa_endpoint_deconfig(ipa);
0481 ipa_uc_deconfig(ipa);
0482 ipa_interrupt_deconfig(ipa->interrupt);
0483 ipa->interrupt = NULL;
0484 ipa_mem_deconfig(ipa);
0485 ipa_hardware_deconfig(ipa);
0486 }
0487
0488 static int ipa_firmware_load(struct device *dev)
0489 {
0490 const struct firmware *fw;
0491 struct device_node *node;
0492 struct resource res;
0493 phys_addr_t phys;
0494 const char *path;
0495 ssize_t size;
0496 void *virt;
0497 int ret;
0498
0499 node = of_parse_phandle(dev->of_node, "memory-region", 0);
0500 if (!node) {
0501 dev_err(dev, "DT error getting \"memory-region\" property\n");
0502 return -EINVAL;
0503 }
0504
0505 ret = of_address_to_resource(node, 0, &res);
0506 of_node_put(node);
0507 if (ret) {
0508 dev_err(dev, "error %d getting \"memory-region\" resource\n",
0509 ret);
0510 return ret;
0511 }
0512
0513
0514 ret = of_property_read_string(dev->of_node, "firmware-name", &path);
0515 if (ret) {
0516 dev_dbg(dev, "error %d getting \"firmware-name\" resource\n",
0517 ret);
0518 path = IPA_FW_PATH_DEFAULT;
0519 }
0520
0521 ret = request_firmware(&fw, path, dev);
0522 if (ret) {
0523 dev_err(dev, "error %d requesting \"%s\"\n", ret, path);
0524 return ret;
0525 }
0526
0527 phys = res.start;
0528 size = (size_t)resource_size(&res);
0529 virt = memremap(phys, size, MEMREMAP_WC);
0530 if (!virt) {
0531 dev_err(dev, "unable to remap firmware memory\n");
0532 ret = -ENOMEM;
0533 goto out_release_firmware;
0534 }
0535
0536 ret = qcom_mdt_load(dev, fw, path, IPA_PAS_ID, virt, phys, size, NULL);
0537 if (ret)
0538 dev_err(dev, "error %d loading \"%s\"\n", ret, path);
0539 else if ((ret = qcom_scm_pas_auth_and_reset(IPA_PAS_ID)))
0540 dev_err(dev, "error %d authenticating \"%s\"\n", ret, path);
0541
0542 memunmap(virt);
0543 out_release_firmware:
0544 release_firmware(fw);
0545
0546 return ret;
0547 }
0548
0549 static const struct of_device_id ipa_match[] = {
0550 {
0551 .compatible = "qcom,msm8998-ipa",
0552 .data = &ipa_data_v3_1,
0553 },
0554 {
0555 .compatible = "qcom,sdm845-ipa",
0556 .data = &ipa_data_v3_5_1,
0557 },
0558 {
0559 .compatible = "qcom,sc7180-ipa",
0560 .data = &ipa_data_v4_2,
0561 },
0562 {
0563 .compatible = "qcom,sdx55-ipa",
0564 .data = &ipa_data_v4_5,
0565 },
0566 {
0567 .compatible = "qcom,sm8350-ipa",
0568 .data = &ipa_data_v4_9,
0569 },
0570 {
0571 .compatible = "qcom,sc7280-ipa",
0572 .data = &ipa_data_v4_11,
0573 },
0574 { },
0575 };
0576 MODULE_DEVICE_TABLE(of, ipa_match);
0577
0578
0579
0580
0581
0582 static void ipa_validate_build(void)
0583 {
0584
0585
0586
0587
0588
0589
0590
0591 BUILD_BUG_ON(!IS_ENABLED(CONFIG_64BIT) && sizeof(size_t) != 4);
0592
0593
0594 BUILD_BUG_ON(GSI_EE_AP != 0);
0595
0596
0597 BUILD_BUG_ON(!GSI_CHANNEL_COUNT_MAX);
0598 BUILD_BUG_ON(!GSI_EVT_RING_COUNT_MAX);
0599
0600
0601 BUILD_BUG_ON(GSI_CHANNEL_COUNT_MAX > 32);
0602 BUILD_BUG_ON(GSI_EVT_RING_COUNT_MAX > 31);
0603
0604
0605
0606
0607
0608 BUILD_BUG_ON(GSI_TLV_MAX > U8_MAX);
0609
0610
0611 BUILD_BUG_ON(!IPA_AGGR_GRANULARITY);
0612
0613
0614 BUILD_BUG_ON(!ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY));
0615 BUILD_BUG_ON(ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY) >
0616 field_max(AGGR_GRANULARITY_FMASK));
0617 }
0618
0619 static bool ipa_version_valid(enum ipa_version version)
0620 {
0621 switch (version) {
0622 case IPA_VERSION_3_0:
0623 case IPA_VERSION_3_1:
0624 case IPA_VERSION_3_5:
0625 case IPA_VERSION_3_5_1:
0626 case IPA_VERSION_4_0:
0627 case IPA_VERSION_4_1:
0628 case IPA_VERSION_4_2:
0629 case IPA_VERSION_4_5:
0630 case IPA_VERSION_4_7:
0631 case IPA_VERSION_4_9:
0632 case IPA_VERSION_4_11:
0633 return true;
0634
0635 default:
0636 return false;
0637 }
0638 }
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663 static int ipa_probe(struct platform_device *pdev)
0664 {
0665 struct device *dev = &pdev->dev;
0666 const struct ipa_data *data;
0667 struct ipa_power *power;
0668 bool modem_init;
0669 struct ipa *ipa;
0670 int ret;
0671
0672 ipa_validate_build();
0673
0674
0675 data = of_device_get_match_data(dev);
0676 if (!data) {
0677 dev_err(dev, "matched hardware not supported\n");
0678 return -ENODEV;
0679 }
0680
0681 if (!ipa_version_valid(data->version)) {
0682 dev_err(dev, "invalid IPA version\n");
0683 return -EINVAL;
0684 }
0685
0686
0687 modem_init = of_property_read_bool(dev->of_node, "modem-init");
0688 if (!modem_init)
0689 if (!qcom_scm_is_available())
0690 return -EPROBE_DEFER;
0691
0692
0693
0694
0695 power = ipa_power_init(dev, data->power_data);
0696 if (IS_ERR(power))
0697 return PTR_ERR(power);
0698
0699
0700 ipa = kzalloc(sizeof(*ipa), GFP_KERNEL);
0701 if (!ipa) {
0702 ret = -ENOMEM;
0703 goto err_power_exit;
0704 }
0705
0706 ipa->pdev = pdev;
0707 dev_set_drvdata(dev, ipa);
0708 ipa->power = power;
0709 ipa->version = data->version;
0710 init_completion(&ipa->completion);
0711
0712 ret = ipa_reg_init(ipa);
0713 if (ret)
0714 goto err_kfree_ipa;
0715
0716 ret = ipa_mem_init(ipa, data->mem_data);
0717 if (ret)
0718 goto err_reg_exit;
0719
0720 ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count,
0721 data->endpoint_data);
0722 if (ret)
0723 goto err_mem_exit;
0724
0725
0726 ipa->filter_map = ipa_endpoint_init(ipa, data->endpoint_count,
0727 data->endpoint_data);
0728 if (!ipa->filter_map) {
0729 ret = -EINVAL;
0730 goto err_gsi_exit;
0731 }
0732
0733 ret = ipa_table_init(ipa);
0734 if (ret)
0735 goto err_endpoint_exit;
0736
0737 ret = ipa_smp2p_init(ipa, modem_init);
0738 if (ret)
0739 goto err_table_exit;
0740
0741
0742 ret = pm_runtime_get_sync(dev);
0743 if (WARN_ON(ret < 0))
0744 goto err_power_put;
0745
0746 ret = ipa_config(ipa, data);
0747 if (ret)
0748 goto err_power_put;
0749
0750 dev_info(dev, "IPA driver initialized");
0751
0752
0753
0754
0755
0756 if (modem_init)
0757 goto done;
0758
0759
0760
0761
0762 ret = ipa_firmware_load(dev);
0763 if (ret)
0764 goto err_deconfig;
0765
0766 ret = ipa_setup(ipa);
0767 if (ret)
0768 goto err_deconfig;
0769 done:
0770 pm_runtime_mark_last_busy(dev);
0771 (void)pm_runtime_put_autosuspend(dev);
0772
0773 return 0;
0774
0775 err_deconfig:
0776 ipa_deconfig(ipa);
0777 err_power_put:
0778 pm_runtime_put_noidle(dev);
0779 ipa_smp2p_exit(ipa);
0780 err_table_exit:
0781 ipa_table_exit(ipa);
0782 err_endpoint_exit:
0783 ipa_endpoint_exit(ipa);
0784 err_gsi_exit:
0785 gsi_exit(&ipa->gsi);
0786 err_mem_exit:
0787 ipa_mem_exit(ipa);
0788 err_reg_exit:
0789 ipa_reg_exit(ipa);
0790 err_kfree_ipa:
0791 kfree(ipa);
0792 err_power_exit:
0793 ipa_power_exit(power);
0794
0795 return ret;
0796 }
0797
0798 static int ipa_remove(struct platform_device *pdev)
0799 {
0800 struct ipa *ipa = dev_get_drvdata(&pdev->dev);
0801 struct ipa_power *power = ipa->power;
0802 struct device *dev = &pdev->dev;
0803 int ret;
0804
0805
0806
0807
0808 ipa_smp2p_irq_disable_setup(ipa);
0809
0810 ret = pm_runtime_get_sync(dev);
0811 if (WARN_ON(ret < 0))
0812 goto out_power_put;
0813
0814 if (ipa->setup_complete) {
0815 ret = ipa_modem_stop(ipa);
0816
0817 if (ret == -EBUSY) {
0818 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
0819 ret = ipa_modem_stop(ipa);
0820 }
0821 if (ret)
0822 return ret;
0823
0824 ipa_teardown(ipa);
0825 }
0826
0827 ipa_deconfig(ipa);
0828 out_power_put:
0829 pm_runtime_put_noidle(dev);
0830 ipa_smp2p_exit(ipa);
0831 ipa_table_exit(ipa);
0832 ipa_endpoint_exit(ipa);
0833 gsi_exit(&ipa->gsi);
0834 ipa_mem_exit(ipa);
0835 ipa_reg_exit(ipa);
0836 kfree(ipa);
0837 ipa_power_exit(power);
0838
0839 dev_info(dev, "IPA driver removed");
0840
0841 return 0;
0842 }
0843
0844 static void ipa_shutdown(struct platform_device *pdev)
0845 {
0846 int ret;
0847
0848 ret = ipa_remove(pdev);
0849 if (ret)
0850 dev_err(&pdev->dev, "shutdown: remove returned %d\n", ret);
0851 }
0852
0853 static const struct attribute_group *ipa_attribute_groups[] = {
0854 &ipa_attribute_group,
0855 &ipa_feature_attribute_group,
0856 &ipa_endpoint_id_attribute_group,
0857 &ipa_modem_attribute_group,
0858 NULL,
0859 };
0860
0861 static struct platform_driver ipa_driver = {
0862 .probe = ipa_probe,
0863 .remove = ipa_remove,
0864 .shutdown = ipa_shutdown,
0865 .driver = {
0866 .name = "ipa",
0867 .pm = &ipa_pm_ops,
0868 .of_match_table = ipa_match,
0869 .dev_groups = ipa_attribute_groups,
0870 },
0871 };
0872
0873 module_platform_driver(ipa_driver);
0874
0875 MODULE_LICENSE("GPL v2");
0876 MODULE_DESCRIPTION("Qualcomm IP Accelerator device driver");