[Deepin-Kernel-SIG] [linux 7.2.y] [deepin] phytium spi/hda/sound/qspi and gf audio support from v6.6 and bugfix - #2129
Conversation
There was a problem hiding this comment.
Sorry @opsiff, your pull request is larger than the review limit of 150,000 diff characters
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
🟡 Changes recommended
Build omissions, resource leaks, unsafe asynchronous teardown, and SPI/QSPI correctness defects must be resolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds Phytium SPI/QSPI and HDA support, Glenfly audio handling, ACPI MTD partition parsing, and SCMI mailbox compatibility changes.
Changes:
- Adds Phytium SPI v2, QSPI, and platform HDA drivers.
- Adds Glenfly framebuffer-backed HDA support and codec IDs.
- Extends SCMI mailbox and MTD partition handling for Phytium firmware.
File summaries
| File | Description |
|---|---|
Documentation/devicetree/bindings/spi/phytium,qspi-nor.yaml |
Defines the Phytium QSPI binding. |
arch/arm64/configs/deepin_arm64_desktop_defconfig |
Updates platform configuration. |
drivers/firmware/arm_scmi/common.h |
Extends SCMI channel state. |
drivers/firmware/arm_scmi/driver.c |
Supports polling-based SCMI completion. |
drivers/firmware/arm_scmi/transports/mailbox.c |
Detects Phytium mailbox behavior. |
drivers/mtd/parsers/Kconfig |
Adds ACPI partition parser configuration. |
drivers/mtd/parsers/Makefile |
Builds the ACPI parser. |
drivers/mtd/parsers/acpipart_core.c |
Parses ACPI-described partitions. |
drivers/mtd/mtdpart.c |
Integrates ACPI partition discovery. |
include/linux/mtd/partitions.h |
Adds partition firmware-node metadata. |
drivers/spi/Kconfig |
Adds Phytium SPI/QSPI options. |
drivers/spi/Makefile |
Adds Phytium build targets. |
drivers/spi/spi-phytium-common.c |
Implements SPI v2 firmware messaging. |
drivers/spi/spi-phytium-pci.c |
Adds PCI frontend support. |
drivers/spi/spi-phytium-plat-v2.c |
Adds SPI v2 platform frontend. |
drivers/spi/spi-phytium-plat.c |
Adds legacy platform integration. |
drivers/spi/spi-phytium-qspi.c |
Implements the QSPI controller. |
drivers/spi/spi-phytium-v2.c |
Implements the SPI v2 controller. |
drivers/spi/spi-phytium.c |
Implements shared legacy SPI behavior. |
drivers/spi/spi-phytium.h |
Defines Phytium SPI state and interfaces. |
sound/hda/codecs/hdmi/hdmi.c |
Adds Glenfly HDMI codec IDs. |
sound/hda/common/controller.c |
Adds Glenfly stream-buffer handling. |
sound/hda/common/hda_controller.h |
Extends shared HDA stream state. |
sound/hda/controllers/Kconfig |
Adds Phytium HDA configuration. |
sound/hda/controllers/Makefile |
Builds the Phytium HDA driver. |
sound/hda/controllers/intel.c |
Adds Glenfly PCI initialization. |
sound/hda/controllers/intel.h |
Defines Glenfly private state. |
sound/hda/controllers/phytium.c |
Implements the Phytium HDA controller. |
sound/hda/controllers/phytium.h |
Defines Phytium HDA private state. |
sound/hda/core/controller.c |
Adds CORB command retransmission. |
Review details
- Files reviewed: 31/31 changed files
- Comments generated: 21
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| obj-$(CONFIG_SPI_PHYTIUM_PLAT) += spi-phytium-plat.o | ||
| obj-$(CONFIG_SPI_PHYTIUM_PCI) += spi-phytium-pci.o | ||
| obj-$(CONFIG_SPI_PHYTIUM_QSPI) += spi-phytium-qspi.o | ||
| obj-$(CONFIG_SPI_PHYTIUM) += spi-phytium-dma.o |
| if (len > 16 && fts->dma_get_ddrdata) { | ||
| tx_addr = __virt_to_phys((u64)fts->tx); | ||
| if (!tx_addr) { | ||
| dev_err(&fts->master->dev, "tx address translation failed\n"); | ||
| return -1; | ||
| } | ||
| *(u64 *)&fts->msg->data[0] = tx_addr; |
|
|
||
| static struct platform_driver spi_phyt_driver = { | ||
| .probe = spi_phyt_probe, | ||
| .remove = spi_phyt_remove, |
| for (i = 0; qspi->fnum > i && i < PHYTIUM_QSPI_MAX_NORCHIP; i++) { | ||
| ret = phytium_qspi_flash_capacity_encode_new(qspi->flash[i].size, | ||
| &qspi->flash_cap, i); | ||
| if (ret) { | ||
| dev_err(dev, "Flash size is invalid.\n"); | ||
| goto probe_setup_failed; |
| fts->log = devm_ioremap(dev, fts->ddr_paddr, fts->log_size); | ||
|
|
||
| if (IS_ERR(fts->log)) { |
| if (fb_size < (4 + 16) * 1024 * 1024 + | ||
| 2 * GF_HDA_FB_STREAM_SIZE + 2 * BDL_SIZE) { |
| struct hda_ft *hda = container_of(chip, struct hda_ft, chip); | ||
|
|
||
| hda->substream = substream; | ||
| } |
| out_free: | ||
| if (bus->irq >= 0) { | ||
| free_irq(bus->irq, (void *)chip); | ||
| bus->irq = -1; | ||
| } | ||
| return err; |
| rirb_wp = snd_hdac_chip_readw(bus, RIRBWP); | ||
| arrived = (u8)(rirb_wp - prev_rirb_wp); | ||
| if (arrived) |
| %YAML 1.2 | ||
| --- | ||
| $id: http://devicetree.org/schemas/spi/phytium,qspi-nor.yaml# | ||
| $schema: http://devicetree.org/schemas/meta-schemas/core.yaml# |
663dbaa to
4c450b3
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Multiple blocking correctness issues affect command retries, suspend/resume, SPI transfers, QSPI probing, and ACPI partition parsing.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
sound/hda/common/controller.c:147
- This copies to an
ioremap_wc()mapping with ordinarymemcpy(). MMIO mappings must be accessed with I/O helpers; ordinary memory operations are not portable and can fault or omit required ordering on supported architectures. Usememcpy_toio()for the mapped framebuffer.
memcpy(gf_chip->diu_fb_stream_vaddr[stream_idx], substream->runtime->dma_area, substream->runtime->dma_bytes);
- Files reviewed: 31/31 changed files
- Comments generated: 15
- Review effort level: Balanced
| %YAML 1.2 | ||
| --- | ||
| $id: http://devicetree.org/schemas/spi/phytium,qspi-nor.yaml# | ||
| $schema: http://devicetree.org/schemas/meta-schemas/core.yaml# |
| acpi_id = acpi_match_device(parse_acpipart_match_table, dev); | ||
| if (dedicated && !acpi_id) | ||
| return 0; |
| if (len <= 16 || !fts->dma_get_ddrdata) | ||
| memcpy_byte(fts->rx, (void *)smem_rx, len); | ||
|
|
||
| fts->rx += len; | ||
| first = 0; |
| if (qspi->flash[i].size != qspi->flash[0].size) { | ||
| dev_err(dev, "Flashes are of different sizes.\n"); | ||
| ret = -EINVAL; | ||
| goto probe_setup_failed; |
| ret = phytium_qspi_flash_capacity_encode_new(qspi->flash[i].size, | ||
| &qspi->flash_cap, i); | ||
| if (ret) { | ||
| dev_err(dev, "Flash size is invalid.\n"); | ||
| goto probe_setup_failed; |
| struct resource *mem; | ||
| int ret; | ||
| int num_cs; | ||
| int global_cs = 1; |
| { | ||
| int ret; | ||
|
|
||
| spi_phyt_hw_init(&fts->master->dev, fts); |
| if (azx_dev->core.bdl.bytes <= BDL_SIZE) { | ||
| memcpy(gf_chip->diu_fb_bdl_vaddr[stream_idx], azx_dev->core.bdl.area, azx_dev->core.bdl.bytes); | ||
| } else { | ||
| memcpy(gf_chip->diu_fb_bdl_vaddr[stream_idx], azx_dev->core.bdl.area, BDL_SIZE); | ||
| } |
| if (substream && substream->runtime && | ||
| substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { | ||
| substream->runtime->status->state = | ||
| substream->runtime->status->suspended_state; | ||
| substream->ops->prepare(substream); |
| cmds_after = bus->rirb.cmds[addr]; | ||
| arrived = cmds_before - cmds_after; | ||
| if (arrived) |
4c450b3 to
ce4e5a8
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Standard QSPI operations fail, resume state is lost, and several timeout, resource, and error-propagation defects remain.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 31/31 changed files
- Comments generated: 8
- Review effort level: Balanced
| if (op->cmd.buswidth == 1 && | ||
| op->addr.buswidth == 1 && | ||
| op->data.buswidth == 1) |
| acpipart_none: | ||
| kfree(parts); | ||
| return ret; |
|
|
||
| config SPI_PHYTIUM | ||
| tristate | ||
| depends on ARCH_PHYTIUM |
| unsigned long long ms = 300000; | ||
| struct msg *msg = (struct msg *)fts->tx_shmem_addr; | ||
|
|
||
| ms = wait_for_completion_timeout(&fts->cmd_completion, msecs_to_jiffies(ms)); | ||
|
|
||
| if (ms == 0) { |
| flash_cap |= (qspi->fnum << QSPI_FLASH_CAP_NUM_SHIFT) & | ||
| QSPI_FLASH_CAP_NUM_MASK; | ||
|
|
||
| writel_relaxed(flash_cap, qspi->io_base + QSPI_FLASH_CAP_REG); |
| fts->tx = (void *)transfer->tx_buf; | ||
| fts->tx_end = fts->tx + transfer->len; | ||
| fts->rx = transfer->rx_buf; | ||
| fts->rx_end = fts->rx + transfer->len; | ||
| fts->len = transfer->len; |
|
|
||
| snd_hdac_stream_setup(azx_stream(azx_dev), false); | ||
|
|
||
| gf_setup_bdle(substream); |
| free_irq(bus->irq, (void *)chip); | ||
| bus->irq = -1; | ||
| } | ||
| chip->disabled = 1; |
ce4e5a8 to
1d3181d
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Confirmed interrupt races, unsafe QSPI writes, MMIO misuse, retry-accounting errors, and binding problems must be resolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
drivers/spi/spi-phytium-v2.c:518
- The IRQ is requested before
spi_master_set_devdata(master, fts)at line 546. Because this is a shared IRQ, the handler can run immediately and dereference a NULL controller drvdata pointer; set the drvdata before registering the handler.
ret = devm_request_irq(dev, fts->irq, spi_phyt_irq, IRQF_SHARED, fts->name, master);
drivers/spi/spi-phytium-qspi.c:574
- For a length not divisible by four, this emits a full final word whose unused bytes are zero. On NOR flash, programming those zero bits corrupts bytes immediately following the requested range. Preserve the neighboring bytes or pad unused lanes with the controller's documented no-program value (normally
0xff).
if (len & mask) {
addr = dst + (len & ~mask);
memcpy(tmp, buf + (len & ~mask), len & mask);
writel_relaxed(*(u32 *)(tmp), addr);
Documentation/devicetree/bindings/spi/phytium,qspi-nor.yaml:5
- This schema URI has an extra
/schemascomponent and cannot resolve to the Devicetree core meta-schema. Use the same canonical URI as the other binding added in this change.
$schema: http://devicetree.org/schemas/meta-schemas/core.yaml#
- Files reviewed: 31/31 changed files
- Comments generated: 14
- Review effort level: Balanced
| return PTR_ERR(fts->tx_shmem_addr); | ||
| } | ||
|
|
||
| fts->msg = (struct msg *)fts->tx_shmem_addr; |
| flash->cs = spi_get_chipselect(spi, 0); | ||
| flash->spi = spi; | ||
| qspi->fnum++; | ||
|
|
||
|
|
||
| if (spi->max_speed_hz) { | ||
| clk_div = DIV_ROUND_UP(qspi->clk_rate, spi->max_speed_hz); | ||
| flash->clk_div = phytium_spi_nor_clac_clk_div(clk_div); | ||
| if (flash->clk_div == 65535) { | ||
| dev_err(qspi->dev, "qspi maximum frequency setting is error.\n"); | ||
| return -EINVAL; | ||
| } | ||
| } else | ||
| flash->clk_div = PHYTIUM_QSPI_DEFAULT_SCK_SEL; |
| complete(&fts->cmd_completion); | ||
| writel_relaxed(0, fts->regfile + SPI_REGFILE_RV2AP_INTR_STATE); | ||
| writel_relaxed(0x10, fts->regfile + SPI_REGFILE_RV2AP_INT_CLEAN); | ||
|
|
||
| return IRQ_HANDLED; |
| struct device_node *mbox_np = | ||
| of_parse_phandle(cdev->of_node, "mboxes", a2p_rx_chan); | ||
|
|
||
| if (mbox_np) { | ||
| if (of_device_is_compatible(mbox_np, "phytium,mbox")) | ||
| cinfo->no_completion_irq = true; | ||
| of_node_put(mbox_np); | ||
| } |
| spi_phytium_show_msg(fts->msg); | ||
| reinit_completion(&fts->cmd_completion); | ||
| phytium_write_regfile(fts, SPI_REGFILE_AP2RV_INTR_STATE, 0x10); | ||
| spi_phytium_check_result(fts); |
| bus->irq = -1; | ||
| } | ||
|
|
||
| devm_iounmap(hddev, bus->remap_addr); |
| bus->rirb.cmds[addr] -= sent - arrived; | ||
| if (!arrived && bus->rirb.cmds[addr] < 1) | ||
| bus->rirb.cmds[addr] = 1; |
| static SIMPLE_DEV_PM_OPS(spi_phyt_pm_ops, spi_phyt_suspend, spi_phyt_resume); | ||
|
|
||
| static const struct of_device_id spi_phyt_of_match[] = { | ||
| { .compatible = "phytium,spi-2.0", .data = (void *)0 }, |
| struct mtd_info; | ||
| struct device_node; | ||
| struct acpi_device; | ||
| struct hwnode_handle; |
| } | ||
|
|
||
| static const struct of_device_id hda_ft_of_match[] = { | ||
| { .compatible = "phytium,hda" }, |
1d3181d to
a3ac4c7
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Firmware-response handling, SPI client-data access, and QSPI partial writes contain correctness and data-corruption issues.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
drivers/spi/spi-phytium-qspi.c:573
- The leading-fragment write starts at the unaligned
dstand then advances it by four although onlyheadinput bytes were consumed. For example, an offset of 1 skips flash byte 4 before the main loop. Align the MMIO write down, place the payload after the leading padding, and advance byhead.
if (head > len)
head = len;
memcpy(tmp, buf, head);
writel_relaxed(*(u32 *)tmp, dst);
buf += head;
dst += 4;
drivers/spi/spi-phytium-qspi.c:589
- For an unaligned offset,
lenwas reduced by the leading fragment, so this reports fewer bytes than were actually written (and can return zero after a successful short write). The SPI-mem caller treats this as a short write and may retry at the wrong offset; preserve and return the original requested length.
return len;
- Files reviewed: 32/32 changed files
- Comments generated: 7
- Review effort level: Balanced
| memcpy_fromio(&fts->msg_buf, fts->msg, sizeof(struct msg)); | ||
| ms = wait_for_completion_timeout(&fts->cmd_completion, | ||
| msecs_to_jiffies(SPI_MASTER_TIMEOUT)); | ||
|
|
||
| if (ms == 0) { | ||
| dev_err(&fts->master->dev, "SPI controller timed out\n"); | ||
| return -1; | ||
| } |
| void __iomem *addr; | ||
| int i; | ||
| size_t mask = 0x03; | ||
| u_char tmp[4] = {0}; |
| struct spi_mem *mem = spi_get_drvdata(spi); | ||
| struct spi_nor *nor = NULL; | ||
| int ret; | ||
|
|
||
| if (mem) | ||
| nor = spi_mem_get_drvdata(mem); |
| if ((*(u8 *)fts->tx == SPINOR_OP_CHIP_ERASE) && (fts->spi_write_flag == 1) && | ||
| fts->flash_read == 0 && fts->flash_erase == 0) { | ||
| ret = spi_phytium_flash_erase(fts, spi_get_chipselect(spi, 0), | ||
| transfer->bits_per_word, | ||
| spi->mode, chip->tmode, 3, SPINOR_OP_CHIP_ERASE); | ||
| fts->spi_write_flag = 0; | ||
| fts->flash_erase = 2; | ||
| } |
| fts->runtimes++; | ||
| } | ||
|
|
||
| mod_timer(&fts->timer, jiffies + msecs_to_jiffies(10)); |
| if (hw_pos == appl_pos) { | ||
| memcpy_toio(gf_chip->diu_fb_stream_vaddr[stream_idx], substream->runtime->dma_area, substream->runtime->dma_bytes); | ||
| } |
| %YAML 1.2 | ||
| --- | ||
| $id: http://devicetree.org/schemas/spi/phytium,qspi-nor.yaml# | ||
| $schema: http://devicetree.org/schemas/meta-schemas/core.yaml# |
a3ac4c7 to
8c00eec
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved DMA, QSPI alignment, initialization, resource-lifetime, GPIO chip-select, and command-retry defects can cause corruption or failed operation.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
drivers/spi/spi-phytium-qspi.c:803
- The controller probe cannot rely on the child SPI-NOR driver already being bound.
spi_register_controller()creates the child device, but its driver may be modular or return-EPROBE_DEFER; thenspi_get_drvdata()is NULL, the size remains zero, and the capacity encoder below rejects it, causing the parent controller probe to fail. Capacity setup needs to happen when the flash size is actually available (for example from the dirmap setup path), rather than inspecting child private data during parent probe.
mem = spi_get_drvdata(qspi->flash[i].spi);
if (mem) {
nor = spi_mem_get_drvdata(mem);
if (nor)
qspi->flash[i].size = nor->mtd.size;
Documentation/devicetree/bindings/spi/phytium,qspi-nor.yaml:5
- This schema URI has an extra
/schemascomponent and does not resolve to the Devicetree core meta-schema. Use the same canonical URI as the other new bindings so schema validation can load it.
$schema: http://devicetree.org/schemas/meta-schemas/core.yaml#
sound/hda/core/controller.c:299
- The final retransmission is queued on the last loop iteration and then the code immediately collapses all outstanding counter references to one without giving that copy an observation window. If two delayed copies subsequently respond, the first reaches zero and the next response can be charged to a following verb on the same codec—the corruption the drain is intended to prevent. Structure the loop so every transmitted copy, including the last retry, is followed by the response check before counters are adjusted.
- Files reviewed: 32/32 changed files
- Comments generated: 8
- Review effort level: Balanced
| ms = wait_for_completion_timeout(&fts->dma_completion, | ||
| msecs_to_jiffies(ms)); | ||
|
|
||
| if (ms == 0) { | ||
| dev_err(&fts->master->cur_msg->spi->dev, | ||
| "DMA transaction timed out\n"); | ||
| return -ETIMEDOUT; | ||
| } | ||
|
|
||
| return 0; |
| if (head > len) | ||
| head = len; | ||
| memcpy(tmp, buf, head); | ||
| writel_relaxed(*(u32 *)tmp, dst); |
| //write cache data to flash | ||
| writel_relaxed(QSPI_FLUSH_EN, qspi->io_base + QSPI_FLUSH_REG); | ||
|
|
||
| return len; |
| - const: phytium,spi | ||
| - const: phytium,spi-2.0 | ||
| description: Phytium SPI controller v2.0 interface |
| for (i = 0; i < n && i < fts->num_cs; i++) { | ||
| gpiod = devm_gpiod_get_index_optional(&pdev->dev, "cs", i, | ||
| GPIOD_OUT_LOW); |
|
|
||
| WARN_ON(fts == NULL); | ||
|
|
||
| master = spi_alloc_host(dev, 0); |
| fts->dma_ops->dma_exit(fts); | ||
| spi_shutdown_chip(fts); | ||
|
|
||
| free_irq(fts->irq, fts->master); |
| extern void spi_phytium_set_cmd8(struct phytium_spi *fts, u16 sub_cmd, u8 data); | ||
| extern void spi_phytium_set_cmd16(struct phytium_spi *fts, u16 sub_cmd, u16 data); | ||
| extern void spi_phytium_set_cmd32(struct phytium_spi *fts, u16 sub_cmd, u32 data); |
8c00eec to
ba90779
Compare
Add binding documentation for Phytium SPI controller. Signed-off-by: yuanxia <yuanxia2073@phytium.com.cn> Signed-off-by: Chen Baozi <chenbaozi@phytium.com.cn> Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn> Link: deepin-community#136 (cherry picked from commit 23b8ee8) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Add support for the Phytium SPI controller driver. Signed-off-by: yuanxia <yuanxia2073@phytium.com.cn> Signed-off-by: Zhang Yiqun <zhangyiqun@phytium.com.cn> Signed-off-by: Peng Min <pengmin1540@phytium.com.cn> Signed-off-by: Chen Baozi <chenbaozi@phytium.com.cn> Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn> Link: deepin-community#136 [ Wentao Guan: rename spi_controller_get_devdata from spi_master_get_devdata,struct spi_controller from struct spi_master ] [ Wentao Guan: XXXX ] (cherry picked from commit 27b76db) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The Glenfly frame buffer and BDL mappings are ioremap_wc() MMIO regions accessed through void __iomem * pointers, but the common controller code used plain memcpy() to write into them and, for the BDL, read back previously written entries directly from the WC mapping. This is not a portable MMIO access pattern — WC reads can return stale data on some architectures. Build the rewritten BDL in a normal-memory stack buffer first, then flush it to the WC mapping with memcpy_toio(). Replace the plain memcpy() calls in gf_pre_trigger() and gf_update_stream() with memcpy_toio() as well. Fixes: 86858d4 ("add gf hdaudio 001 patch in deepin kernel 6.6") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
…symbol The front-end symbols SPI_PHYTIUM_PLAT and SPI_PHYTIUM_PCI allow COMPILE_TEST on non-Phytium architectures but select SPI_PHYTIUM, whose direct "depends on ARCH_PHYTIUM" is then unmet: Kconfig reports an unmet direct dependency and the compile-test paths never build the core. Follow the in-tree convention (e.g. SPI_ROCKCHIP_spi selection chains) of leaving architecture gating to the user-visible front-end symbols and dropping the depends from the hidden helper symbol. Fixes: caf2f8f ("arm64: spi: add Phytium SPI controller support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
…sfers Two issues in the V2 SPI adapter: - check_result() waited for the firmware response with a hard-coded 300000 ms timeout, so a single unavailable RV endpoint stalled device probing or an SPI operation for five minutes. Use the already defined SPI_MASTER_TIMEOUT (8 ms), matching how long a healthy AP-to-RV round trip is expected to take. - spi_phyt_transfer_one() accepted transfers with both buffers NULL; the tx/rx end pointers were then constructed from NULL arithmetic and the function fell through to a return of an uninitialized ret, reporting an arbitrary result without clocking anything. Reject this unsupported transfer shape with -EOPNOTSUPP up front. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Fixes: 5e49cfb ("spi-v2: phytium: Add support for full-duplex transmission mode") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The direct-mapping branch computed flash capacity into a local variable, wrote it to the register and dropped it, while the nodirmap branch caches its value in qspi->flash_cap. The resume path rewrites the capacity register from qspi->flash_cap, so after a suspend/resume cycle in dirmap mode the zero-initialized cache zeroed out the flash capacity the probe had programmed. Cache the programmed value in the dirmap branch as well. Fixes: 9f2e218 ("arm64: spi: Phytium-qspi: Add support for Phytium QSPI controller") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
spi-phytium-plat-v2.c casts the devm_ioremap_resource() mapping of the shared memory to a plain struct msg *; the common code then uses memset, plain dereferences and ordinary copies on it. Those accesses are not valid for an ioremap'd resource and can violate MMIO access width/order requirements on Phytium architectures. Introduce a normal-memory shadow buffer (struct msg msg_buf) alongside the __iomem pointer, populate it with ordinary field writes, and flush it to the mapping with memcpy_toio() at each notification boundary. Read the response status back with memcpy_fromio(). Convert the secondary message slot in spi_phytium_write_pre() to the same pattern. Replace the smem_tx/smem_rx u64 arithmetic with __iomem pointer arithmetic and use memcpy_toio()/memcpy_fromio() for those transfers as well. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
phytium_qspi_setup() committed flash->spi, flash->cs and fnum++ before validating the clock divider, so a setup that later returned -EINVAL left the controller with a stale flash entry and an inflated flash count. The post-registration capacity scan then dereferenced this rejected entry. Validate the divider first and only commit flash->spi, flash->cs and fnum when the slot was previously unset, making setup idempotent. Fixes: 9f2e218 ("arm64: spi: Phytium-qspi: Add support for Phytium QSPI controller") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The IRQ handler was registered with IRQF_SHARED but unconditionally completed the command without checking whether this controller raised the interrupt; an interrupt from another device could falsely complete an in-flight SPI command. Acknowledgement also happened after complete(), so a waiter on another CPU could submit a new command before the old status was cleared. Read the RV2AP interrupt state register and return IRQ_NONE when not ours; acknowledge before calling complete() so the old status is cleared first. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
spi_phytium_default() discarded the timeout/error from spi_phytium_check_result(), so spi_phyt_hw_init() — and therefore spi_phyt_add_host() — continued and registered a controller even when the backing RV firmware never responded, exposing a nonfunctional device. Return the status from spi_phytium_default(), propagate it through spi_phyt_hw_init() (now returning int), and abort probe or resume when the initial command fails. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The direct-mapping write path rejected every non-4-byte-aligned offset with -EINVAL, but the SPI-mem dirmap API accepts byte-granular offsets and SPI NOR writes can begin at an arbitrary address, so otherwise valid MTD writes failed. Handle an unaligned leading fragment by padding it to a 4-byte word with non-programming 0xff bytes before the aligned word loop. Fixes: 9f2e218 ("arm64: spi: Phytium-qspi: Add support for Phytium QSPI controller") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
azx_irq_pending_work() had two issues in the pending-IRQ workaround:
- A negative azx_position_ok() result ("too early") reset the aggregate
pending counter to zero, discarding retries already requested by
earlier streams in the same loop iteration. Later changed to
pending++, but that still retried indefinitely.
- The retry loop used udelay(1000) in process context, busy-waiting
a workqueue CPU.
Follow the Intel implementation: treat a negative result as terminal
for that stream in the current round (leave the flag set and let the
next interrupt reschedule), and sleep between rounds with msleep(1)
instead of busy-waiting.
Fixes: 8da93e4 ("hda: phytium: Add Phytium hda driver support")
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
hda_ft_probe() passed the return value of platform_get_irq() directly to request_irq() without checking for errors. A negative return — notably -EPROBE_DEFER when the interrupt provider has not yet probed — was interpreted as an IRQ number, the request failed, and the device was never reprobed. Check for a negative IRQ and propagate it, letting -EPROBE_DEFER reach the driver core for a deferred retry. Fixes: 8da93e4 ("hda: phytium: Add Phytium hda driver support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The spi-phytium-plat-v2.c driver declares the "phytium,spi-2.0" compatible string but the Phytium SPI binding only accepted "phytium,spi", so firmware using the v2.0 interface could not be schema-validated. Add it as an accepted value. The Phytium HDA controller (phytium,hda) has no binding at all, so firmware cannot be validated against its register and interrupt requirements. Add a new binding under Documentation/devicetree/bindings/sound/phytium,hda.yaml. Fixes: caf2f8f ("arm64: spi: add Phytium SPI controller support") Fixes: 8da93e4 ("hda: phytium: Add Phytium hda driver support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The forward declaration for the fwnode_handle type added to struct mtd_partition was misspelled as "struct hwnode_handle;", creating an unrelated unused struct tag instead of declaring the type that mtd_partition.fwnode actually references. Fixes: 7f4fb2e ("arm64: phytium: UEFI mode acpi table support for qspi/spi driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
spi_phyt_transfer_one() read spi_get_drvdata(spi) and treated the result as a struct spi_mem *, but that field belongs to the client driver: spi-mem drivers store a struct spi_mem there, while ordinary SPI clients such as the MCP251x CAN controller also supported by this driver store their own private structure. For a non-spi-nor client the pointer was then dereferenced as spi_mem/spi_nor, crashing during the first transfer. Only interpret the drvdata as a struct spi_mem when the bound client driver is actually "spi-nor". Fixes: b127bad ("spi-v2: phytium: Adapt the mcp251x device") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The V2 files were never actually compiled: SPI_PHYTIUM_V2 and SPI_PHYTIUM_PLAT_V2 depend on ARCH_PHYTIUM, which is unset on every build of this tree, so the Kconfig symbols were silently dropped and the stale pre-6.x API usage went unnoticed. Adapt the code so it builds against 6.18: - s/spi_master/spi_controller/ for the alloc, devdata, register and put helpers (spi_alloc_host, spi_controller_get/set_devdata, devm_spi_register_controller, spi_controller_put) and spi->master -> spi->controller - from_timer() no longer exists; use timer_container_of(), and del_timer_sync() is now timer_delete_sync() - the legacy of_get_named_gpio()/devm_gpio_request() OF path is gone; request the chip-select lines through the gpiod API for both DT and ACPI firmware, matching what the SPI core expects, and drop the now unused fts->cs array - add missing prototypes by making the file-local helpers static and remove the unused ones (spi_phytium_data_subid, spi_phyt_enable_debug) - drop the dead asm/memory.h and linux/of_gpio.h includes - allow COMPILE_TEST for SPI_PHYTIUM_PLAT_V2 so the files keep compiling on other architectures Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
After issuing SPINOR_OP_CHIP_ERASE to the firmware, execution fell through to the generic TX path, which sent the same opcode a second time — a duplicate flash operation. The return value of spi_phytium_flash_erase() was also ignored and the flash_erase state was committed even on failure. Return right after the erase command and only update the state flags on success, propagating the error otherwise. Fixes: b127bad ("spi-v2: phytium: Adapt the mcp251x device") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The alive watchdog timer handler rearmed itself unconditionally every 10 ms even though alive_enabled defaults to false, causing 100 unnecessary wakeups per second per controller indefinitely. The add_host and resume paths also armed the timer unconditionally. Rearm only while alive monitoring is enabled, and start the timer from the sysfs enable path when alive monitoring transitions to enabled. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
When hw_pos == appl_pos, gf_update_stream() copied the entire PCM buffer — up to 7 MiB — to the framebuffer MMIO mapping. The function runs from the PCM pointer callback, which can be invoked from the period/IRQ path, so a caught-up or underrun stream caused extreme interrupt latency and repeatedly copied an empty buffer. Drop the full-copy branch: the pointer callback now only moves the newly committed range (appl_pos advance), and the full refresh remains in gf_pre_trigger() when the stream starts. Fixes: 86858d4 ("add gf hdaudio 001 patch in deepin kernel 6.6") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The DMA completion wait returned success even when the controller error IRQ had already set cur_msg->status to -EIO via phytium_spi_check_status(). The chunked transfer path then submitted another DMA chunk after the controller was reset, corrupting state. Check cur_msg->status after the completion fires and propagate the error so the transfer stops and handle_err terminates outstanding DMA. Fixes: caf2f8f ("arm64: spi: add Phytium SPI controller support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The v2 probe unconditionally requires resource 0 (register file) and resource 1 (shared memory), but the schema allowed a single reg range for phytium,spi-2.0 — a v2 DT with one range validated and then always failed probing. Add a per-compatible conditional: require exactly two reg ranges for phytium,spi-2.0, keeping one for the v1 compatible. Fixes: caf2f8f ("arm64: spi: add Phytium SPI controller support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
spi_phyt_add_host() allocated the controller with spi_alloc_host() (non-devm) but registered it with devm_spi_register_controller(). The devres cleanup only unregisters the controller; it does not drop the initial reference taken by the allocation, so every successful unbind leaked the controller. The managed registration also ordered teardown wrongly: the devres unregister action only runs after the platform .remove callback has returned, but spi_phyt_remove_host() shuts the chip down inside .remove — leaving child devices and the transfer queue registered against hardware that is already disabled. Switch to devm_spi_alloc_host() so the initial reference is managed, register explicitly with spi_register_controller(), and make spi_phyt_remove_host() unregister the controller before stopping the hardware, matching the V1 driver. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
phytium_spi_add_host() allocates the controller with spi_alloc_host(), which takes an initial reference, but phytium_spi_remove_host() only calls spi_unregister_controller(). That function does device_del() without put_device(), so the initial reference is never released and the controller allocation leaks on every unbind. Add spi_controller_put() after spi_unregister_controller() to drop the reference. Fixes: caf2f8f ("arm64: spi: add Phytium SPI controller support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
spi_phytium_set_cmd8/16/32() discarded the return value of spi_phytium_check_result(), so their setup callers returned success even when a firmware command timed out or reported an error, leaving the controller partially configured. Change these helpers to return int and propagate the check_result status everywhere: - spi_phyt_setup() aborts on the first failed command (chip disable, clock setting, DATA_WIDTH/MODE/TMOD, final chip enable); - the spi_phyt_enable_chip()/set_clk()/dma_reset()/global_cs() wrappers return int instead of discarding the result; - spi_phyt_resume_host() propagates failures from the chip disable, clock setting and re-enable sequence. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
…rate phytium_spi_dma_wait_rx_done() computed the poll delay as 4U * NSEC_PER_SEC / fts->max_freq * nents without guarding the division. fts->max_freq is 0 when the clock is unconfigured or the ACPI "spi-clock" property is absent, so the FIFO drain on the DMA error-recovery path divided by zero and crashed. Use max_t(u32, fts->max_freq, 1) as the divisor, mirroring the guard already present in phytium_spi_dma_wait_tx_done(). Fixes: 3674931 ("arm64: spi: Phytium: Adapt SPI driver to use DDMA interface") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Two stack buffer overflows in the firmware command helpers: - spi_phytium_flash_erase() copied len bytes (the full remaining transfer length) into cmd_addr[1..7], which holds only 7 bytes, and then read len + 1 bytes back from the 8-byte buffer, past its end. A malformed or oversized client transfer longer than 7 bytes corrupted the stack. - spi_phytium_flash_write() copied fts->len bytes into cmd_addr[2..7], 6 bytes of space, with no bound. cmd_addr[0] also assigned the size_t length to a u8 byte, silently truncating it. Cap the copies to the buffer space in both functions and make the u8 length conversion explicit. Also fix the unaligned u64 dereference in memcpy_byte(): its callers pass &cmd_addr[1]/&cmd_addr[2], which are not 8-byte aligned; use get_unaligned()/put_unaligned() so the helper is safe on strict-alignment architectures. Fixes: b4cb017 ("spi-v2: phytium: Add the debug log function to the driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The capacity registers need each flash's size, which comes from the spi-nor driver bound to the child. When MTD_SPI_NOR is a module that has not loaded yet, the children exist but no driver is bound, so the sizes stay zero and the capacity encoding cannot be programmed. Register a bus notifier and program the capacity when spi-nor binds. SPI children are parented by the controller device, so filter notifications against &qspi->ctrl->dev rather than the platform device. This keeps the controller independent of spi-nor module load order. Fixes: 9f2e218 ("arm64: spi: Phytium-qspi: Add support for Phytium QSPI controller") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
…ware down phytium_qspi_remove() disabled the clock first, while the controller was registered through devm_spi_register_controller(): the devres unregister action only runs after the platform .remove callback returns, so child devices and the transfer queue stayed registered against dead hardware for that window. The deferred-probe error path added for spi-nor load ordering has the same inverted teardown. Register explicitly with spi_register_controller() and unregister the controller before disabling the clock, both in .remove and on the post-registration failure paths. Fixes: 9f2e218 ("arm64: spi: Phytium-qspi: Add support for Phytium QSPI controller") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The parser treated any child of the flash device as proof that a dedicated partition layout was present, then iterated only the master's direct children. A conventional "partitions" container node therefore failed parsing: it has no offset/length of its own, so in dedicated mode it triggered -EINVAL, and its partition children were never visited. An unrelated child node (e.g. a GPIO consumer) likewise switched the parser into strict dedicated mode by mistake. Descend into a "partitions" subnode when present, mirroring the OF parser: the container enables dedicated mode and its children are the partitions. Without the container, keep parsing the direct subnodes leniently. Fixes: 7f4fb2e ("arm64: phytium: UEFI mode acpi table support for qspi/spi driver") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
The driver provides runtime suspend and resume callbacks, but never sets AZX_DCAPS_PM_RUNTIME or enables runtime PM. Consequently the callbacks are unreachable and the controller remains active even after all codecs enter D3. Enable runtime PM and hold the controller active while the asynchronous probe accesses its registers. Allow codecs to use the configured power-save delay so the parent controller can stop its command engine and place the link in reset once every codec is idle. Use the same callbacks for system sleep and balance runtime PM during probe failure, removal and shutdown. Also quiesce and synchronize the deferred stream IRQ work before entering link reset. Fixes: 8da93e4 ("hda: phytium: Add Phytium hda driver support") Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
54b7cf3 to
3a83132
Compare
No description provided.