From 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 22 Oct 2024 10:36:11 +0000
Subject: [PATCH] 修改4g拨号为QMI,需要在系统里后台执行quectel-CM
---
kernel/drivers/parisc/ccio-dma.c | 69 +++++++++++++++++-----------------
1 files changed, 34 insertions(+), 35 deletions(-)
diff --git a/kernel/drivers/parisc/ccio-dma.c b/kernel/drivers/parisc/ccio-dma.c
index 6efab7a..be81b76 100644
--- a/kernel/drivers/parisc/ccio-dma.c
+++ b/kernel/drivers/parisc/ccio-dma.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
** ccio-dma.c:
** DMA management routines for first generation cache-coherent machines.
@@ -7,10 +8,6 @@
** (c) Copyright 2000 Ryan Bradetich
** (c) Copyright 2000 Hewlett-Packard Company
**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
**
**
** "Real Mode" operation refers to U2/Uturn chip operation.
@@ -42,6 +39,7 @@
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/dma-map-ops.h>
#include <linux/scatterlist.h>
#include <linux/iommu-helper.h>
#include <linux/export.h>
@@ -54,6 +52,8 @@
#include <asm/io.h>
#include <asm/hardware.h> /* for register_module() */
#include <asm/parisc-device.h>
+
+#include "iommu.h"
/*
** Choose "ccio" since that's what HP-UX calls it.
@@ -109,8 +109,6 @@
#define IOA_NORMAL_MODE 0x00020080 /* IO_CONTROL to turn on CCIO */
#define CMD_TLB_DIRECT_WRITE 35 /* IO_COMMAND for I/O TLB Writes */
#define CMD_TLB_PURGE 33 /* IO_COMMAND to Purge I/O TLB entry */
-
-#define CCIO_MAPPING_ERROR (~(dma_addr_t)0)
struct ioa_registers {
/* Runway Supervisory Set */
@@ -359,8 +357,7 @@
** ggg sacrifices another 710 to the computer gods.
*/
- boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
- 1ULL << IOVP_SHIFT) >> IOVP_SHIFT;
+ boundary_size = dma_get_seg_boundary_nr_pages(dev, IOVP_SHIFT);
if (pages_needed <= 8) {
/*
@@ -570,7 +567,7 @@
** "hints" parm includes the VALID bit!
** "dep" clobbers the physical address offset bits as well.
*/
- pa = virt_to_phys(vba);
+ pa = lpa(vba);
asm volatile("depw %1,31,12,%0" : "+r" (pa) : "r" (hints));
((u32 *)pdir_ptr)[1] = (u32) pa;
@@ -607,14 +604,13 @@
** PCX-T'? Don't know. (eg C110 or similar K-class)
**
** See PDC_MODEL/option 0/SW_CAP word for "Non-coherent IO-PDIR bit".
- ** Hopefully we can patch (NOP) these out at boot time somehow.
**
** "Since PCX-U employs an offset hash that is incompatible with
** the real mode coherence index generation of U2, the PDIR entry
** must be flushed to memory to retain coherence."
*/
- asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
- asm volatile("sync");
+ asm_io_fdc(pdir_ptr);
+ asm_io_sync();
}
/**
@@ -680,17 +676,14 @@
** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360)
** PCX-U/U+ do. (eg C200/C240)
** See PDC_MODEL/option 0/SW_CAP for "Non-coherent IO-PDIR bit".
- **
- ** Hopefully someone figures out how to patch (NOP) the
- ** FDC/SYNC out at boot time.
*/
- asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr[7]));
+ asm_io_fdc(pdir_ptr);
iovp += IOVP_SIZE;
byte_cnt -= IOVP_SIZE;
}
- asm volatile("sync");
+ asm_io_sync();
ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt);
}
@@ -714,8 +707,8 @@
return 0;
}
- /* only support 32-bit devices (ie PCI/GSC) */
- return (int)(mask == 0xffffffffUL);
+ /* only support 32-bit or better devices (ie PCI/GSC) */
+ return (int)(mask >= 0xffffffffUL);
}
/**
@@ -742,7 +735,7 @@
BUG_ON(!dev);
ioc = GET_IOC(dev);
if (!ioc)
- return CCIO_MAPPING_ERROR;
+ return DMA_MAPPING_ERROR;
BUG_ON(size <= 0);
@@ -1024,11 +1017,6 @@
DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents);
}
-static int ccio_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return dma_addr == CCIO_MAPPING_ERROR;
-}
-
static const struct dma_map_ops ccio_ops = {
.dma_supported = ccio_dma_supported,
.alloc = ccio_alloc,
@@ -1037,7 +1025,9 @@
.unmap_page = ccio_unmap_page,
.map_sg = ccio_map_sg,
.unmap_sg = ccio_unmap_sg,
- .mapping_error = ccio_mapping_error,
+ .get_sgtable = dma_common_get_sgtable,
+ .alloc_pages = dma_common_alloc_pages,
+ .free_pages = dma_common_free_pages,
};
#ifdef CONFIG_PROC_FS
@@ -1254,7 +1244,7 @@
** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
*/
- iova_space_size = (u32) (totalram_pages / count_parisc_driver(&ccio_driver));
+ iova_space_size = (u32) (totalram_pages() / count_parisc_driver(&ccio_driver));
/* limit IOVA space size to 1MB-1GB */
@@ -1293,7 +1283,7 @@
DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n",
__func__, ioc->ioc_regs,
- (unsigned long) totalram_pages >> (20 - PAGE_SHIFT),
+ (unsigned long) totalram_pages() >> (20 - PAGE_SHIFT),
iova_space_size>>20,
iov_order + PAGE_SHIFT);
@@ -1390,15 +1380,17 @@
}
}
-static void __init ccio_init_resources(struct ioc *ioc)
+static int __init ccio_init_resources(struct ioc *ioc)
{
struct resource *res = ioc->mmio_region;
char *name = kmalloc(14, GFP_KERNEL);
-
+ if (unlikely(!name))
+ return -ENOMEM;
snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path);
ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low);
ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv);
+ return 0;
}
static int new_ioc_area(struct resource *res, unsigned long size,
@@ -1528,6 +1520,7 @@
{
int i;
struct ioc *ioc, **ioc_p = &ioc_list;
+ struct pci_hba_data *hba;
ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL);
if (ioc == NULL) {
@@ -1546,19 +1539,25 @@
*ioc_p = ioc;
ioc->hw_path = dev->hw_path;
- ioc->ioc_regs = ioremap_nocache(dev->hpa.start, 4096);
+ ioc->ioc_regs = ioremap(dev->hpa.start, 4096);
if (!ioc->ioc_regs) {
kfree(ioc);
return -ENOMEM;
}
ccio_ioc_init(ioc);
- ccio_init_resources(ioc);
+ if (ccio_init_resources(ioc)) {
+ iounmap(ioc->ioc_regs);
+ kfree(ioc);
+ return -ENOMEM;
+ }
hppa_dma_ops = &ccio_ops;
- dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+ hba = kzalloc(sizeof(*hba), GFP_KERNEL);
/* if this fails, no I/O cards will work, so may as well bug */
- BUG_ON(dev->dev.platform_data == NULL);
- HBA_DATA(dev->dev.platform_data)->iommu = ioc;
+ BUG_ON(hba == NULL);
+
+ hba->iommu = ioc;
+ dev->dev.platform_data = hba;
#ifdef CONFIG_PROC_FS
if (ioc_count == 0) {
--
Gitblit v1.6.2