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-2024 Linaro Ltd.
20 #include "ipa.h"
39 * This driver supports the Qualcomm IP Accelerator (IPA), which is a
40 * networking component found in many Qualcomm SoCs. The IPA is connected
41 * to the application processor (AP), but is also connected (and partially
42 * controlled by) other "execution environments" (EEs), such as a modem.
44 * The IPA is the conduit between the AP and the modem that carries network
46 * connection of the modem to external (e.g. LTE) networks.
48 * The IPA provides protocol checksum calculation, offloading this work
49 * from the AP. The IPA offers additional functionality, including routing,
51 * currently supported. Despite that, some resources--including routing
52 * tables and filter tables--are defined in this driver because they must
55 * There are two distinct layers that implement the IPA hardware, and this
57 * interface (GSI) is an integral component of the IPA, providing a
58 * well-defined communication layer between the AP subsystem and the IPA
60 * between the AP and the IPA.
62 * The IPA layer uses GSI channels to implement its "endpoints". And while
63 * a GSI channel carries data between the AP and the IPA, a pair of IPA
64 * endpoints is used to carry traffic between two EEs. Specifically, the main
65 * modem network interface is implemented by two pairs of endpoints: a TX
66 * endpoint on the AP coupled with an RX endpoint on the modem; and another
67 * RX endpoint on the AP receiving data from a TX endpoint on the modem.
70 /* The name of the GSI firmware file relative to /lib/firmware */
74 /* Shift of 19.2 MHz timestamp to achieve lower resolution timestamps */
75 /* IPA v5.5+ does not specify Qtime timestamp config for DPL */
80 /* Divider for 19.2 MHz crystal oscillator clock to get common timer clock */
87 * @IPA_LOADER_SELF: AP loads GSI firmware
88 * @IPA_LOADER_MODEM: Modem loads GSI firmware, signals when done
89 * @IPA_LOADER_SKIP: Neither AP nor modem need to load GSI firmware
101 * ipa_setup() - Set up IPA hardware
102 * @ipa: IPA pointer
105 * the command TX endpoint. If the modem is doing GSI firmware load
107 * interrupt has been signaled by the modem. Otherwise it will be
111 int ipa_setup(struct ipa *ipa) in ipa_setup() argument
115 struct device *dev = ipa->dev; in ipa_setup()
118 ret = gsi_setup(&ipa->gsi); in ipa_setup()
122 ipa_endpoint_setup(ipa); in ipa_setup()
124 /* We need to use the AP command TX endpoint to perform other in ipa_setup()
127 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
132 ret = ipa_mem_setup(ipa); /* No matching teardown required */ in ipa_setup()
136 ret = ipa_table_setup(ipa); /* No matching teardown required */ in ipa_setup()
141 * to use it by default. in ipa_setup()
143 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_setup()
148 ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id); in ipa_setup()
150 /* We're all set. Now prepare for communication with the modem */ in ipa_setup()
151 ret = ipa_qmi_setup(ipa); in ipa_setup()
155 ipa->setup_complete = true; in ipa_setup()
157 dev_info(dev, "IPA driver setup completed successfully\n"); in ipa_setup()
162 ipa_endpoint_default_route_clear(ipa); in ipa_setup()
167 ipa_endpoint_teardown(ipa); in ipa_setup()
168 gsi_teardown(&ipa->gsi); in ipa_setup()
174 * ipa_teardown() - Inverse of ipa_setup()
175 * @ipa: IPA pointer
177 static void ipa_teardown(struct ipa *ipa) in ipa_teardown() argument
182 /* We're going to tear everything down, as if setup never completed */ in ipa_teardown()
183 ipa->setup_complete = false; in ipa_teardown()
185 ipa_qmi_teardown(ipa); in ipa_teardown()
186 ipa_endpoint_default_route_clear(ipa); in ipa_teardown()
187 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_teardown()
189 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_teardown()
191 ipa_endpoint_teardown(ipa); in ipa_teardown()
192 gsi_teardown(&ipa->gsi); in ipa_teardown()
196 ipa_hardware_config_bcr(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_bcr() argument
201 /* IPA v4.5+ has no backward compatibility register */ in ipa_hardware_config_bcr()
202 if (ipa->version >= IPA_VERSION_4_5) in ipa_hardware_config_bcr()
205 reg = ipa_reg(ipa, IPA_BCR); in ipa_hardware_config_bcr()
206 val = data->backward_compat; in ipa_hardware_config_bcr()
207 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_bcr()
210 static void ipa_hardware_config_tx(struct ipa *ipa) in ipa_hardware_config_tx() argument
212 enum ipa_version version = ipa->version; in ipa_hardware_config_tx()
220 /* Disable PA mask to allow HOLB drop */ in ipa_hardware_config_tx()
221 reg = ipa_reg(ipa, IPA_TX_CFG); in ipa_hardware_config_tx()
224 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_tx()
228 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_tx()
231 static void ipa_hardware_config_clkon(struct ipa *ipa) in ipa_hardware_config_clkon() argument
233 enum ipa_version version = ipa->version; in ipa_hardware_config_clkon()
244 reg = ipa_reg(ipa, CLKON_CFG); in ipa_hardware_config_clkon()
248 } else { /* IPA v4.0+ */ in ipa_hardware_config_clkon()
254 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_clkon()
257 /* Configure bus access behavior for IPA components */
258 static void ipa_hardware_config_comp(struct ipa *ipa) in ipa_hardware_config_comp() argument
264 /* Nothing to configure prior to IPA v4.0 */ in ipa_hardware_config_comp()
265 if (ipa->version < IPA_VERSION_4_0) in ipa_hardware_config_comp()
268 reg = ipa_reg(ipa, COMP_CFG); in ipa_hardware_config_comp()
271 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_comp()
273 if (ipa->version == IPA_VERSION_4_0) { in ipa_hardware_config_comp()
277 } else if (ipa->version < IPA_VERSION_4_5) { in ipa_hardware_config_comp()
280 /* For IPA v4.5+ FULL_FLUSH_WAIT_RS_CLOSURE_EN is 0 */ in ipa_hardware_config_comp()
286 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_comp()
291 ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_qsb() argument
299 data0 = &data->qsb_data[IPA_QSB_MASTER_DDR]; in ipa_hardware_config_qsb()
300 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
301 data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE]; in ipa_hardware_config_qsb()
304 reg = ipa_reg(ipa, QSB_MAX_WRITES); in ipa_hardware_config_qsb()
306 val = reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes); in ipa_hardware_config_qsb()
307 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
308 val |= reg_encode(reg, GEN_QMB_1_MAX_WRITES, data1->max_writes); in ipa_hardware_config_qsb()
310 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
313 reg = ipa_reg(ipa, QSB_MAX_READS); in ipa_hardware_config_qsb()
315 val = reg_encode(reg, GEN_QMB_0_MAX_READS, data0->max_reads); in ipa_hardware_config_qsb()
316 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
318 data0->max_reads_beats); in ipa_hardware_config_qsb()
319 if (data->qsb_count > 1) { in ipa_hardware_config_qsb()
320 val = reg_encode(reg, GEN_QMB_1_MAX_READS, data1->max_reads); in ipa_hardware_config_qsb()
321 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
323 data1->max_reads_beats); in ipa_hardware_config_qsb()
326 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
332 /* Compute the value to use in the COUNTER_CFG register AGGR_GRANULARITY
333 * field to represent the given number of microseconds. The value is one
340 return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; in ipa_aggr_granularity_val()
343 /* IPA uses unified Qtime starting at IPA v4.5, implementing various
344 * timestamps and timers independent of the IPA core clock rate. The
345 * Qtimer is based on a 56-bit timestamp incremented at each tick of
348 * For IPA timestamps (tag, NAT, data path logging) a lower resolution
350 * some number of bits to produce the low-order bits of the coarser
354 * a divider (we use 192, to produce a 100kHz timer clock). From
355 * this common clock, three "pulse generators" are used to produce
356 * timer ticks at a configurable frequency. IPA timers (such as
357 * those used for aggregation or head-of-line block handling) now
360 static void ipa_qtime_config(struct ipa *ipa) in ipa_qtime_config() argument
367 reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG); in ipa_qtime_config()
368 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
370 reg = ipa_reg(ipa, QTIME_TIMESTAMP_CFG); in ipa_qtime_config()
371 if (ipa->version < IPA_VERSION_5_5) { in ipa_qtime_config()
372 /* Set DPL time stamp resolution to use Qtime (not 1 msec) */ in ipa_qtime_config()
380 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
383 reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG); in ipa_qtime_config()
386 if (ipa->version >= IPA_VERSION_5_0) { in ipa_qtime_config()
393 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
396 reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG); in ipa_qtime_config()
399 val = reg_encode(reg, DIV_VALUE, IPA_XO_CLOCK_DIVIDER - 1); in ipa_qtime_config()
401 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
403 /* Divider value is set; re-enable the common timer clock divider */ in ipa_qtime_config()
406 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
409 /* Before IPA v4.5 timing is controlled by a counter register */
410 static void ipa_hardware_config_counter(struct ipa *ipa) in ipa_hardware_config_counter() argument
416 reg = ipa_reg(ipa, COUNTER_CFG); in ipa_hardware_config_counter()
419 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_counter()
422 static void ipa_hardware_config_timing(struct ipa *ipa) in ipa_hardware_config_timing() argument
424 if (ipa->version < IPA_VERSION_4_5) in ipa_hardware_config_timing()
425 ipa_hardware_config_counter(ipa); in ipa_hardware_config_timing()
427 ipa_qtime_config(ipa); in ipa_hardware_config_timing()
430 static void ipa_hardware_config_hashing(struct ipa *ipa) in ipa_hardware_config_hashing() argument
434 /* Other than IPA v4.2, all versions enable "hashing". Starting in ipa_hardware_config_hashing()
435 * with IPA v5.0, the filter and router tables are implemented in ipa_hardware_config_hashing()
437 * (now referred to as "cacheing"), so there's nothing to do here. in ipa_hardware_config_hashing()
439 if (ipa->version != IPA_VERSION_4_2) in ipa_hardware_config_hashing()
442 /* IPA v4.2 does not support hashed tables, so disable them */ in ipa_hardware_config_hashing()
443 reg = ipa_reg(ipa, FILT_ROUT_HASH_EN); in ipa_hardware_config_hashing()
448 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_hashing()
451 static void ipa_idle_indication_cfg(struct ipa *ipa, in ipa_idle_indication_cfg() argument
458 if (ipa->version < IPA_VERSION_3_5_1) in ipa_idle_indication_cfg()
461 reg = ipa_reg(ipa, IDLE_INDICATION_CFG); in ipa_idle_indication_cfg()
467 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_idle_indication_cfg()
471 * ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
472 * @ipa: IPA pointer
474 * Configures when the IPA signals it is idle to the global clock
475 * controller, which can respond by scaling down the clock to save
478 static void ipa_hardware_dcd_config(struct ipa *ipa) in ipa_hardware_dcd_config() argument
480 /* Recommended values for IPA 3.5 and later according to IPA HPG */ in ipa_hardware_dcd_config()
481 ipa_idle_indication_cfg(ipa, 256, false); in ipa_hardware_dcd_config()
484 static void ipa_hardware_dcd_deconfig(struct ipa *ipa) in ipa_hardware_dcd_deconfig() argument
486 /* Power-on reset values */ in ipa_hardware_dcd_deconfig()
487 ipa_idle_indication_cfg(ipa, 0, true); in ipa_hardware_dcd_deconfig()
491 * ipa_hardware_config() - Primitive hardware initialization
492 * @ipa: IPA pointer
493 * @data: IPA configuration data
495 static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config() argument
497 ipa_hardware_config_bcr(ipa, data); in ipa_hardware_config()
498 ipa_hardware_config_tx(ipa); in ipa_hardware_config()
499 ipa_hardware_config_clkon(ipa); in ipa_hardware_config()
500 ipa_hardware_config_comp(ipa); in ipa_hardware_config()
501 ipa_hardware_config_qsb(ipa, data); in ipa_hardware_config()
502 ipa_hardware_config_timing(ipa); in ipa_hardware_config()
503 ipa_hardware_config_hashing(ipa); in ipa_hardware_config()
504 ipa_hardware_dcd_config(ipa); in ipa_hardware_config()
508 * ipa_hardware_deconfig() - Inverse of ipa_hardware_config()
509 * @ipa: IPA pointer
511 * This restores the power-on reset values (even if they aren't different)
513 static void ipa_hardware_deconfig(struct ipa *ipa) in ipa_hardware_deconfig() argument
516 ipa_hardware_dcd_deconfig(ipa); in ipa_hardware_deconfig()
520 * ipa_config() - Configure IPA hardware
521 * @ipa: IPA pointer
522 * @data: IPA configuration data
524 * Perform initialization requiring IPA power to be enabled.
526 static int ipa_config(struct ipa *ipa, const struct ipa_data *data) in ipa_config() argument
530 ipa_hardware_config(ipa, data); in ipa_config()
532 ret = ipa_mem_config(ipa); in ipa_config()
536 ret = ipa_interrupt_config(ipa); in ipa_config()
540 ipa_uc_config(ipa); in ipa_config()
542 ret = ipa_endpoint_config(ipa); in ipa_config()
546 ipa_table_config(ipa); /* No deconfig required */ in ipa_config()
548 /* Assign resource limitation to each group; no deconfig required */ in ipa_config()
549 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
553 ret = ipa_modem_config(ipa); in ipa_config()
560 ipa_endpoint_deconfig(ipa); in ipa_config()
562 ipa_uc_deconfig(ipa); in ipa_config()
563 ipa_interrupt_deconfig(ipa); in ipa_config()
565 ipa_mem_deconfig(ipa); in ipa_config()
567 ipa_hardware_deconfig(ipa); in ipa_config()
573 * ipa_deconfig() - Inverse of ipa_config()
574 * @ipa: IPA pointer
576 static void ipa_deconfig(struct ipa *ipa) in ipa_deconfig() argument
578 ipa_modem_deconfig(ipa); in ipa_deconfig()
579 ipa_endpoint_deconfig(ipa); in ipa_deconfig()
580 ipa_uc_deconfig(ipa); in ipa_deconfig()
581 ipa_interrupt_deconfig(ipa); in ipa_deconfig()
582 ipa_mem_deconfig(ipa); in ipa_deconfig()
583 ipa_hardware_deconfig(ipa); in ipa_deconfig()
597 node = of_parse_phandle(dev->of_node, "memory-region", 0); in ipa_firmware_load()
599 dev_err(dev, "DT error getting \"memory-region\" property\n"); in ipa_firmware_load()
600 return -EINVAL; in ipa_firmware_load()
606 dev_err(dev, "error %d getting \"memory-region\" resource\n", in ipa_firmware_load()
612 ret = of_property_read_string(dev->of_node, "firmware-name", &path); in ipa_firmware_load()
614 dev_dbg(dev, "error %d getting \"firmware-name\" resource\n", in ipa_firmware_load()
629 dev_err(dev, "unable to remap firmware memory\n"); in ipa_firmware_load()
630 ret = -ENOMEM; in ipa_firmware_load()
649 .compatible = "qcom,msm8998-ipa",
653 .compatible = "qcom,sdm845-ipa",
657 .compatible = "qcom,sc7180-ipa",
661 .compatible = "qcom,sdx55-ipa",
665 .compatible = "qcom,sm6350-ipa",
669 .compatible = "qcom,sm8350-ipa",
673 .compatible = "qcom,sc7280-ipa",
677 .compatible = "qcom,sdx65-ipa",
681 .compatible = "qcom,sm8550-ipa",
694 /* At one time we assumed a 64-bit build, allowing some do_div() in ipa_validate_build()
695 * calls to be replaced by simple division or modulo operations. in ipa_validate_build()
698 * of being a 64-bit value. (It should be guaranteed 32 bits wide in ipa_validate_build()
699 * on a 32-bit build, but there is no harm in verifying that.) in ipa_validate_build()
703 /* Code assumes the EE ID for the AP is 0 (zeroed structure field) */ in ipa_validate_build()
715 * TLV FIFO size. A transaction structure uses 8-bit fields in ipa_validate_build()
716 * to represents the number of TREs it has allocated and used. in ipa_validate_build()
734 modem_init = of_property_read_bool(dev->of_node, "modem-init"); in ipa_firmware_loader()
735 ret = of_property_read_string(dev->of_node, "qcom,gsi-loader", &str); in ipa_firmware_loader()
738 if (ret == -EINVAL) { in ipa_firmware_loader()
752 /* Modem loads GSI firmware for "modem" */ in ipa_firmware_loader()
753 if (!strcmp(str, "modem")) in ipa_firmware_loader()
764 /* We need Trust Zone to load firmware; make sure it's available */ in ipa_firmware_loader()
772 * ipa_probe() - IPA platform driver probe function
778 * This is the main entry point for the IPA driver. Initialization proceeds
780 * - The "init" stage involves activities that can be initialized without
781 * access to the IPA hardware.
782 * - The "config" stage requires IPA power to be active so IPA registers
783 * can be accessed, but does not require the use of IPA immediate commands.
784 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
785 * layer to be initialized.
787 * A Boolean Device Tree "modem-init" property determines whether GSI
788 * initialization will be performed by the AP (Trust Zone) or the modem.
789 * If the AP does GSI initialization, the setup phase is entered after
790 * this has completed successfully. Otherwise the modem initializes
792 * to the AP; this triggers the start if IPA setup.
796 struct device *dev = &pdev->dev; in ipa_probe()
801 struct ipa *ipa; in ipa_probe() local
810 return -ENODEV; in ipa_probe()
813 if (!data->modem_route_count) { in ipa_probe()
815 return -EINVAL; in ipa_probe()
820 return -EINVAL; in ipa_probe()
822 return -EPROBE_DEFER; in ipa_probe()
824 /* The IPA interrupt might not be ready when we're probed, so this in ipa_probe()
825 * might return -EPROBE_DEFER. in ipa_probe()
832 * so this might return -EPROBE_DEFER. in ipa_probe()
834 power = ipa_power_init(dev, data->power_data); in ipa_probe()
840 /* No more EPROBE_DEFER. Allocate and initialize the IPA structure */ in ipa_probe()
841 ipa = kzalloc(sizeof(*ipa), GFP_KERNEL); in ipa_probe()
842 if (!ipa) { in ipa_probe()
843 ret = -ENOMEM; in ipa_probe()
847 ipa->dev = dev; in ipa_probe()
848 dev_set_drvdata(dev, ipa); in ipa_probe()
849 ipa->interrupt = interrupt; in ipa_probe()
850 ipa->power = power; in ipa_probe()
851 ipa->version = data->version; in ipa_probe()
852 ipa->modem_route_count = data->modem_route_count; in ipa_probe()
853 init_completion(&ipa->completion); in ipa_probe()
855 ret = ipa_reg_init(ipa, pdev); in ipa_probe()
859 ret = ipa_mem_init(ipa, pdev, data->mem_data); in ipa_probe()
863 ret = ipa_cmd_init(ipa); in ipa_probe()
867 ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count, in ipa_probe()
868 data->endpoint_data); in ipa_probe()
872 /* Result is a non-zero mask of endpoints that support filtering */ in ipa_probe()
873 ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data); in ipa_probe()
877 ret = ipa_table_init(ipa); in ipa_probe()
881 ret = ipa_smp2p_init(ipa, pdev, loader == IPA_LOADER_MODEM); in ipa_probe()
885 /* Power needs to be active for config and setup */ in ipa_probe()
890 ret = ipa_config(ipa, data); in ipa_probe()
894 dev_info(dev, "IPA driver initialized"); in ipa_probe()
896 /* If the modem is loading GSI firmware, it will trigger a call to in ipa_probe()
903 /* The AP is loading GSI firmware; do so now */ in ipa_probe()
909 /* GSI firmware is loaded; proceed to setup */ in ipa_probe()
910 ret = ipa_setup(ipa); in ipa_probe()
920 ipa_deconfig(ipa); in ipa_probe()
923 ipa_smp2p_exit(ipa); in ipa_probe()
925 ipa_table_exit(ipa); in ipa_probe()
927 ipa_endpoint_exit(ipa); in ipa_probe()
929 gsi_exit(&ipa->gsi); in ipa_probe()
931 ipa_mem_exit(ipa); in ipa_probe()
933 ipa_reg_exit(ipa); in ipa_probe()
935 kfree(ipa); in ipa_probe()
949 struct ipa *ipa; in ipa_remove() local
952 ipa = dev_get_drvdata(&pdev->dev); in ipa_remove()
953 dev = ipa->dev; in ipa_remove()
954 WARN_ON(dev != &pdev->dev); in ipa_remove()
956 power = ipa->power; in ipa_remove()
957 interrupt = ipa->interrupt; in ipa_remove()
959 /* Prevent the modem from triggering a call to ipa_setup(). This in ipa_remove()
960 * also ensures a modem-initiated setup that's underway completes. in ipa_remove()
962 ipa_smp2p_irq_disable_setup(ipa); in ipa_remove()
968 if (ipa->setup_complete) { in ipa_remove()
969 ret = ipa_modem_stop(ipa); in ipa_remove()
971 if (ret == -EBUSY) { in ipa_remove()
973 ret = ipa_modem_stop(ipa); in ipa_remove()
981 dev_err(dev, "Failed to stop modem (%pe), leaking resources\n", in ipa_remove()
986 ipa_teardown(ipa); in ipa_remove()
989 ipa_deconfig(ipa); in ipa_remove()
992 ipa_smp2p_exit(ipa); in ipa_remove()
993 ipa_table_exit(ipa); in ipa_remove()
994 ipa_endpoint_exit(ipa); in ipa_remove()
995 gsi_exit(&ipa->gsi); in ipa_remove()
996 ipa_mem_exit(ipa); in ipa_remove()
997 ipa_reg_exit(ipa); in ipa_remove()
998 kfree(ipa); in ipa_remove()
1002 dev_info(dev, "IPA driver removed"); in ipa_remove()
1018 .name = "ipa",