Lines Matching +full:ipa +full:- +full:ap +full:- +full:to +full:- +full:modem

1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2018-2023 Linaro Ltd.
22 #include "ipa.h"
41 * This driver supports the Qualcomm IP Accelerator (IPA), which is a
42 * networking component found in many Qualcomm SoCs. The IPA is connected
43 * to the application processor (AP), but is also connected (and partially
44 * controlled by) other "execution environments" (EEs), such as a modem.
46 * The IPA is the conduit between the AP and the modem that carries network
48 * connection of the modem to external (e.g. LTE) networks.
50 * The IPA provides protocol checksum calculation, offloading this work
51 * from the AP. The IPA offers additional functionality, including routing,
53 * currently supported. Despite that, some resources--including routing
54 * tables and filter tables--are defined in this driver because they must
57 * There are two distinct layers that implement the IPA hardware, and this
59 * interface (GSI) is an integral component of the IPA, providing a
60 * well-defined communication layer between the AP subsystem and the IPA
62 * between the AP and the IPA.
64 * The IPA layer uses GSI channels to implement its "endpoints". And while
65 * a GSI channel carries data between the AP and the IPA, a pair of IPA
66 * endpoints is used to carry traffic between two EEs. Specifically, the main
67 * modem network interface is implemented by two pairs of endpoints: a TX
68 * endpoint on the AP coupled with an RX endpoint on the modem; and another
69 * RX endpoint on the AP receiving data from a TX endpoint on the modem.
72 /* The name of the GSI firmware file relative to /lib/firmware */
76 /* Shift of 19.2 MHz timestamp to achieve lower resolution timestamps */
81 /* Divider for 19.2 MHz crystal oscillator clock to get common timer clock */
88 * @IPA_LOADER_SELF: AP loads GSI firmware
89 * @IPA_LOADER_MODEM: Modem loads GSI firmware, signals when done
90 * @IPA_LOADER_SKIP: Neither AP nor modem need to load GSI firmware
102 * ipa_setup() - Set up IPA hardware
103 * @ipa: IPA pointer
106 * the command TX endpoint. If the modem is doing GSI firmware load
108 * interrupt has been signaled by the modem. Otherwise it will be
112 int ipa_setup(struct ipa *ipa) in ipa_setup() argument
116 struct device *dev = &ipa->pdev->dev; in ipa_setup()
119 ret = gsi_setup(&ipa->gsi); in ipa_setup()
123 ret = ipa_power_setup(ipa); in ipa_setup()
127 ipa_endpoint_setup(ipa); in ipa_setup()
129 /* We need to use the AP command TX endpoint to perform other in ipa_setup()
132 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
137 ret = ipa_mem_setup(ipa); /* No matching teardown required */ in ipa_setup()
141 ret = ipa_table_setup(ipa); /* No matching teardown required */ in ipa_setup()
146 * to use it by default. in ipa_setup()
148 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_setup()
153 ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id); in ipa_setup()
155 /* We're all set. Now prepare for communication with the modem */ in ipa_setup()
156 ret = ipa_qmi_setup(ipa); in ipa_setup()
160 ipa->setup_complete = true; in ipa_setup()
162 dev_info(dev, "IPA driver setup completed successfully\n"); in ipa_setup()
167 ipa_endpoint_default_route_clear(ipa); in ipa_setup()
172 ipa_endpoint_teardown(ipa); in ipa_setup()
173 ipa_power_teardown(ipa); in ipa_setup()
175 gsi_teardown(&ipa->gsi); in ipa_setup()
181 * ipa_teardown() - Inverse of ipa_setup()
182 * @ipa: IPA pointer
184 static void ipa_teardown(struct ipa *ipa) in ipa_teardown() argument
189 /* We're going to tear everything down, as if setup never completed */ in ipa_teardown()
190 ipa->setup_complete = false; in ipa_teardown()
192 ipa_qmi_teardown(ipa); in ipa_teardown()
193 ipa_endpoint_default_route_clear(ipa); in ipa_teardown()
194 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_teardown()
196 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_teardown()
198 ipa_endpoint_teardown(ipa); in ipa_teardown()
199 ipa_power_teardown(ipa); in ipa_teardown()
200 gsi_teardown(&ipa->gsi); in ipa_teardown()
204 ipa_hardware_config_bcr(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_bcr() argument
209 /* IPA v4.5+ has no backward compatibility register */ in ipa_hardware_config_bcr()
210 if (ipa->version >= IPA_VERSION_4_5) in ipa_hardware_config_bcr()
213 reg = ipa_reg(ipa, IPA_BCR); in ipa_hardware_config_bcr()
214 val = data->backward_compat; in ipa_hardware_config_bcr()
215 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_bcr()
218 static void ipa_hardware_config_tx(struct ipa *ipa) in ipa_hardware_config_tx() argument
220 enum ipa_version version = ipa->version; in ipa_hardware_config_tx()
228 /* Disable PA mask to allow HOLB drop */ in ipa_hardware_config_tx()
229 reg = ipa_reg(ipa, IPA_TX_CFG); in ipa_hardware_config_tx()
232 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_tx()
236 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_tx()
239 static void ipa_hardware_config_clkon(struct ipa *ipa) in ipa_hardware_config_clkon() argument
241 enum ipa_version version = ipa->version; in ipa_hardware_config_clkon()
252 reg = ipa_reg(ipa, CLKON_CFG); in ipa_hardware_config_clkon()
256 } else { /* IPA v4.0+ */ in ipa_hardware_config_clkon()
262 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_clkon()
265 /* Configure bus access behavior for IPA components */
266 static void ipa_hardware_config_comp(struct ipa *ipa) in ipa_hardware_config_comp() argument
272 /* Nothing to configure prior to IPA v4.0 */ in ipa_hardware_config_comp()
273 if (ipa->version < IPA_VERSION_4_0) in ipa_hardware_config_comp()
276 reg = ipa_reg(ipa, COMP_CFG); in ipa_hardware_config_comp()
279 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_comp()
281 if (ipa->version == IPA_VERSION_4_0) { in ipa_hardware_config_comp()
285 } else if (ipa->version < IPA_VERSION_4_5) { in ipa_hardware_config_comp()
288 /* For IPA v4.5+ FULL_FLUSH_WAIT_RS_CLOSURE_EN is 0 */ in ipa_hardware_config_comp()
294 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_comp()
299 ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_qsb() argument
307 data0 = &data->qsb_data[IPA_QSB_MASTER_DDR]; in ipa_hardware_config_qsb()
308 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
309 data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE]; in ipa_hardware_config_qsb()
312 reg = ipa_reg(ipa, QSB_MAX_WRITES); in ipa_hardware_config_qsb()
314 val = reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes); in ipa_hardware_config_qsb()
315 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
316 val |= reg_encode(reg, GEN_QMB_1_MAX_WRITES, data1->max_writes); in ipa_hardware_config_qsb()
318 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
321 reg = ipa_reg(ipa, QSB_MAX_READS); in ipa_hardware_config_qsb()
323 val = reg_encode(reg, GEN_QMB_0_MAX_READS, data0->max_reads); in ipa_hardware_config_qsb()
324 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
326 data0->max_reads_beats); in ipa_hardware_config_qsb()
327 if (data->qsb_count > 1) { in ipa_hardware_config_qsb()
328 val = reg_encode(reg, GEN_QMB_1_MAX_READS, data1->max_reads); in ipa_hardware_config_qsb()
329 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
331 data1->max_reads_beats); in ipa_hardware_config_qsb()
334 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
340 /* Compute the value to use in the COUNTER_CFG register AGGR_GRANULARITY
341 * field to represent the given number of microseconds. The value is one
348 return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; in ipa_aggr_granularity_val()
351 /* IPA uses unified Qtime starting at IPA v4.5, implementing various
352 * timestamps and timers independent of the IPA core clock rate. The
353 * Qtimer is based on a 56-bit timestamp incremented at each tick of
356 * For IPA timestamps (tag, NAT, data path logging) a lower resolution
358 * some number of bits to produce the low-order bits of the coarser
362 * a divider (we use 192, to produce a 100kHz timer clock). From
363 * this common clock, three "pulse generators" are used to produce
364 * timer ticks at a configurable frequency. IPA timers (such as
365 * those used for aggregation or head-of-line block handling) now
368 static void ipa_qtime_config(struct ipa *ipa) in ipa_qtime_config() argument
375 reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG); in ipa_qtime_config()
376 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
378 reg = ipa_reg(ipa, QTIME_TIMESTAMP_CFG); in ipa_qtime_config()
379 /* Set DPL time stamp resolution to use Qtime (instead of 1 msec) */ in ipa_qtime_config()
386 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
389 reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG); in ipa_qtime_config()
392 if (ipa->version >= IPA_VERSION_5_0) { in ipa_qtime_config()
399 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
402 reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG); in ipa_qtime_config()
405 val = reg_encode(reg, DIV_VALUE, IPA_XO_CLOCK_DIVIDER - 1); in ipa_qtime_config()
407 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
409 /* Divider value is set; re-enable the common timer clock divider */ in ipa_qtime_config()
412 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
415 /* Before IPA v4.5 timing is controlled by a counter register */
416 static void ipa_hardware_config_counter(struct ipa *ipa) in ipa_hardware_config_counter() argument
422 reg = ipa_reg(ipa, COUNTER_CFG); in ipa_hardware_config_counter()
425 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_counter()
428 static void ipa_hardware_config_timing(struct ipa *ipa) in ipa_hardware_config_timing() argument
430 if (ipa->version < IPA_VERSION_4_5) in ipa_hardware_config_timing()
431 ipa_hardware_config_counter(ipa); in ipa_hardware_config_timing()
433 ipa_qtime_config(ipa); in ipa_hardware_config_timing()
436 static void ipa_hardware_config_hashing(struct ipa *ipa) in ipa_hardware_config_hashing() argument
440 /* Other than IPA v4.2, all versions enable "hashing". Starting in ipa_hardware_config_hashing()
441 * with IPA v5.0, the filter and router tables are implemented in ipa_hardware_config_hashing()
443 * (now referred to as "cacheing"), so there's nothing to do here. in ipa_hardware_config_hashing()
445 if (ipa->version != IPA_VERSION_4_2) in ipa_hardware_config_hashing()
448 /* IPA v4.2 does not support hashed tables, so disable them */ in ipa_hardware_config_hashing()
449 reg = ipa_reg(ipa, FILT_ROUT_HASH_EN); in ipa_hardware_config_hashing()
454 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_hashing()
457 static void ipa_idle_indication_cfg(struct ipa *ipa, in ipa_idle_indication_cfg() argument
464 if (ipa->version < IPA_VERSION_3_5_1) in ipa_idle_indication_cfg()
467 reg = ipa_reg(ipa, IDLE_INDICATION_CFG); in ipa_idle_indication_cfg()
473 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_idle_indication_cfg()
477 * ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
478 * @ipa: IPA pointer
480 * Configures when the IPA signals it is idle to the global clock
481 * controller, which can respond by scaling down the clock to save
484 static void ipa_hardware_dcd_config(struct ipa *ipa) in ipa_hardware_dcd_config() argument
486 /* Recommended values for IPA 3.5 and later according to IPA HPG */ in ipa_hardware_dcd_config()
487 ipa_idle_indication_cfg(ipa, 256, false); in ipa_hardware_dcd_config()
490 static void ipa_hardware_dcd_deconfig(struct ipa *ipa) in ipa_hardware_dcd_deconfig() argument
492 /* Power-on reset values */ in ipa_hardware_dcd_deconfig()
493 ipa_idle_indication_cfg(ipa, 0, true); in ipa_hardware_dcd_deconfig()
497 * ipa_hardware_config() - Primitive hardware initialization
498 * @ipa: IPA pointer
499 * @data: IPA configuration data
501 static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config() argument
503 ipa_hardware_config_bcr(ipa, data); in ipa_hardware_config()
504 ipa_hardware_config_tx(ipa); in ipa_hardware_config()
505 ipa_hardware_config_clkon(ipa); in ipa_hardware_config()
506 ipa_hardware_config_comp(ipa); in ipa_hardware_config()
507 ipa_hardware_config_qsb(ipa, data); in ipa_hardware_config()
508 ipa_hardware_config_timing(ipa); in ipa_hardware_config()
509 ipa_hardware_config_hashing(ipa); in ipa_hardware_config()
510 ipa_hardware_dcd_config(ipa); in ipa_hardware_config()
514 * ipa_hardware_deconfig() - Inverse of ipa_hardware_config()
515 * @ipa: IPA pointer
517 * This restores the power-on reset values (even if they aren't different)
519 static void ipa_hardware_deconfig(struct ipa *ipa) in ipa_hardware_deconfig() argument
522 ipa_hardware_dcd_deconfig(ipa); in ipa_hardware_deconfig()
526 * ipa_config() - Configure IPA hardware
527 * @ipa: IPA pointer
528 * @data: IPA configuration data
530 * Perform initialization requiring IPA power to be enabled.
532 static int ipa_config(struct ipa *ipa, const struct ipa_data *data) in ipa_config() argument
536 ipa_hardware_config(ipa, data); in ipa_config()
538 ret = ipa_mem_config(ipa); in ipa_config()
542 ipa->interrupt = ipa_interrupt_config(ipa); in ipa_config()
543 if (IS_ERR(ipa->interrupt)) { in ipa_config()
544 ret = PTR_ERR(ipa->interrupt); in ipa_config()
545 ipa->interrupt = NULL; in ipa_config()
549 ipa_uc_config(ipa); in ipa_config()
551 ret = ipa_endpoint_config(ipa); in ipa_config()
555 ipa_table_config(ipa); /* No deconfig required */ in ipa_config()
557 /* Assign resource limitation to each group; no deconfig required */ in ipa_config()
558 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
562 ret = ipa_modem_config(ipa); in ipa_config()
569 ipa_endpoint_deconfig(ipa); in ipa_config()
571 ipa_uc_deconfig(ipa); in ipa_config()
572 ipa_interrupt_deconfig(ipa->interrupt); in ipa_config()
573 ipa->interrupt = NULL; in ipa_config()
575 ipa_mem_deconfig(ipa); in ipa_config()
577 ipa_hardware_deconfig(ipa); in ipa_config()
583 * ipa_deconfig() - Inverse of ipa_config()
584 * @ipa: IPA pointer
586 static void ipa_deconfig(struct ipa *ipa) in ipa_deconfig() argument
588 ipa_modem_deconfig(ipa); in ipa_deconfig()
589 ipa_endpoint_deconfig(ipa); in ipa_deconfig()
590 ipa_uc_deconfig(ipa); in ipa_deconfig()
591 ipa_interrupt_deconfig(ipa->interrupt); in ipa_deconfig()
592 ipa->interrupt = NULL; in ipa_deconfig()
593 ipa_mem_deconfig(ipa); in ipa_deconfig()
594 ipa_hardware_deconfig(ipa); in ipa_deconfig()
608 node = of_parse_phandle(dev->of_node, "memory-region", 0); in ipa_firmware_load()
610 dev_err(dev, "DT error getting \"memory-region\" property\n"); in ipa_firmware_load()
611 return -EINVAL; in ipa_firmware_load()
617 dev_err(dev, "error %d getting \"memory-region\" resource\n", in ipa_firmware_load()
623 ret = of_property_read_string(dev->of_node, "firmware-name", &path); in ipa_firmware_load()
625 dev_dbg(dev, "error %d getting \"firmware-name\" resource\n", in ipa_firmware_load()
640 dev_err(dev, "unable to remap firmware memory\n"); in ipa_firmware_load()
641 ret = -ENOMEM; in ipa_firmware_load()
660 .compatible = "qcom,msm8998-ipa",
664 .compatible = "qcom,sdm845-ipa",
668 .compatible = "qcom,sc7180-ipa",
672 .compatible = "qcom,sdx55-ipa",
676 .compatible = "qcom,sm6350-ipa",
680 .compatible = "qcom,sm8350-ipa",
684 .compatible = "qcom,sc7280-ipa",
688 .compatible = "qcom,sdx65-ipa",
701 /* At one time we assumed a 64-bit build, allowing some do_div() in ipa_validate_build()
702 * calls to be replaced by simple division or modulo operations. in ipa_validate_build()
705 * of being a 64-bit value. (It should be guaranteed 32 bits wide in ipa_validate_build()
706 * on a 32-bit build, but there is no harm in verifying that.) in ipa_validate_build()
710 /* Code assumes the EE ID for the AP is 0 (zeroed structure field) */ in ipa_validate_build()
722 * TLV FIFO size. A transaction structure uses 8-bit fields in ipa_validate_build()
723 * to represents the number of TREs it has allocated and used. in ipa_validate_build()
741 modem_init = of_property_read_bool(dev->of_node, "modem-init"); in ipa_firmware_loader()
742 ret = of_property_read_string(dev->of_node, "qcom,gsi-loader", &str); in ipa_firmware_loader()
745 if (ret == -EINVAL) { in ipa_firmware_loader()
759 /* Modem loads GSI firmware for "modem" */ in ipa_firmware_loader()
760 if (!strcmp(str, "modem")) in ipa_firmware_loader()
771 /* We need Trust Zone to load firmware; make sure it's available */ in ipa_firmware_loader()
779 * ipa_probe() - IPA platform driver probe function
785 * This is the main entry point for the IPA driver. Initialization proceeds
787 * - The "init" stage involves activities that can be initialized without
788 * access to the IPA hardware.
789 * - The "config" stage requires IPA power to be active so IPA registers
790 * can be accessed, but does not require the use of IPA immediate commands.
791 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
792 * layer to be initialized.
794 * A Boolean Device Tree "modem-init" property determines whether GSI
795 * initialization will be performed by the AP (Trust Zone) or the modem.
796 * If the AP does GSI initialization, the setup phase is entered after
797 * this has completed successfully. Otherwise the modem initializes
799 * to the AP; this triggers the start if IPA setup.
803 struct device *dev = &pdev->dev; in ipa_probe()
807 struct ipa *ipa; in ipa_probe() local
816 return -ENODEV; in ipa_probe()
819 if (!ipa_version_supported(data->version)) { in ipa_probe()
820 dev_err(dev, "unsupported IPA version %u\n", data->version); in ipa_probe()
821 return -EINVAL; in ipa_probe()
824 if (!data->modem_route_count) { in ipa_probe()
826 return -EINVAL; in ipa_probe()
831 return -EINVAL; in ipa_probe()
833 return -EPROBE_DEFER; in ipa_probe()
836 * probed, so might return -EPROBE_DEFER. in ipa_probe()
838 power = ipa_power_init(dev, data->power_data); in ipa_probe()
842 /* No more EPROBE_DEFER. Allocate and initialize the IPA structure */ in ipa_probe()
843 ipa = kzalloc(sizeof(*ipa), GFP_KERNEL); in ipa_probe()
844 if (!ipa) { in ipa_probe()
845 ret = -ENOMEM; in ipa_probe()
849 ipa->pdev = pdev; in ipa_probe()
850 dev_set_drvdata(dev, ipa); in ipa_probe()
851 ipa->power = power; in ipa_probe()
852 ipa->version = data->version; in ipa_probe()
853 ipa->modem_route_count = data->modem_route_count; in ipa_probe()
854 init_completion(&ipa->completion); in ipa_probe()
856 ret = ipa_reg_init(ipa); in ipa_probe()
860 ret = ipa_mem_init(ipa, data->mem_data); in ipa_probe()
864 ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count, in ipa_probe()
865 data->endpoint_data); in ipa_probe()
869 /* Result is a non-zero mask of endpoints that support filtering */ in ipa_probe()
870 ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data); in ipa_probe()
874 ret = ipa_table_init(ipa); in ipa_probe()
878 ret = ipa_smp2p_init(ipa, loader == IPA_LOADER_MODEM); in ipa_probe()
882 /* Power needs to be active for config and setup */ in ipa_probe()
887 ret = ipa_config(ipa, data); in ipa_probe()
891 dev_info(dev, "IPA driver initialized"); in ipa_probe()
893 /* If the modem is loading GSI firmware, it will trigger a call to in ipa_probe()
900 /* The AP is loading GSI firmware; do so now */ in ipa_probe()
906 /* GSI firmware is loaded; proceed to setup */ in ipa_probe()
907 ret = ipa_setup(ipa); in ipa_probe()
917 ipa_deconfig(ipa); in ipa_probe()
920 ipa_smp2p_exit(ipa); in ipa_probe()
922 ipa_table_exit(ipa); in ipa_probe()
924 ipa_endpoint_exit(ipa); in ipa_probe()
926 gsi_exit(&ipa->gsi); in ipa_probe()
928 ipa_mem_exit(ipa); in ipa_probe()
930 ipa_reg_exit(ipa); in ipa_probe()
932 kfree(ipa); in ipa_probe()
941 struct ipa *ipa = dev_get_drvdata(&pdev->dev); in ipa_remove() local
942 struct ipa_power *power = ipa->power; in ipa_remove()
943 struct device *dev = &pdev->dev; in ipa_remove()
946 /* Prevent the modem from triggering a call to ipa_setup(). This in ipa_remove()
947 * also ensures a modem-initiated setup that's underway completes. in ipa_remove()
949 ipa_smp2p_irq_disable_setup(ipa); in ipa_remove()
955 if (ipa->setup_complete) { in ipa_remove()
956 ret = ipa_modem_stop(ipa); in ipa_remove()
958 if (ret == -EBUSY) { in ipa_remove()
960 ret = ipa_modem_stop(ipa); in ipa_remove()
965 ipa_teardown(ipa); in ipa_remove()
968 ipa_deconfig(ipa); in ipa_remove()
971 ipa_smp2p_exit(ipa); in ipa_remove()
972 ipa_table_exit(ipa); in ipa_remove()
973 ipa_endpoint_exit(ipa); in ipa_remove()
974 gsi_exit(&ipa->gsi); in ipa_remove()
975 ipa_mem_exit(ipa); in ipa_remove()
976 ipa_reg_exit(ipa); in ipa_remove()
977 kfree(ipa); in ipa_remove()
980 dev_info(dev, "IPA driver removed"); in ipa_remove()
991 dev_err(&pdev->dev, "shutdown: remove returned %d\n", ret); in ipa_shutdown()
1007 .name = "ipa",