.. | .. |
---|
1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 1 | /* |
---|
3 | 2 | * SDIO access interface for drivers - linux specific (pci only) |
---|
4 | 3 | * |
---|
5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
---|
6 | | - * |
---|
| 4 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
---|
| 5 | + * |
---|
| 6 | + * Copyright (C) 1999-2017, Broadcom Corporation |
---|
| 7 | + * |
---|
7 | 8 | * Unless you and Broadcom execute a separate written software license |
---|
8 | 9 | * agreement governing use of this software, this software is licensed to you |
---|
9 | 10 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
---|
10 | 11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
---|
11 | 12 | * following added to such license: |
---|
12 | | - * |
---|
| 13 | + * |
---|
13 | 14 | * As a special exception, the copyright holders of this software give you |
---|
14 | 15 | * permission to link this software with independent modules, and to copy and |
---|
15 | 16 | * distribute the resulting executable under terms of your choice, provided that |
---|
.. | .. |
---|
17 | 18 | * the license of that module. An independent module is a module which is not |
---|
18 | 19 | * derived from this software. The special exception does not apply to any |
---|
19 | 20 | * modifications of the software. |
---|
20 | | - * |
---|
| 21 | + * |
---|
21 | 22 | * Notwithstanding the above, under no circumstances may you combine this |
---|
22 | 23 | * software in any way with any other Broadcom software provided under a license |
---|
23 | 24 | * other than the GPL, without Broadcom's express prior written consent. |
---|
.. | .. |
---|
25 | 26 | * |
---|
26 | 27 | * <<Broadcom-WL-IPTag/Open:>> |
---|
27 | 28 | * |
---|
28 | | - * $Id: bcmsdh_linux.c 579798 2015-08-17 07:00:05Z $ |
---|
| 29 | + * $Id: bcmsdh_linux.c 689948 2017-03-14 05:21:03Z $ |
---|
29 | 30 | */ |
---|
30 | 31 | |
---|
31 | 32 | /** |
---|
.. | .. |
---|
48 | 49 | #include <bcmutils.h> |
---|
49 | 50 | #include <dngl_stats.h> |
---|
50 | 51 | #include <dhd.h> |
---|
51 | | -#if defined(CONFIG_ARCH_ODIN) |
---|
52 | | -#include <linux/platform_data/gpio-odin.h> |
---|
53 | | -#endif /* defined(CONFIG_ARCH_ODIN) */ |
---|
54 | 52 | #include <dhd_linux.h> |
---|
55 | 53 | |
---|
56 | 54 | /* driver info, initialized when bcmsdh_register is called */ |
---|
.. | .. |
---|
85 | 83 | } bcmsdh_os_info_t; |
---|
86 | 84 | |
---|
87 | 85 | /* debugging macros */ |
---|
88 | | -#define SDLX_MSG(x) do { printf x; } while (0) |
---|
| 86 | +#define SDLX_MSG(x) |
---|
89 | 87 | |
---|
90 | 88 | /** |
---|
91 | 89 | * Checks to see if vendor and device IDs match a supported SDIO Host Controller. |
---|
.. | .. |
---|
98 | 96 | #ifdef BCMSDIOH_STD |
---|
99 | 97 | /* Check for Arasan host controller */ |
---|
100 | 98 | if (vendor == VENDOR_SI_IMAGE) { |
---|
| 99 | + return (TRUE); |
---|
| 100 | + } |
---|
| 101 | + if (device == SDIOH_FPGA_ID && vendor == VENDOR_CYPRESS) { |
---|
101 | 102 | return (TRUE); |
---|
102 | 103 | } |
---|
103 | 104 | /* Check for BRCM 27XX Standard host controller */ |
---|
.. | .. |
---|
161 | 162 | bcmsdh_osinfo->dev = dev; |
---|
162 | 163 | osl_set_bus_handle(osh, bcmsdh); |
---|
163 | 164 | |
---|
164 | | -#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 165 | +#if (!defined(CONFIG_PM_WAKELOCKS) || !defined(CONFIG_HAS_WAKELOCK)) && \ |
---|
| 166 | + (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
165 | 167 | if (dev && device_init_wakeup(dev, true) == 0) |
---|
166 | 168 | bcmsdh_osinfo->dev_wake_enabled = TRUE; |
---|
167 | | -#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */ |
---|
| 169 | +#endif /* CONFIG_PM_WAKELOCKS ||CONFIG_HAS_WAKELOCK && |
---|
| 170 | + * (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 171 | + */ |
---|
168 | 172 | |
---|
169 | 173 | #if defined(OOB_INTR_ONLY) |
---|
170 | 174 | spin_lock_init(&bcmsdh_osinfo->oob_irq_spinlock); |
---|
.. | .. |
---|
179 | 183 | |
---|
180 | 184 | /* Read the vendor/device ID from the CIS */ |
---|
181 | 185 | vendevid = bcmsdh_query_device(bcmsdh); |
---|
| 186 | + |
---|
182 | 187 | /* try to attach to the target device */ |
---|
| 188 | +#if defined(BCMSPI) && (defined(BCMPCISPIHOST) || defined(BCMSDIOH_SPI)) |
---|
| 189 | + bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num, |
---|
| 190 | + slot_num, 0, bus_type, (void *)regs, NULL, bcmsdh); |
---|
| 191 | +#else |
---|
183 | 192 | bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num, |
---|
184 | 193 | slot_num, 0, bus_type, (void *)regs, osh, bcmsdh); |
---|
| 194 | +#endif /* BCMSPI && (BCMPCISPIHOST || BCMSDIOH_SPI) */ |
---|
185 | 195 | if (bcmsdh_osinfo->context == NULL) { |
---|
186 | 196 | SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); |
---|
187 | 197 | goto err; |
---|
.. | .. |
---|
202 | 212 | { |
---|
203 | 213 | bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt; |
---|
204 | 214 | |
---|
205 | | -#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 215 | +#if (!defined(CONFIG_PM_WAKELOCKS) || !defined(CONFIG_HAS_WAKELOCK)) && \ |
---|
| 216 | + (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
206 | 217 | if (bcmsdh_osinfo->dev) |
---|
207 | 218 | device_init_wakeup(bcmsdh_osinfo->dev, false); |
---|
208 | 219 | bcmsdh_osinfo->dev_wake_enabled = FALSE; |
---|
209 | | -#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */ |
---|
| 220 | +#endif /* CONFIG_PM_WAKELOCKS ||CONFIG_HAS_WAKELOCK && |
---|
| 221 | + * (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 222 | + */ |
---|
210 | 223 | |
---|
211 | 224 | drvinfo.remove(bcmsdh_osinfo->context); |
---|
212 | 225 | MFREE(bcmsdh->osh, bcmsdh->os_cxt, sizeof(bcmsdh_os_info_t)); |
---|
.. | .. |
---|
214 | 227 | |
---|
215 | 228 | return 0; |
---|
216 | 229 | } |
---|
| 230 | + |
---|
| 231 | +#ifdef DHD_WAKE_STATUS |
---|
| 232 | +int bcmsdh_get_total_wake(bcmsdh_info_t *bcmsdh) |
---|
| 233 | +{ |
---|
| 234 | + return bcmsdh->total_wake_count; |
---|
| 235 | +} |
---|
| 236 | + |
---|
| 237 | +int bcmsdh_set_get_wake(bcmsdh_info_t *bcmsdh, int flag) |
---|
| 238 | +{ |
---|
| 239 | + bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt; |
---|
| 240 | + unsigned long flags; |
---|
| 241 | + int ret; |
---|
| 242 | + |
---|
| 243 | + spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags); |
---|
| 244 | + |
---|
| 245 | + ret = bcmsdh->pkt_wake; |
---|
| 246 | + bcmsdh->total_wake_count += flag; |
---|
| 247 | + bcmsdh->pkt_wake = flag; |
---|
| 248 | + |
---|
| 249 | + spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags); |
---|
| 250 | + return ret; |
---|
| 251 | +} |
---|
| 252 | +#endif /* DHD_WAKE_STATUS */ |
---|
217 | 253 | |
---|
218 | 254 | int bcmsdh_suspend(bcmsdh_info_t *bcmsdh) |
---|
219 | 255 | { |
---|
.. | .. |
---|
270 | 306 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) |
---|
271 | 307 | if (bcmsdh_pci_driver.node.next == NULL) |
---|
272 | 308 | return; |
---|
273 | | -#endif |
---|
| 309 | +#endif // endif |
---|
274 | 310 | |
---|
275 | 311 | bcmsdh_unregister_client_driver(); |
---|
276 | 312 | } |
---|
277 | 313 | |
---|
278 | 314 | void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *bcmsdh) |
---|
279 | 315 | { |
---|
280 | | -#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 316 | +#if (!defined(CONFIG_PM_WAKELOCKS) || !defined(CONFIG_HAS_WAKELOCK)) && \ |
---|
| 317 | + (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
281 | 318 | bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt; |
---|
282 | 319 | pm_stay_awake(bcmsdh_osinfo->dev); |
---|
283 | | -#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */ |
---|
| 320 | +#endif /* CONFIG_PM_WAKELOCKS ||CONFIG_HAS_WAKELOCK && |
---|
| 321 | + * (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 322 | + */ |
---|
284 | 323 | } |
---|
285 | 324 | |
---|
286 | 325 | void bcmsdh_dev_relax(bcmsdh_info_t *bcmsdh) |
---|
287 | 326 | { |
---|
288 | | -#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 327 | +#if (!defined(CONFIG_PM_WAKELOCKS) || !defined(CONFIG_HAS_WAKELOCK)) && \ |
---|
| 328 | + (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
289 | 329 | bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt; |
---|
290 | 330 | pm_relax(bcmsdh_osinfo->dev); |
---|
291 | | -#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */ |
---|
| 331 | +#endif /* CONFIG_PM_WAKELOCKS ||CONFIG_HAS_WAKELOCK && |
---|
| 332 | + * (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) |
---|
| 333 | + */ |
---|
292 | 334 | } |
---|
293 | 335 | |
---|
294 | 336 | bool bcmsdh_dev_pm_enabled(bcmsdh_info_t *bcmsdh) |
---|
.. | .. |
---|
298 | 340 | return bcmsdh_osinfo->dev_wake_enabled; |
---|
299 | 341 | } |
---|
300 | 342 | |
---|
301 | | -#if defined(OOB_INTR_ONLY) |
---|
| 343 | +#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) |
---|
302 | 344 | void bcmsdh_oob_intr_set(bcmsdh_info_t *bcmsdh, bool enable) |
---|
303 | 345 | { |
---|
304 | 346 | unsigned long flags; |
---|
.. | .. |
---|
324 | 366 | bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)dev_id; |
---|
325 | 367 | bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt; |
---|
326 | 368 | |
---|
| 369 | +#ifndef BCMSPI_ANDROID |
---|
327 | 370 | bcmsdh_oob_intr_set(bcmsdh, FALSE); |
---|
| 371 | +#endif /* !BCMSPI_ANDROID */ |
---|
328 | 372 | bcmsdh_osinfo->oob_irq_handler(bcmsdh_osinfo->oob_irq_handler_context); |
---|
329 | 373 | |
---|
330 | 374 | return IRQ_HANDLED; |
---|
.. | .. |
---|
345 | 389 | (int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags)); |
---|
346 | 390 | bcmsdh_osinfo->oob_irq_handler = oob_irq_handler; |
---|
347 | 391 | bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context; |
---|
348 | | -#if defined(CONFIG_ARCH_ODIN) |
---|
349 | | - err = odin_gpio_sms_request_irq(bcmsdh_osinfo->oob_irq_num, wlan_oob_irq, |
---|
350 | | - bcmsdh_osinfo->oob_irq_flags, "bcmsdh_sdmmc", bcmsdh); |
---|
351 | | -#else |
---|
| 392 | + bcmsdh_osinfo->oob_irq_enabled = TRUE; |
---|
| 393 | + bcmsdh_osinfo->oob_irq_registered = TRUE; |
---|
352 | 394 | err = request_irq(bcmsdh_osinfo->oob_irq_num, wlan_oob_irq, |
---|
353 | 395 | bcmsdh_osinfo->oob_irq_flags, "bcmsdh_sdmmc", bcmsdh); |
---|
354 | | -#endif /* defined(CONFIG_ARCH_ODIN) */ |
---|
355 | 396 | if (err) { |
---|
356 | 397 | SDLX_MSG(("%s: request_irq failed with %d\n", __FUNCTION__, err)); |
---|
| 398 | + bcmsdh_osinfo->oob_irq_enabled = FALSE; |
---|
| 399 | + bcmsdh_osinfo->oob_irq_registered = FALSE; |
---|
357 | 400 | return err; |
---|
358 | 401 | } |
---|
359 | 402 | |
---|
| 403 | +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) |
---|
| 404 | + if (device_may_wakeup(bcmsdh_osinfo->dev)) { |
---|
| 405 | +#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */ |
---|
360 | 406 | err = enable_irq_wake(bcmsdh_osinfo->oob_irq_num); |
---|
361 | 407 | if (!err) |
---|
362 | 408 | bcmsdh_osinfo->oob_irq_wake_enabled = TRUE; |
---|
363 | | - bcmsdh_osinfo->oob_irq_enabled = TRUE; |
---|
364 | | - bcmsdh_osinfo->oob_irq_registered = TRUE; |
---|
| 409 | +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) |
---|
| 410 | + } |
---|
| 411 | +#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */ |
---|
365 | 412 | return err; |
---|
366 | 413 | } |
---|
367 | 414 | |
---|
.. | .. |
---|
376 | 423 | return; |
---|
377 | 424 | } |
---|
378 | 425 | if (bcmsdh_osinfo->oob_irq_wake_enabled) { |
---|
| 426 | +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) |
---|
| 427 | + if (device_may_wakeup(bcmsdh_osinfo->dev)) { |
---|
| 428 | +#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */ |
---|
379 | 429 | err = disable_irq_wake(bcmsdh_osinfo->oob_irq_num); |
---|
380 | 430 | if (!err) |
---|
381 | 431 | bcmsdh_osinfo->oob_irq_wake_enabled = FALSE; |
---|
| 432 | +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) |
---|
| 433 | + } |
---|
| 434 | +#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */ |
---|
382 | 435 | } |
---|
383 | 436 | if (bcmsdh_osinfo->oob_irq_enabled) { |
---|
384 | 437 | disable_irq(bcmsdh_osinfo->oob_irq_num); |
---|
.. | .. |
---|
387 | 440 | free_irq(bcmsdh_osinfo->oob_irq_num, bcmsdh); |
---|
388 | 441 | bcmsdh_osinfo->oob_irq_registered = FALSE; |
---|
389 | 442 | } |
---|
390 | | -#endif |
---|
| 443 | +#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */ |
---|
391 | 444 | |
---|
392 | 445 | /* Module parameters specific to each host-controller driver */ |
---|
393 | 446 | |
---|
394 | 447 | extern uint sd_msglevel; /* Debug message level */ |
---|
395 | | -module_param(sd_msglevel, uint, 0664); |
---|
| 448 | +module_param(sd_msglevel, uint, 0); |
---|
396 | 449 | |
---|
397 | 450 | extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ |
---|
398 | 451 | module_param(sd_power, uint, 0); |
---|
.. | .. |
---|
427 | 480 | extern char dhd_sdiod_uhsi_ds_override[2]; |
---|
428 | 481 | module_param_string(dhd_sdiod_uhsi_ds_override, dhd_sdiod_uhsi_ds_override, 2, 0); |
---|
429 | 482 | |
---|
430 | | -#endif |
---|
| 483 | +#endif // endif |
---|
| 484 | + |
---|
| 485 | + |
---|
| 486 | + |
---|
431 | 487 | |
---|
432 | 488 | #ifdef BCMSDH_MODULE |
---|
433 | 489 | EXPORT_SYMBOL(bcmsdh_attach); |
---|
.. | .. |
---|
440 | 496 | |
---|
441 | 497 | #if defined(DHD_DEBUG) |
---|
442 | 498 | EXPORT_SYMBOL(bcmsdh_intr_pending); |
---|
443 | | -#endif |
---|
| 499 | +#endif // endif |
---|
| 500 | + |
---|
| 501 | +#if defined(BT_OVER_SDIO) |
---|
| 502 | +EXPORT_SYMBOL(bcmsdh_btsdio_interface_init); |
---|
| 503 | +#endif /* defined (BT_OVER_SDIO) */ |
---|
444 | 504 | |
---|
445 | 505 | EXPORT_SYMBOL(bcmsdh_devremove_reg); |
---|
446 | 506 | EXPORT_SYMBOL(bcmsdh_cfg_read); |
---|