|
@@ -15,6 +15,8 @@
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
*/
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/of.h>
|
|
|
+#include <linux/of_device.h>
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/reset.h>
|
|
|
#include "core.h"
|
|
@@ -502,6 +504,126 @@ static void ath10k_ahb_irq_disable(struct ath10k *ar)
|
|
|
ath10k_pci_disable_and_clear_legacy_irq(ar);
|
|
|
}
|
|
|
|
|
|
+static int ath10k_ahb_resource_init(struct ath10k *ar)
|
|
|
+{
|
|
|
+ struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
|
|
|
+ struct platform_device *pdev;
|
|
|
+ struct device *dev;
|
|
|
+ struct resource *res;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ pdev = ar_ahb->pdev;
|
|
|
+ dev = &pdev->dev;
|
|
|
+
|
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
+ if (!res) {
|
|
|
+ ath10k_err(ar, "failed to get memory resource\n");
|
|
|
+ ret = -ENXIO;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ ar_ahb->mem = devm_ioremap_resource(&pdev->dev, res);
|
|
|
+ if (IS_ERR(ar_ahb->mem)) {
|
|
|
+ ath10k_err(ar, "mem ioremap error\n");
|
|
|
+ ret = PTR_ERR(ar_ahb->mem);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ ar_ahb->mem_len = resource_size(res);
|
|
|
+
|
|
|
+ ar_ahb->gcc_mem = ioremap_nocache(ATH10K_GCC_REG_BASE,
|
|
|
+ ATH10K_GCC_REG_SIZE);
|
|
|
+ if (!ar_ahb->gcc_mem) {
|
|
|
+ ath10k_err(ar, "gcc mem ioremap error\n");
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto err_mem_unmap;
|
|
|
+ }
|
|
|
+
|
|
|
+ ar_ahb->tcsr_mem = ioremap_nocache(ATH10K_TCSR_REG_BASE,
|
|
|
+ ATH10K_TCSR_REG_SIZE);
|
|
|
+ if (!ar_ahb->tcsr_mem) {
|
|
|
+ ath10k_err(ar, "tcsr mem ioremap error\n");
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto err_gcc_mem_unmap;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
|
|
|
+ if (ret) {
|
|
|
+ ath10k_err(ar, "failed to set 32-bit dma mask: %d\n", ret);
|
|
|
+ goto err_tcsr_mem_unmap;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
|
|
|
+ if (ret) {
|
|
|
+ ath10k_err(ar, "failed to set 32-bit consistent dma: %d\n",
|
|
|
+ ret);
|
|
|
+ goto err_tcsr_mem_unmap;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = ath10k_ahb_clock_init(ar);
|
|
|
+ if (ret)
|
|
|
+ goto err_tcsr_mem_unmap;
|
|
|
+
|
|
|
+ ret = ath10k_ahb_rst_ctrl_init(ar);
|
|
|
+ if (ret)
|
|
|
+ goto err_clock_deinit;
|
|
|
+
|
|
|
+ ar_ahb->irq = platform_get_irq_byname(pdev, "legacy");
|
|
|
+ if (ar_ahb->irq < 0) {
|
|
|
+ ath10k_err(ar, "failed to get irq number: %d\n", ar_ahb->irq);
|
|
|
+ goto err_clock_deinit;
|
|
|
+ }
|
|
|
+
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "irq: %d\n", ar_ahb->irq);
|
|
|
+
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%p mem_len: %lu gcc mem: 0x%p tcsr_mem: 0x%p\n",
|
|
|
+ ar_ahb->mem, ar_ahb->mem_len,
|
|
|
+ ar_ahb->gcc_mem, ar_ahb->tcsr_mem);
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_clock_deinit:
|
|
|
+ ath10k_ahb_clock_deinit(ar);
|
|
|
+
|
|
|
+err_tcsr_mem_unmap:
|
|
|
+ iounmap(ar_ahb->tcsr_mem);
|
|
|
+
|
|
|
+err_gcc_mem_unmap:
|
|
|
+ ar_ahb->tcsr_mem = NULL;
|
|
|
+ iounmap(ar_ahb->gcc_mem);
|
|
|
+
|
|
|
+err_mem_unmap:
|
|
|
+ ar_ahb->gcc_mem = NULL;
|
|
|
+ devm_iounmap(&pdev->dev, ar_ahb->mem);
|
|
|
+
|
|
|
+out:
|
|
|
+ ar_ahb->mem = NULL;
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static void ath10k_ahb_resource_deinit(struct ath10k *ar)
|
|
|
+{
|
|
|
+ struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
|
|
|
+ struct device *dev;
|
|
|
+
|
|
|
+ dev = &ar_ahb->pdev->dev;
|
|
|
+
|
|
|
+ if (ar_ahb->mem)
|
|
|
+ devm_iounmap(dev, ar_ahb->mem);
|
|
|
+
|
|
|
+ if (ar_ahb->gcc_mem)
|
|
|
+ iounmap(ar_ahb->gcc_mem);
|
|
|
+
|
|
|
+ if (ar_ahb->tcsr_mem)
|
|
|
+ iounmap(ar_ahb->tcsr_mem);
|
|
|
+
|
|
|
+ ar_ahb->mem = NULL;
|
|
|
+ ar_ahb->gcc_mem = NULL;
|
|
|
+ ar_ahb->tcsr_mem = NULL;
|
|
|
+
|
|
|
+ ath10k_ahb_clock_deinit(ar);
|
|
|
+ ath10k_ahb_rst_ctrl_deinit(ar);
|
|
|
+}
|
|
|
+
|
|
|
static int ath10k_ahb_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
return 0;
|