diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2013-11-25 08:06:21 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2013-11-27 09:45:32 -0500 |
commit | fc15ca13a6c95e0d6af682af118c3c8e679a8152 (patch) | |
tree | e14205c8a0e0dce4daa3139c5324321d0f0d2e0e /drivers/net | |
parent | e539887b1521ed4aefce7387bc3f33814b11442d (diff) |
ath10k: split up pci irq code
Hardware waits until host signals whether it has
chosen MSI(-X) or shared legacy interrupts. It is
not required for the driver to register interrupt
handlers immediately.
This patch prepares the pci irq code for more
changes.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/pci.c | 225 |
1 files changed, 131 insertions, 94 deletions
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 12fb12ea2182..957fc59c2256 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -55,8 +55,10 @@ static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info); | |||
55 | static void ath10k_pci_stop_ce(struct ath10k *ar); | 55 | static void ath10k_pci_stop_ce(struct ath10k *ar); |
56 | static int ath10k_pci_device_reset(struct ath10k *ar); | 56 | static int ath10k_pci_device_reset(struct ath10k *ar); |
57 | static int ath10k_pci_wait_for_target_init(struct ath10k *ar); | 57 | static int ath10k_pci_wait_for_target_init(struct ath10k *ar); |
58 | static int ath10k_pci_start_intr(struct ath10k *ar); | 58 | static int ath10k_pci_init_irq(struct ath10k *ar); |
59 | static void ath10k_pci_stop_intr(struct ath10k *ar); | 59 | static int ath10k_pci_deinit_irq(struct ath10k *ar); |
60 | static int ath10k_pci_request_irq(struct ath10k *ar); | ||
61 | static void ath10k_pci_free_irq(struct ath10k *ar); | ||
60 | 62 | ||
61 | static const struct ce_attr host_ce_config_wlan[] = { | 63 | static const struct ce_attr host_ce_config_wlan[] = { |
62 | /* CE0: host->target HTC control and raw streams */ | 64 | /* CE0: host->target HTC control and raw streams */ |
@@ -1354,7 +1356,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) | |||
1354 | ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__); | 1356 | ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__); |
1355 | 1357 | ||
1356 | /* Irqs are never explicitly re-enabled. They are implicitly re-enabled | 1358 | /* Irqs are never explicitly re-enabled. They are implicitly re-enabled |
1357 | * by ath10k_pci_start_intr(). */ | 1359 | * by upon power_up. */ |
1358 | ath10k_pci_disable_irqs(ar); | 1360 | ath10k_pci_disable_irqs(ar); |
1359 | 1361 | ||
1360 | ath10k_pci_stop_ce(ar); | 1362 | ath10k_pci_stop_ce(ar); |
@@ -1900,34 +1902,40 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) | |||
1900 | goto err_ce; | 1902 | goto err_ce; |
1901 | } | 1903 | } |
1902 | 1904 | ||
1903 | ret = ath10k_pci_start_intr(ar); | 1905 | ret = ath10k_pci_init_irq(ar); |
1904 | if (ret) { | 1906 | if (ret) { |
1905 | ath10k_err("failed to start interrupt handling: %d\n", ret); | 1907 | ath10k_err("failed to init irqs: %d\n", ret); |
1906 | goto err_ce; | 1908 | goto err_ce; |
1907 | } | 1909 | } |
1908 | 1910 | ||
1911 | ret = ath10k_pci_request_irq(ar); | ||
1912 | if (ret) { | ||
1913 | ath10k_err("failed to request irqs: %d\n", ret); | ||
1914 | goto err_deinit_irq; | ||
1915 | } | ||
1916 | |||
1909 | ret = ath10k_pci_wait_for_target_init(ar); | 1917 | ret = ath10k_pci_wait_for_target_init(ar); |
1910 | if (ret) { | 1918 | if (ret) { |
1911 | ath10k_err("failed to wait for target to init: %d\n", ret); | 1919 | ath10k_err("failed to wait for target to init: %d\n", ret); |
1912 | goto err_irq; | 1920 | goto err_free_irq; |
1913 | } | 1921 | } |
1914 | 1922 | ||
1915 | ret = ath10k_ce_enable_err_irq(ar); | 1923 | ret = ath10k_ce_enable_err_irq(ar); |
1916 | if (ret) { | 1924 | if (ret) { |
1917 | ath10k_err("failed to enable CE error irq: %d\n", ret); | 1925 | ath10k_err("failed to enable CE error irq: %d\n", ret); |
1918 | goto err_irq; | 1926 | goto err_free_irq; |
1919 | } | 1927 | } |
1920 | 1928 | ||
1921 | ret = ath10k_pci_init_config(ar); | 1929 | ret = ath10k_pci_init_config(ar); |
1922 | if (ret) { | 1930 | if (ret) { |
1923 | ath10k_err("failed to setup init config: %d\n", ret); | 1931 | ath10k_err("failed to setup init config: %d\n", ret); |
1924 | goto err_irq; | 1932 | goto err_free_irq; |
1925 | } | 1933 | } |
1926 | 1934 | ||
1927 | ret = ath10k_pci_wake_target_cpu(ar); | 1935 | ret = ath10k_pci_wake_target_cpu(ar); |
1928 | if (ret) { | 1936 | if (ret) { |
1929 | ath10k_err("could not wake up target CPU: %d\n", ret); | 1937 | ath10k_err("could not wake up target CPU: %d\n", ret); |
1930 | goto err_irq; | 1938 | goto err_free_irq; |
1931 | } | 1939 | } |
1932 | 1940 | ||
1933 | ath10k_pci_start_bmi(ar); | 1941 | ath10k_pci_start_bmi(ar); |
@@ -1944,11 +1952,12 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) | |||
1944 | 1952 | ||
1945 | return 0; | 1953 | return 0; |
1946 | 1954 | ||
1947 | err_irq: | 1955 | err_free_irq: |
1948 | ath10k_ce_disable_interrupts(ar); | 1956 | ath10k_pci_free_irq(ar); |
1949 | ath10k_pci_stop_intr(ar); | ||
1950 | ath10k_pci_kill_tasklet(ar); | 1957 | ath10k_pci_kill_tasklet(ar); |
1951 | ath10k_pci_device_reset(ar); | 1958 | ath10k_pci_device_reset(ar); |
1959 | err_deinit_irq: | ||
1960 | ath10k_pci_deinit_irq(ar); | ||
1952 | err_ce: | 1961 | err_ce: |
1953 | ath10k_pci_ce_deinit(ar); | 1962 | ath10k_pci_ce_deinit(ar); |
1954 | err_ps: | 1963 | err_ps: |
@@ -1962,7 +1971,8 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar) | |||
1962 | { | 1971 | { |
1963 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1972 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
1964 | 1973 | ||
1965 | ath10k_pci_stop_intr(ar); | 1974 | ath10k_pci_free_irq(ar); |
1975 | ath10k_pci_deinit_irq(ar); | ||
1966 | ath10k_pci_device_reset(ar); | 1976 | ath10k_pci_device_reset(ar); |
1967 | 1977 | ||
1968 | ath10k_pci_ce_deinit(ar); | 1978 | ath10k_pci_ce_deinit(ar); |
@@ -2152,24 +2162,17 @@ static void ath10k_pci_tasklet(unsigned long data) | |||
2152 | } | 2162 | } |
2153 | } | 2163 | } |
2154 | 2164 | ||
2155 | static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num) | 2165 | static int ath10k_pci_request_irq_msix(struct ath10k *ar) |
2156 | { | 2166 | { |
2157 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2167 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2158 | int ret; | 2168 | int ret, i; |
2159 | int i; | ||
2160 | |||
2161 | ret = pci_enable_msi_block(ar_pci->pdev, num); | ||
2162 | if (ret) | ||
2163 | return ret; | ||
2164 | 2169 | ||
2165 | ret = request_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, | 2170 | ret = request_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, |
2166 | ath10k_pci_msi_fw_handler, | 2171 | ath10k_pci_msi_fw_handler, |
2167 | IRQF_SHARED, "ath10k_pci", ar); | 2172 | IRQF_SHARED, "ath10k_pci", ar); |
2168 | if (ret) { | 2173 | if (ret) { |
2169 | ath10k_warn("request_irq(%d) failed %d\n", | 2174 | ath10k_warn("failed to request MSI-X fw irq %d: %d\n", |
2170 | ar_pci->pdev->irq + MSI_ASSIGN_FW, ret); | 2175 | ar_pci->pdev->irq + MSI_ASSIGN_FW, ret); |
2171 | |||
2172 | pci_disable_msi(ar_pci->pdev); | ||
2173 | return ret; | 2176 | return ret; |
2174 | } | 2177 | } |
2175 | 2178 | ||
@@ -2178,45 +2181,38 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num) | |||
2178 | ath10k_pci_per_engine_handler, | 2181 | ath10k_pci_per_engine_handler, |
2179 | IRQF_SHARED, "ath10k_pci", ar); | 2182 | IRQF_SHARED, "ath10k_pci", ar); |
2180 | if (ret) { | 2183 | if (ret) { |
2181 | ath10k_warn("request_irq(%d) failed %d\n", | 2184 | ath10k_warn("failed to request MSI-X ce irq %d: %d\n", |
2182 | ar_pci->pdev->irq + i, ret); | 2185 | ar_pci->pdev->irq + i, ret); |
2183 | 2186 | ||
2184 | for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) | 2187 | for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) |
2185 | free_irq(ar_pci->pdev->irq + i, ar); | 2188 | free_irq(ar_pci->pdev->irq + i, ar); |
2186 | 2189 | ||
2187 | free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar); | 2190 | free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar); |
2188 | pci_disable_msi(ar_pci->pdev); | ||
2189 | return ret; | 2191 | return ret; |
2190 | } | 2192 | } |
2191 | } | 2193 | } |
2192 | 2194 | ||
2193 | ath10k_dbg(ATH10K_DBG_BOOT, | ||
2194 | "MSI-X interrupt handling (%d intrs)\n", num); | ||
2195 | return 0; | 2195 | return 0; |
2196 | } | 2196 | } |
2197 | 2197 | ||
2198 | static int ath10k_pci_start_intr_msi(struct ath10k *ar) | 2198 | static int ath10k_pci_request_irq_msi(struct ath10k *ar) |
2199 | { | 2199 | { |
2200 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2200 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2201 | int ret; | 2201 | int ret; |
2202 | 2202 | ||
2203 | ret = pci_enable_msi(ar_pci->pdev); | ||
2204 | if (ret < 0) | ||
2205 | return ret; | ||
2206 | |||
2207 | ret = request_irq(ar_pci->pdev->irq, | 2203 | ret = request_irq(ar_pci->pdev->irq, |
2208 | ath10k_pci_interrupt_handler, | 2204 | ath10k_pci_interrupt_handler, |
2209 | IRQF_SHARED, "ath10k_pci", ar); | 2205 | IRQF_SHARED, "ath10k_pci", ar); |
2210 | if (ret < 0) { | 2206 | if (ret) { |
2211 | pci_disable_msi(ar_pci->pdev); | 2207 | ath10k_warn("failed to request MSI irq %d: %d\n", |
2208 | ar_pci->pdev->irq, ret); | ||
2212 | return ret; | 2209 | return ret; |
2213 | } | 2210 | } |
2214 | 2211 | ||
2215 | ath10k_dbg(ATH10K_DBG_BOOT, "MSI interrupt handling\n"); | ||
2216 | return 0; | 2212 | return 0; |
2217 | } | 2213 | } |
2218 | 2214 | ||
2219 | static int ath10k_pci_start_intr_legacy(struct ath10k *ar) | 2215 | static int ath10k_pci_request_irq_legacy(struct ath10k *ar) |
2220 | { | 2216 | { |
2221 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2217 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2222 | int ret; | 2218 | int ret; |
@@ -2224,99 +2220,140 @@ static int ath10k_pci_start_intr_legacy(struct ath10k *ar) | |||
2224 | ret = request_irq(ar_pci->pdev->irq, | 2220 | ret = request_irq(ar_pci->pdev->irq, |
2225 | ath10k_pci_interrupt_handler, | 2221 | ath10k_pci_interrupt_handler, |
2226 | IRQF_SHARED, "ath10k_pci", ar); | 2222 | IRQF_SHARED, "ath10k_pci", ar); |
2227 | if (ret < 0) | ||
2228 | return ret; | ||
2229 | |||
2230 | ret = ath10k_pci_wake(ar); | ||
2231 | if (ret) { | 2223 | if (ret) { |
2232 | free_irq(ar_pci->pdev->irq, ar); | 2224 | ath10k_warn("failed to request legacy irq %d: %d\n", |
2233 | ath10k_err("failed to wake up target: %d\n", ret); | 2225 | ar_pci->pdev->irq, ret); |
2234 | return ret; | 2226 | return ret; |
2235 | } | 2227 | } |
2236 | 2228 | ||
2237 | /* | ||
2238 | * A potential race occurs here: The CORE_BASE write | ||
2239 | * depends on target correctly decoding AXI address but | ||
2240 | * host won't know when target writes BAR to CORE_CTRL. | ||
2241 | * This write might get lost if target has NOT written BAR. | ||
2242 | * For now, fix the race by repeating the write in below | ||
2243 | * synchronization checking. | ||
2244 | */ | ||
2245 | iowrite32(PCIE_INTR_FIRMWARE_MASK | | ||
2246 | PCIE_INTR_CE_MASK_ALL, | ||
2247 | ar_pci->mem + (SOC_CORE_BASE_ADDRESS | | ||
2248 | PCIE_INTR_ENABLE_ADDRESS)); | ||
2249 | |||
2250 | ath10k_pci_sleep(ar); | ||
2251 | ath10k_dbg(ATH10K_DBG_BOOT, "legacy interrupt handling\n"); | ||
2252 | return 0; | 2229 | return 0; |
2253 | } | 2230 | } |
2254 | 2231 | ||
2255 | static int ath10k_pci_start_intr(struct ath10k *ar) | 2232 | static int ath10k_pci_request_irq(struct ath10k *ar) |
2233 | { | ||
2234 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
2235 | |||
2236 | switch (ar_pci->num_msi_intrs) { | ||
2237 | case 0: | ||
2238 | return ath10k_pci_request_irq_legacy(ar); | ||
2239 | case 1: | ||
2240 | return ath10k_pci_request_irq_msi(ar); | ||
2241 | case MSI_NUM_REQUEST: | ||
2242 | return ath10k_pci_request_irq_msix(ar); | ||
2243 | } | ||
2244 | |||
2245 | ath10k_warn("unknown irq configuration upon request\n"); | ||
2246 | return -EINVAL; | ||
2247 | } | ||
2248 | |||
2249 | static void ath10k_pci_free_irq(struct ath10k *ar) | ||
2256 | { | 2250 | { |
2257 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2251 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2258 | int num = MSI_NUM_REQUEST; | ||
2259 | int ret; | ||
2260 | int i; | 2252 | int i; |
2261 | 2253 | ||
2262 | tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long) ar); | 2254 | /* There's at least one interrupt irregardless whether its legacy INTR |
2255 | * or MSI or MSI-X */ | ||
2256 | for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) | ||
2257 | free_irq(ar_pci->pdev->irq + i, ar); | ||
2258 | } | ||
2259 | |||
2260 | static void ath10k_pci_init_irq_tasklets(struct ath10k *ar) | ||
2261 | { | ||
2262 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
2263 | int i; | ||
2264 | |||
2265 | tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar); | ||
2263 | tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet, | 2266 | tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet, |
2264 | (unsigned long) ar); | 2267 | (unsigned long)ar); |
2265 | 2268 | ||
2266 | for (i = 0; i < CE_COUNT; i++) { | 2269 | for (i = 0; i < CE_COUNT; i++) { |
2267 | ar_pci->pipe_info[i].ar_pci = ar_pci; | 2270 | ar_pci->pipe_info[i].ar_pci = ar_pci; |
2268 | tasklet_init(&ar_pci->pipe_info[i].intr, | 2271 | tasklet_init(&ar_pci->pipe_info[i].intr, ath10k_pci_ce_tasklet, |
2269 | ath10k_pci_ce_tasklet, | ||
2270 | (unsigned long)&ar_pci->pipe_info[i]); | 2272 | (unsigned long)&ar_pci->pipe_info[i]); |
2271 | } | 2273 | } |
2274 | } | ||
2275 | |||
2276 | static int ath10k_pci_init_irq(struct ath10k *ar) | ||
2277 | { | ||
2278 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
2279 | int ret; | ||
2280 | |||
2281 | ath10k_pci_init_irq_tasklets(ar); | ||
2272 | 2282 | ||
2273 | if (!test_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features)) | 2283 | if (!test_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features)) |
2274 | num = 1; | 2284 | goto msi; |
2275 | 2285 | ||
2276 | if (num > 1) { | 2286 | /* Try MSI-X */ |
2277 | ret = ath10k_pci_start_intr_msix(ar, num); | 2287 | ar_pci->num_msi_intrs = MSI_NUM_REQUEST; |
2278 | if (ret == 0) | 2288 | ret = pci_enable_msi_block(ar_pci->pdev, ar_pci->num_msi_intrs); |
2279 | goto exit; | 2289 | if (ret == 0) |
2290 | return 0; | ||
2291 | if (ret > 0) | ||
2292 | pci_disable_msi(ar_pci->pdev); | ||
2280 | 2293 | ||
2281 | ath10k_dbg(ATH10K_DBG_BOOT, | 2294 | msi: |
2282 | "MSI-X didn't succeed (%d), trying MSI\n", ret); | 2295 | /* Try MSI */ |
2283 | num = 1; | 2296 | ar_pci->num_msi_intrs = 1; |
2284 | } | 2297 | ret = pci_enable_msi(ar_pci->pdev); |
2298 | if (ret == 0) | ||
2299 | return 0; | ||
2285 | 2300 | ||
2286 | if (num == 1) { | 2301 | /* Try legacy irq |
2287 | ret = ath10k_pci_start_intr_msi(ar); | 2302 | * |
2288 | if (ret == 0) | 2303 | * A potential race occurs here: The CORE_BASE write |
2289 | goto exit; | 2304 | * depends on target correctly decoding AXI address but |
2305 | * host won't know when target writes BAR to CORE_CTRL. | ||
2306 | * This write might get lost if target has NOT written BAR. | ||
2307 | * For now, fix the race by repeating the write in below | ||
2308 | * synchronization checking. */ | ||
2309 | ar_pci->num_msi_intrs = 0; | ||
2290 | 2310 | ||
2291 | ath10k_dbg(ATH10K_DBG_BOOT, | 2311 | ret = ath10k_pci_wake(ar); |
2292 | "MSI didn't succeed (%d), trying legacy INTR\n", | 2312 | if (ret) { |
2293 | ret); | 2313 | ath10k_warn("failed to wake target: %d\n", ret); |
2294 | num = 0; | 2314 | return ret; |
2295 | } | 2315 | } |
2296 | 2316 | ||
2297 | ret = ath10k_pci_start_intr_legacy(ar); | 2317 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, |
2318 | PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); | ||
2319 | ath10k_pci_sleep(ar); | ||
2320 | |||
2321 | return 0; | ||
2322 | } | ||
2323 | |||
2324 | static int ath10k_pci_deinit_irq_legacy(struct ath10k *ar) | ||
2325 | { | ||
2326 | int ret; | ||
2327 | |||
2328 | ret = ath10k_pci_wake(ar); | ||
2298 | if (ret) { | 2329 | if (ret) { |
2299 | ath10k_warn("Failed to start legacy interrupts: %d\n", ret); | 2330 | ath10k_warn("failed to wake target: %d\n", ret); |
2300 | return ret; | 2331 | return ret; |
2301 | } | 2332 | } |
2302 | 2333 | ||
2303 | exit: | 2334 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, |
2304 | ar_pci->num_msi_intrs = num; | 2335 | 0); |
2305 | return ret; | 2336 | ath10k_pci_sleep(ar); |
2337 | |||
2338 | return 0; | ||
2306 | } | 2339 | } |
2307 | 2340 | ||
2308 | static void ath10k_pci_stop_intr(struct ath10k *ar) | 2341 | static int ath10k_pci_deinit_irq(struct ath10k *ar) |
2309 | { | 2342 | { |
2310 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2343 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2311 | int i; | ||
2312 | 2344 | ||
2313 | /* There's at least one interrupt irregardless whether its legacy INTR | 2345 | switch (ar_pci->num_msi_intrs) { |
2314 | * or MSI or MSI-X */ | 2346 | case 0: |
2315 | for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) | 2347 | return ath10k_pci_deinit_irq_legacy(ar); |
2316 | free_irq(ar_pci->pdev->irq + i, ar); | 2348 | case 1: |
2317 | 2349 | /* fall-through */ | |
2318 | if (ar_pci->num_msi_intrs > 0) | 2350 | case MSI_NUM_REQUEST: |
2319 | pci_disable_msi(ar_pci->pdev); | 2351 | pci_disable_msi(ar_pci->pdev); |
2352 | return 0; | ||
2353 | } | ||
2354 | |||
2355 | ath10k_warn("unknown irq configuration upon deinit\n"); | ||
2356 | return -EINVAL; | ||
2320 | } | 2357 | } |
2321 | 2358 | ||
2322 | static int ath10k_pci_wait_for_target_init(struct ath10k *ar) | 2359 | static int ath10k_pci_wait_for_target_init(struct ath10k *ar) |