From: Álvaro Fernández Rojas Date: Wed, 3 Jul 2024 18:30:59 +0000 (+0200) Subject: bcm27xx: update to latest RPi patches X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=e74ead2249b3d6dcae466c5f864fc73f46c9dd6c;p=openwrt%2Fstaging%2Fansuel.git bcm27xx: update to latest RPi patches The patches were generated from the RPi repo with the following command: git format-patch v6.6.36..rpi-6.6.y Signed-off-by: Álvaro Fernández Rojas --- diff --git a/target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch b/target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch deleted file mode 100644 index d77c7eaf1c..0000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0536-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch +++ /dev/null @@ -1,328 +0,0 @@ -From c6cd3e6878e32548ea90c4160c534e952221c194 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 28 Apr 2021 17:46:01 +0100 -Subject: [PATCH 0536/1085] dmaengine: dw-axi-dmac: Fixes for RP1 - -Don't assume that DMA addresses of devices are the same as their -physical addresses - convert correctly. - -The CFG2 register layout is used when there are more than 8 channels, -but also when configured for more than 16 target peripheral devices -because the index of the handshake signal has to be made wider. - -Reset the DMAC on probe - -The driver goes to the trouble of tracking when transfers have been -paused, but then doesn't report that state when queried. - -Not having APB registers is not an error - for most use cases it's -not even of interest, it's expected. Demote the message to debug level, -which is disabled by default. - -Each channel has a descriptor pool, which is shared between transfers. -It is unsafe to treat the total number of descriptors allocated from a -pool as the number allocated to a specific transfer; doing so leads -to releasing buffers that shouldn't be released and walking off the -ends of descriptor lists. Instead, give each transfer descriptor its -own count. - -Support partial transfers: -Some use cases involve streaming from a device where the transfer only -proceeds when the device's FIFO occupancy exceeds a certain threshold. -In such cases (e.g. when pulling data from a UART) it is important to -know how much data has been transferred so far, in order that remaining -bytes can be read from the FIFO directly by software. - -Add the necessary code to provide this "residue" value with a finer, -sub-transfer granularity. - -In order to prevent the occasional byte getting stuck in the DMA -controller's internal buffers, restrict the destination memory width -to the source register width. - -Signed-off-by: Phil Elwell ---- - .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 132 +++++++++++++++--- - drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + - 2 files changed, 113 insertions(+), 20 deletions(-) - ---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c -+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -84,6 +85,17 @@ axi_chan_iowrite64(struct axi_dma_chan * - iowrite32(upper_32_bits(val), chan->chan_regs + reg + 4); - } - -+static inline u64 -+axi_chan_ioread64(struct axi_dma_chan *chan, u32 reg) -+{ -+ /* -+ * We split one 64 bit read into two 32 bit reads as some HW doesn't -+ * support 64 bit access. -+ */ -+ return ((u64)ioread32(chan->chan_regs + reg + 4) << 32) + -+ ioread32(chan->chan_regs + reg); -+} -+ - static inline void axi_chan_config_write(struct axi_dma_chan *chan, - struct axi_dma_chan_config *config) - { -@@ -220,7 +232,18 @@ static void axi_dma_hw_init(struct axi_d - { - int ret; - u32 i; -+ int retries = 1000; - -+ axi_dma_iowrite32(chip, DMAC_RESET, 1); -+ while (axi_dma_ioread32(chip, DMAC_RESET)) { -+ retries--; -+ if (!retries) { -+ dev_err(chip->dev, "%s: DMAC failed to reset\n", -+ __func__); -+ return; -+ } -+ cpu_relax(); -+ } - for (i = 0; i < chip->dw->hdata->nr_channels; i++) { - axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL); - axi_chan_disable(&chip->dw->chan[i]); -@@ -283,7 +306,7 @@ static struct axi_dma_lli *axi_desc_get( - static void axi_desc_put(struct axi_dma_desc *desc) - { - struct axi_dma_chan *chan = desc->chan; -- int count = desc->nr_hw_descs; -+ u32 count = desc->hw_desc_count; - struct axi_dma_hw_desc *hw_desc; - int descs_put; - -@@ -305,6 +328,48 @@ static void vchan_desc_put(struct virt_d - axi_desc_put(vd_to_axi_desc(vdesc)); - } - -+static u32 axi_dma_desc_src_pos(struct axi_dma_desc *desc, dma_addr_t addr) -+{ -+ unsigned int idx = 0; -+ u32 pos = 0; -+ -+ while (pos < desc->length) { -+ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++]; -+ u32 len = hw_desc->len; -+ dma_addr_t start = le64_to_cpu(hw_desc->lli->sar); -+ -+ if (addr >= start && addr <= (start + len)) { -+ pos += addr - start; -+ break; -+ } -+ -+ pos += len; -+ } -+ -+ return pos; -+} -+ -+static u32 axi_dma_desc_dst_pos(struct axi_dma_desc *desc, dma_addr_t addr) -+{ -+ unsigned int idx = 0; -+ u32 pos = 0; -+ -+ while (pos < desc->length) { -+ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++]; -+ u32 len = hw_desc->len; -+ dma_addr_t start = le64_to_cpu(hw_desc->lli->dar); -+ -+ if (addr >= start && addr <= (start + len)) { -+ pos += addr - start; -+ break; -+ } -+ -+ pos += len; -+ } -+ -+ return pos; -+} -+ - static enum dma_status - dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, - struct dma_tx_state *txstate) -@@ -314,10 +379,7 @@ dma_chan_tx_status(struct dma_chan *dcha - enum dma_status status; - u32 completed_length; - unsigned long flags; -- u32 completed_blocks; - size_t bytes = 0; -- u32 length; -- u32 len; - - status = dma_cookie_status(dchan, cookie, txstate); - if (status == DMA_COMPLETE || !txstate) -@@ -326,16 +388,31 @@ dma_chan_tx_status(struct dma_chan *dcha - spin_lock_irqsave(&chan->vc.lock, flags); - - vdesc = vchan_find_desc(&chan->vc, cookie); -- if (vdesc) { -- length = vd_to_axi_desc(vdesc)->length; -- completed_blocks = vd_to_axi_desc(vdesc)->completed_blocks; -- len = vd_to_axi_desc(vdesc)->hw_desc[0].len; -- completed_length = completed_blocks * len; -- bytes = length - completed_length; -+ if (vdesc && vdesc == vchan_next_desc(&chan->vc)) { -+ /* This descriptor is in-progress */ -+ struct axi_dma_desc *desc = vd_to_axi_desc(vdesc); -+ dma_addr_t addr; -+ -+ if (chan->direction == DMA_MEM_TO_DEV) { -+ addr = axi_chan_ioread64(chan, CH_SAR); -+ completed_length = axi_dma_desc_src_pos(desc, addr); -+ } else if (chan->direction == DMA_DEV_TO_MEM) { -+ addr = axi_chan_ioread64(chan, CH_DAR); -+ completed_length = axi_dma_desc_dst_pos(desc, addr); -+ } else { -+ completed_length = 0; -+ } -+ bytes = desc->length - completed_length; -+ } else if (vdesc) { -+ /* Still in the queue so not started */ -+ bytes = vd_to_axi_desc(vdesc)->length; - } - -- spin_unlock_irqrestore(&chan->vc.lock, flags); -+ if (chan->is_paused && status == DMA_IN_PROGRESS) -+ status = DMA_PAUSED; -+ - dma_set_residue(txstate, bytes); -+ spin_unlock_irqrestore(&chan->vc.lock, flags); - - return status; - } -@@ -523,7 +600,7 @@ static void dw_axi_dma_set_hw_channel(st - unsigned long reg_value, val; - - if (!chip->apb_regs) { -- dev_err(chip->dev, "apb_regs not initialized\n"); -+ dev_dbg(chip->dev, "apb_regs not initialized\n"); - return; - } - -@@ -627,18 +704,25 @@ static int dw_axi_dma_set_hw_desc(struct - switch (chan->direction) { - case DMA_MEM_TO_DEV: - reg_width = __ffs(chan->config.dst_addr_width); -- device_addr = chan->config.dst_addr; -+ device_addr = phys_to_dma(chan->chip->dev, chan->config.dst_addr); - ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS | - mem_width << CH_CTL_L_SRC_WIDTH_POS | -+ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_DST_MSIZE_POS | -+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS | - DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS | - DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS; - block_ts = len >> mem_width; - break; - case DMA_DEV_TO_MEM: - reg_width = __ffs(chan->config.src_addr_width); -- device_addr = chan->config.src_addr; -+ /* Prevent partial access units getting lost */ -+ if (mem_width > reg_width) -+ mem_width = reg_width; -+ device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr); - ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS | - mem_width << CH_CTL_L_DST_WIDTH_POS | -+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | -+ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_SRC_MSIZE_POS | - DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS | - DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS; - block_ts = len >> reg_width; -@@ -674,9 +758,6 @@ static int dw_axi_dma_set_hw_desc(struct - } - - hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1); -- -- ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | -- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS; - hw_desc->lli->ctl_lo = cpu_to_le32(ctllo); - - set_desc_src_master(hw_desc); -@@ -771,6 +852,8 @@ dw_axi_dma_chan_prep_cyclic(struct dma_c - src_addr += segment_len; - } - -+ desc->hw_desc_count = total_segments; -+ - llp = desc->hw_desc[0].llp; - - /* Managed transfer list */ -@@ -850,6 +933,8 @@ dw_axi_dma_chan_prep_slave_sg(struct dma - } while (len >= segment_len); - } - -+ desc->hw_desc_count = loop; -+ - /* Set end-of-link to the last link descriptor of list */ - set_desc_last(&desc->hw_desc[num_sgs - 1]); - -@@ -957,6 +1042,8 @@ dma_chan_prep_dma_memcpy(struct dma_chan - num++; - } - -+ desc->hw_desc_count = num; -+ - /* Set end-of-link to the last link descriptor of list */ - set_desc_last(&desc->hw_desc[num - 1]); - /* Managed transfer list */ -@@ -1005,7 +1092,7 @@ static void axi_chan_dump_lli(struct axi - static void axi_chan_list_dump_lli(struct axi_dma_chan *chan, - struct axi_dma_desc *desc_head) - { -- int count = atomic_read(&chan->descs_allocated); -+ u32 count = desc_head->hw_desc_count; - int i; - - for (i = 0; i < count; i++) -@@ -1048,11 +1135,11 @@ out: - - static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan) - { -- int count = atomic_read(&chan->descs_allocated); - struct axi_dma_hw_desc *hw_desc; - struct axi_dma_desc *desc; - struct virt_dma_desc *vd; - unsigned long flags; -+ u32 count; - u64 llp; - int i; - -@@ -1074,6 +1161,7 @@ static void axi_chan_block_xfer_complete - if (chan->cyclic) { - desc = vd_to_axi_desc(vd); - if (desc) { -+ count = desc->hw_desc_count; - llp = lo_hi_readq(chan->chan_regs + CH_LLP); - for (i = 0; i < count; i++) { - hw_desc = &desc->hw_desc[i]; -@@ -1323,6 +1411,10 @@ static int parse_device_properties(struc - - chip->dw->hdata->nr_masters = tmp; - -+ ret = device_property_read_u32(dev, "snps,dma-targets", &tmp); -+ if (!ret && tmp > 16) -+ chip->dw->hdata->use_cfg2 = true; -+ - ret = device_property_read_u32(dev, "snps,data-width", &tmp); - if (ret) - return ret; ---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h -+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h -@@ -101,6 +101,7 @@ struct axi_dma_desc { - - struct virt_dma_desc vd; - struct axi_dma_chan *chan; -+ u32 hw_desc_count; - u32 completed_blocks; - u32 length; - u32 period_len; diff --git a/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch b/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch index 20867f81e7..ac6a07f16e 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0967-dmaengine-dw-axi-dmac-Fix-a-non-atomic-update.patch @@ -30,7 +30,7 @@ Signed-off-by: Phil Elwell --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c -@@ -466,8 +466,6 @@ static void axi_chan_block_xfer_start(st +@@ -389,8 +389,6 @@ static void axi_chan_block_xfer_start(st return; } diff --git a/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch b/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch index 4eace2a2e2..d7d4ca6172 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1047-dw-axi-dmac-platform-Avoid-trampling-with-zero-lengt.patch @@ -22,7 +22,7 @@ Signed-off-by: Dom Cobley --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c -@@ -917,6 +917,9 @@ dw_axi_dma_chan_prep_slave_sg(struct dma +@@ -834,6 +834,9 @@ dw_axi_dma_chan_prep_slave_sg(struct dma mem = sg_dma_address(sg); len = sg_dma_len(sg); num_segments = DIV_ROUND_UP(sg_dma_len(sg), axi_block_len); diff --git a/target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch b/target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch new file mode 100644 index 0000000000..f521711977 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1133-drivers-mmc-sdhci-brcmstb-improve-bcm2712-card-remov.patch @@ -0,0 +1,52 @@ +From 5c0f94088e0694220a2f0d8ad6e8216b50a80f2e Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Thu, 13 Jun 2024 15:01:02 +0100 +Subject: [PATCH 1133/1145] drivers: mmc: sdhci-brcmstb: improve bcm2712 card + removal handling + +If the controller is being reset, then the CQE needs to be reset as well. + +For removable cards, CQHCI_SSC1 must specify a polling mode (CBC=0) +otherwise it's possible that the controller stops emitting periodic +CMD13s on card removal, without raising an error status interrupt. + +Signed-off-by: Jonathan Bell +--- + drivers/mmc/host/sdhci-brcmstb.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/sdhci-brcmstb.c ++++ b/drivers/mmc/host/sdhci-brcmstb.c +@@ -365,8 +365,21 @@ static void sdhci_brcmstb_cqe_enable(str + + sdhci_cqe_enable(mmc); + +- /* Reset CMD13 polling timer back to eMMC specification default */ +- cqhci_writel(cq_host, 0x00011000, CQHCI_SSC1); ++ /* ++ * The controller resets this register to a very short default interval ++ * whenever CQHCI is disabled. ++ * ++ * For removable cards CBC needs to be clear or card removal can hang ++ * the CQE. In polling mode, a CIT of 0x4000 "cycles" seems to produce the best ++ * throughput. ++ * ++ * For nonremovable cards, the specification default of CBC=1 CIT=0x1000 ++ * suffices. ++ */ ++ if (mmc->caps & MMC_CAP_NONREMOVABLE) ++ cqhci_writel(cq_host, 0x00011000, CQHCI_SSC1); ++ else ++ cqhci_writel(cq_host, 0x00004000, CQHCI_SSC1); + } + + static const struct cqhci_host_ops sdhci_brcmstb_cqhci_ops = { +@@ -386,7 +399,7 @@ static struct sdhci_ops sdhci_brcmstb_op + .set_clock = sdhci_bcm2712_set_clock, + .set_power = sdhci_brcmstb_set_power, + .set_bus_width = sdhci_set_bus_width, +- .reset = sdhci_reset, ++ .reset = brcmstb_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, + .init_sd_express = bcm2712_init_sd_express, + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch b/target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch new file mode 100644 index 0000000000..45b94b7f17 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1136-feat-Add-support-for-SunFounder-PiPower-3-overlay.patch @@ -0,0 +1,193 @@ +From a1d3defcca200077e1e382fe049ca613d16efd2b Mon Sep 17 00:00:00 2001 +From: Cavon Lee +Date: Tue, 18 Jun 2024 14:01:23 +0800 +Subject: [PATCH 1136/1145] feat: Add support for SunFounder PiPower 3 overlay + fix: Fix wrong Pironman 5 ir default pin number fix: Change space indentation + to tab + +Signed-off-by: Cavon Lee +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 +- + .../overlays/sunfounder-pipower3-overlay.dts | 44 ++++++++++ + .../overlays/sunfounder-pironman5-overlay.dts | 88 ++++++++++--------- + 4 files changed, 98 insertions(+), 43 deletions(-) + create mode 100644 arch/arm/boot/dts/overlays/sunfounder-pipower3-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -275,6 +275,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + ssd1306-spi.dtbo \ + ssd1331-spi.dtbo \ + ssd1351-spi.dtbo \ ++ sunfounder-pipower3.dtbo \ + sunfounder-pironman5.dtbo \ + superaudioboard.dtbo \ + sx150x.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -4695,11 +4695,17 @@ Params: speed SPI bus + reset_pin GPIO pin for RESET (default 25) + + ++Name: sunfounder-pipower3 ++Info: Overlay for SunFounder PiPower 3 ++Load: dtoverlay=sunfounder-pipower3,= ++Params: poweroff_pin Change poweroff pin (default 26) ++ ++ + Name: sunfounder-pironman5 + Info: Overlay for SunFounder Pironman 5 + Load: dtoverlay=sunfounder-pironman5,= + Params: ir Enable IR or not (on or off, default on) +- ir_pins Change IR receiver pin (default 12) ++ ir_pins Change IR receiver pin (default 13) + + + Name: superaudioboard +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sunfounder-pipower3-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target-path = "/chosen"; ++ __overlay__ { ++ power: power { ++ hat_current_supply = <5000>; ++ }; ++ }; ++ }; ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ power_ctrl: power_ctrl { ++ compatible = "gpio-poweroff"; ++ gpios = <&gpio 26 0>; ++ force; ++ }; ++ }; ++ }; ++ fragment@3 { ++ target = <&gpio>; ++ __overlay__ { ++ power_ctrl_pins: power_ctrl_pins { ++ brcm,pins = <26>; ++ brcm,function = <1>; // out ++ }; ++ }; ++ }; ++ __overrides__ { ++ poweroff_pin = <&power_ctrl>,"gpios:4", ++ <&power_ctrl_pins>,"brcm,pins:0"; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/sunfounder-pironman5-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sunfounder-pironman5-overlay.dts +@@ -2,50 +2,54 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835"; ++ compatible = "brcm,bcm2835"; + +- fragment@0 { +- target = <&i2c1>; +- __overlay__ { +- status = "okay"; +- }; +- }; +- fragment@1 { +- target = <&spi0>; +- __overlay__ { +- status = "okay"; +- }; +- }; +- fragment@2 { +- target-path = "/"; +- __overlay__ { +- gpio_ir: ir-receiver@c { +- compatible = "gpio-ir-receiver"; +- pinctrl-names = "default"; +- pinctrl-0 = <&gpio_ir_pins>; ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ gpio_ir: ir-receiver@d { ++ compatible = "gpio-ir-receiver"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_ir_pins>; + +- // pin number, high or low +- gpios = <&gpio 12 1>; ++ // pin number, high or low ++ gpios = <&gpio 13 1>; + +- // parameter for keymap name +- linux,rc-map-name = "rc-rc6-mce"; ++ // parameter for keymap name ++ linux,rc-map-name = "rc-rc6-mce"; + +- status = "okay"; +- }; +- }; +- }; +- fragment@3 { +- target = <&gpio>; +- __overlay__ { +- gpio_ir_pins: gpio_ir_pins@c { +- brcm,pins = <12>; +- brcm,function = <0>; +- brcm,pull = <2>; +- }; +- }; +- }; +- __overrides__ { +- ir = <&gpio_ir>,"status"; +- ir_pins = <&gpio_ir>,"gpios:4", <&gpio_ir>,"reg:0", <&gpio_ir_pins>,"brcm,pins:0", <&gpio_ir_pins>,"reg:0"; +- }; ++ status = "okay"; ++ }; ++ }; ++ }; ++ fragment@3 { ++ target = <&gpio>; ++ __overlay__ { ++ gpio_ir_pins: gpio_ir_pins@d { ++ brcm,pins = <13>; ++ brcm,function = <0>; ++ brcm,pull = <2>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ ir = <&gpio_ir>,"status"; ++ ir_pins = ++ <&gpio_ir>,"gpios:4", ++ <&gpio_ir>,"reg:0", ++ <&gpio_ir_pins>,"brcm,pins:0", ++ <&gpio_ir_pins>,"reg:0"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch b/target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch new file mode 100644 index 0000000000..b763006154 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1137-pwm-gpio-pwm-follow-pwm_apply_might_sleep-rename.patch @@ -0,0 +1,32 @@ +From cd92a9591833ea06d1f12391f6b027fcecf436a9 Mon Sep 17 00:00:00 2001 +From: Ratchanan Srirattanamet +Date: Tue, 18 Jun 2024 15:44:13 +0700 +Subject: [PATCH 1137/1145] pwm: gpio-pwm: follow pwm_apply_might_sleep() + rename + +Fixes: 03286093be68("drivers/gpio: Add a driver that wraps the PWM API as a GPIO controller") +Signed-off-by: Ratchanan Srirattanamet +--- + drivers/gpio/gpio-pwm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpio/gpio-pwm.c ++++ b/drivers/gpio/gpio-pwm.c +@@ -34,7 +34,7 @@ static void pwm_gpio_set(struct gpio_chi + + pwm_get_state(pwm_gpio->pwm[off], &state); + state.duty_cycle = val ? state.period : 0; +- pwm_apply_state(pwm_gpio->pwm[off], &state); ++ pwm_apply_might_sleep(pwm_gpio->pwm[off], &state); + } + + static int pwm_gpio_parse_dt(struct pwm_gpio *pwm_gpio, +@@ -79,7 +79,7 @@ static int pwm_gpio_parse_dt(struct pwm_ + pwm_init_state(pwm_gpio->pwm[i], &state); + + state.duty_cycle = 0; +- pwm_apply_state(pwm_gpio->pwm[i], &state); ++ pwm_apply_might_sleep(pwm_gpio->pwm[i], &state); + } + + pwm_gpio->gc.ngpio = num_gpios; diff --git a/target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch b/target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch new file mode 100644 index 0000000000..b19941bc8a --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1138-drm-bridge-panel-Ensure-backlight-is-reachable.patch @@ -0,0 +1,29 @@ +From da87f91ad8450ccc5274cd7b6ba8d823b396c96f Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 18 Jun 2024 15:33:30 +0100 +Subject: [PATCH 1138/1145] drm/bridge: panel: Ensure backlight is reachable + +Ensure that the various options of modules vs builtin results +in being able to call into the backlight code. + +https://github.com/raspberrypi/linux/issues/6198 + +Fixes: 573f8fd0abf1 ("drm/bridge: panel: Name an associated backlight device") +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/bridge/panel.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/bridge/panel.c ++++ b/drivers/gpu/drm/bridge/panel.c +@@ -87,8 +87,10 @@ static int panel_bridge_attach(struct dr + drm_connector_attach_encoder(&panel_bridge->connector, + bridge->encoder); + ++#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE) + backlight_set_display_name(panel_bridge->panel->backlight, + panel_bridge->connector.name); ++#endif + + if (bridge->dev->registered) { + if (connector->funcs->reset) diff --git a/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch b/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch new file mode 100644 index 0000000000..113b3fdf53 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch @@ -0,0 +1,36 @@ +From 7af85d54e39733bb9a236b95ea5ed1ab8277d560 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Tue, 11 Jun 2024 16:12:47 +0100 +Subject: [PATCH 1141/1145] fs/ntfs3: Fix memory corruption when page_size + changes + +The rework in fs/ntfs3: Reduce stack usage +changes log->page_size but doesn't change the associated +log->page_mask and log->page_bits. + +That results in the bytes value in read_log_page +getting a negative value, which is bad when it is +passed to memcpy. + +The kernel panic can be observed when connecting an +ntfs formatted drive that has previously been connected +to a Windows machine to a Raspberry Pi 5, which by defauilt +uses a 16K kernel pagesize. + +Fixes: 865e7a7700d9 ("fs/ntfs3: Reduce stack usage") +Signed-off-by: Dom Cobley +--- + fs/ntfs3/fslog.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3907,6 +3907,8 @@ check_restart_area: + log->l_size = log->orig_file_size; + log->page_size = norm_file_page(t32, &log->l_size, + t32 == DefaultLogPageSize); ++ log->page_mask = log->page_size - 1; ++ log->page_bits = blksize_bits(log->page_size); + } + + if (log->page_size != t32 || diff --git a/target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch b/target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch new file mode 100644 index 0000000000..fb08ba1ad5 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1142-fixup-drivers-mmc-sdhci-brcmstb-bcm2712-supports-HS4.patch @@ -0,0 +1,26 @@ +From d2813c02131b9ddf938277f4123da7ccbd113ea7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 24 Jun 2024 22:35:42 +0100 +Subject: [PATCH 1142/1145] fixup! drivers: mmc: sdhci-brcmstb: bcm2712 + supports HS400es and clock gating + +Declaring auto-clockgate support for a host that can interface with +SDIO cards is a bug. + +See: https://github.com/raspberrypi/linux/issues/6237 + +Signed-off-by: Phil Elwell +--- + drivers/mmc/host/sdhci-brcmstb.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-brcmstb.c ++++ b/drivers/mmc/host/sdhci-brcmstb.c +@@ -429,7 +429,6 @@ static const struct brcmstb_match_priv m + }; + + static const struct brcmstb_match_priv match_priv_2712 = { +- .flags = BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE, + .hs400es = sdhci_brcmstb_hs400es, + .cfginit = sdhci_brcmstb_cfginit_2712, + .ops = &sdhci_brcmstb_ops_2712, diff --git a/target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch b/target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch new file mode 100644 index 0000000000..ad364196e9 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1144-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch @@ -0,0 +1,346 @@ +From 3b42260d2130b5ca110c5340ab2bd055eede5968 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 28 Apr 2021 17:46:01 +0100 +Subject: [PATCH 1144/1145] dmaengine: dw-axi-dmac: Fixes for RP1 + +Don't assume that DMA addresses of devices are the same as their +physical addresses - convert correctly. + +The CFG2 register layout is used when there are more than 8 channels, +but also when configured for more than 16 target peripheral devices +because the index of the handshake signal has to be made wider. + +Reset the DMAC on probe + +The driver goes to the trouble of tracking when transfers have been +paused, but then doesn't report that state when queried. + +Not having APB registers is not an error - for most use cases it's +not even of interest, it's expected. Demote the message to debug level, +which is disabled by default. + +Each channel has a descriptor pool, which is shared between transfers. +It is unsafe to treat the total number of descriptors allocated from a +pool as the number allocated to a specific transfer; doing so leads +to releasing buffers that shouldn't be released and walking off the +ends of descriptor lists. Instead, give each transfer descriptor its +own count. + +Support partial transfers: +Some use cases involve streaming from a device where the transfer only +proceeds when the device's FIFO occupancy exceeds a certain threshold. +In such cases (e.g. when pulling data from a UART) it is important to +know how much data has been transferred so far, in order that remaining +bytes can be read from the FIFO directly by software. + +Add the necessary code to provide this "residue" value with a finer, +sub-transfer granularity. + +In order to prevent the occasional byte getting stuck in the DMA +controller's internal buffers, restrict the destination memory width +to the source register width. + +Signed-off-by: Phil Elwell +--- + .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 136 +++++++++++++++--- + drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + + 2 files changed, 116 insertions(+), 21 deletions(-) + +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -84,6 +85,17 @@ axi_chan_iowrite64(struct axi_dma_chan * + iowrite32(upper_32_bits(val), chan->chan_regs + reg + 4); + } + ++static inline u64 ++axi_chan_ioread64(struct axi_dma_chan *chan, u32 reg) ++{ ++ /* ++ * We split one 64 bit read into two 32 bit reads as some HW doesn't ++ * support 64 bit access. ++ */ ++ return ((u64)ioread32(chan->chan_regs + reg + 4) << 32) + ++ ioread32(chan->chan_regs + reg); ++} ++ + static inline void axi_chan_config_write(struct axi_dma_chan *chan, + struct axi_dma_chan_config *config) + { +@@ -220,7 +232,18 @@ static void axi_dma_hw_init(struct axi_d + { + int ret; + u32 i; ++ int retries = 1000; + ++ axi_dma_iowrite32(chip, DMAC_RESET, 1); ++ while (axi_dma_ioread32(chip, DMAC_RESET)) { ++ retries--; ++ if (!retries) { ++ dev_err(chip->dev, "%s: DMAC failed to reset\n", ++ __func__); ++ return; ++ } ++ cpu_relax(); ++ } + for (i = 0; i < chip->dw->hdata->nr_channels; i++) { + axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL); + axi_chan_disable(&chip->dw->chan[i]); +@@ -256,7 +279,6 @@ static struct axi_dma_desc *axi_desc_all + kfree(desc); + return NULL; + } +- desc->nr_hw_descs = num; + + return desc; + } +@@ -283,7 +305,7 @@ static struct axi_dma_lli *axi_desc_get( + static void axi_desc_put(struct axi_dma_desc *desc) + { + struct axi_dma_chan *chan = desc->chan; +- int count = desc->nr_hw_descs; ++ u32 count = desc->hw_desc_count; + struct axi_dma_hw_desc *hw_desc; + int descs_put; + +@@ -305,6 +327,48 @@ static void vchan_desc_put(struct virt_d + axi_desc_put(vd_to_axi_desc(vdesc)); + } + ++static u32 axi_dma_desc_src_pos(struct axi_dma_desc *desc, dma_addr_t addr) ++{ ++ unsigned int idx = 0; ++ u32 pos = 0; ++ ++ while (pos < desc->length) { ++ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++]; ++ u32 len = hw_desc->len; ++ dma_addr_t start = le64_to_cpu(hw_desc->lli->sar); ++ ++ if (addr >= start && addr <= (start + len)) { ++ pos += addr - start; ++ break; ++ } ++ ++ pos += len; ++ } ++ ++ return pos; ++} ++ ++static u32 axi_dma_desc_dst_pos(struct axi_dma_desc *desc, dma_addr_t addr) ++{ ++ unsigned int idx = 0; ++ u32 pos = 0; ++ ++ while (pos < desc->length) { ++ struct axi_dma_hw_desc *hw_desc = &desc->hw_desc[idx++]; ++ u32 len = hw_desc->len; ++ dma_addr_t start = le64_to_cpu(hw_desc->lli->dar); ++ ++ if (addr >= start && addr <= (start + len)) { ++ pos += addr - start; ++ break; ++ } ++ ++ pos += len; ++ } ++ ++ return pos; ++} ++ + static enum dma_status + dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, + struct dma_tx_state *txstate) +@@ -314,10 +378,7 @@ dma_chan_tx_status(struct dma_chan *dcha + enum dma_status status; + u32 completed_length; + unsigned long flags; +- u32 completed_blocks; + size_t bytes = 0; +- u32 length; +- u32 len; + + status = dma_cookie_status(dchan, cookie, txstate); + if (status == DMA_COMPLETE || !txstate) +@@ -326,16 +387,31 @@ dma_chan_tx_status(struct dma_chan *dcha + spin_lock_irqsave(&chan->vc.lock, flags); + + vdesc = vchan_find_desc(&chan->vc, cookie); +- if (vdesc) { +- length = vd_to_axi_desc(vdesc)->length; +- completed_blocks = vd_to_axi_desc(vdesc)->completed_blocks; +- len = vd_to_axi_desc(vdesc)->hw_desc[0].len; +- completed_length = completed_blocks * len; +- bytes = length - completed_length; ++ if (vdesc && vdesc == vchan_next_desc(&chan->vc)) { ++ /* This descriptor is in-progress */ ++ struct axi_dma_desc *desc = vd_to_axi_desc(vdesc); ++ dma_addr_t addr; ++ ++ if (chan->direction == DMA_MEM_TO_DEV) { ++ addr = axi_chan_ioread64(chan, CH_SAR); ++ completed_length = axi_dma_desc_src_pos(desc, addr); ++ } else if (chan->direction == DMA_DEV_TO_MEM) { ++ addr = axi_chan_ioread64(chan, CH_DAR); ++ completed_length = axi_dma_desc_dst_pos(desc, addr); ++ } else { ++ completed_length = 0; ++ } ++ bytes = desc->length - completed_length; ++ } else if (vdesc) { ++ /* Still in the queue so not started */ ++ bytes = vd_to_axi_desc(vdesc)->length; + } + +- spin_unlock_irqrestore(&chan->vc.lock, flags); ++ if (chan->is_paused && status == DMA_IN_PROGRESS) ++ status = DMA_PAUSED; ++ + dma_set_residue(txstate, bytes); ++ spin_unlock_irqrestore(&chan->vc.lock, flags); + + return status; + } +@@ -521,7 +597,7 @@ static void dw_axi_dma_set_hw_channel(st + unsigned long reg_value, val; + + if (!chip->apb_regs) { +- dev_err(chip->dev, "apb_regs not initialized\n"); ++ dev_dbg(chip->dev, "apb_regs not initialized\n"); + return; + } + +@@ -625,18 +701,25 @@ static int dw_axi_dma_set_hw_desc(struct + switch (chan->direction) { + case DMA_MEM_TO_DEV: + reg_width = __ffs(chan->config.dst_addr_width); +- device_addr = chan->config.dst_addr; ++ device_addr = phys_to_dma(chan->chip->dev, chan->config.dst_addr); + ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS | + mem_width << CH_CTL_L_SRC_WIDTH_POS | ++ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_DST_MSIZE_POS | ++ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS | + DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS | + DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS; + block_ts = len >> mem_width; + break; + case DMA_DEV_TO_MEM: + reg_width = __ffs(chan->config.src_addr_width); +- device_addr = chan->config.src_addr; ++ /* Prevent partial access units getting lost */ ++ if (mem_width > reg_width) ++ mem_width = reg_width; ++ device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr); + ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS | + mem_width << CH_CTL_L_DST_WIDTH_POS | ++ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | ++ DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_SRC_MSIZE_POS | + DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS | + DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS; + block_ts = len >> reg_width; +@@ -672,9 +755,6 @@ static int dw_axi_dma_set_hw_desc(struct + } + + hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1); +- +- ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | +- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS; + hw_desc->lli->ctl_lo = cpu_to_le32(ctllo); + + set_desc_src_master(hw_desc); +@@ -769,6 +849,8 @@ dw_axi_dma_chan_prep_cyclic(struct dma_c + src_addr += segment_len; + } + ++ desc->hw_desc_count = total_segments; ++ + llp = desc->hw_desc[0].llp; + + /* Managed transfer list */ +@@ -851,6 +933,8 @@ dw_axi_dma_chan_prep_slave_sg(struct dma + } while (len >= segment_len); + } + ++ desc->hw_desc_count = loop; ++ + /* Set end-of-link to the last link descriptor of list */ + set_desc_last(&desc->hw_desc[num_sgs - 1]); + +@@ -958,6 +1042,8 @@ dma_chan_prep_dma_memcpy(struct dma_chan + num++; + } + ++ desc->hw_desc_count = num; ++ + /* Set end-of-link to the last link descriptor of list */ + set_desc_last(&desc->hw_desc[num - 1]); + /* Managed transfer list */ +@@ -1006,7 +1092,7 @@ static void axi_chan_dump_lli(struct axi + static void axi_chan_list_dump_lli(struct axi_dma_chan *chan, + struct axi_dma_desc *desc_head) + { +- int count = atomic_read(&chan->descs_allocated); ++ u32 count = desc_head->hw_desc_count; + int i; + + for (i = 0; i < count; i++) +@@ -1049,11 +1135,11 @@ out: + + static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan) + { +- int count = atomic_read(&chan->descs_allocated); + struct axi_dma_hw_desc *hw_desc; + struct axi_dma_desc *desc; + struct virt_dma_desc *vd; + unsigned long flags; ++ u32 count; + u64 llp; + int i; + +@@ -1075,6 +1161,7 @@ static void axi_chan_block_xfer_complete + if (chan->cyclic) { + desc = vd_to_axi_desc(vd); + if (desc) { ++ count = desc->hw_desc_count; + llp = lo_hi_readq(chan->chan_regs + CH_LLP); + for (i = 0; i < count; i++) { + hw_desc = &desc->hw_desc[i]; +@@ -1095,6 +1182,9 @@ static void axi_chan_block_xfer_complete + /* Remove the completed descriptor from issued list before completing */ + list_del(&vd->node); + vchan_cookie_complete(vd); ++ ++ /* Submit queued descriptors after processing the completed ones */ ++ axi_chan_start_first_queued(chan); + } + + out: +@@ -1324,6 +1414,10 @@ static int parse_device_properties(struc + + chip->dw->hdata->nr_masters = tmp; + ++ ret = device_property_read_u32(dev, "snps,dma-targets", &tmp); ++ if (!ret && tmp > 16) ++ chip->dw->hdata->use_cfg2 = true; ++ + ret = device_property_read_u32(dev, "snps,data-width", &tmp); + if (ret) + return ret; +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +@@ -101,6 +101,7 @@ struct axi_dma_desc { + + struct virt_dma_desc vd; + struct axi_dma_chan *chan; ++ u32 hw_desc_count; + u32 completed_blocks; + u32 length; + u32 period_len; diff --git a/target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch b/target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch new file mode 100644 index 0000000000..adefd4ab54 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1145-fixup-dmaengine-dw-axi-dmac-Fixes-for-RP1.patch @@ -0,0 +1,89 @@ +From 769634f344626ed73bcda14c91b567067974d7b2 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Sat, 29 Jun 2024 09:30:23 +0100 +Subject: [PATCH 1145/1145] fixup! dmaengine: dw-axi-dmac: Fixes for RP1 + +nr_hw_descs is the upstream version of what count_hw_descs, so make +(more) use of it instead. + +Signed-off-by: Phil Elwell +--- + drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 14 +++++++------- + drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 - + 2 files changed, 7 insertions(+), 8 deletions(-) + +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +@@ -305,7 +305,7 @@ static struct axi_dma_lli *axi_desc_get( + static void axi_desc_put(struct axi_dma_desc *desc) + { + struct axi_dma_chan *chan = desc->chan; +- u32 count = desc->hw_desc_count; ++ int count = desc->nr_hw_descs; + struct axi_dma_hw_desc *hw_desc; + int descs_put; + +@@ -849,7 +849,7 @@ dw_axi_dma_chan_prep_cyclic(struct dma_c + src_addr += segment_len; + } + +- desc->hw_desc_count = total_segments; ++ desc->nr_hw_descs = total_segments; + + llp = desc->hw_desc[0].llp; + +@@ -933,7 +933,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma + } while (len >= segment_len); + } + +- desc->hw_desc_count = loop; ++ desc->nr_hw_descs = loop; + + /* Set end-of-link to the last link descriptor of list */ + set_desc_last(&desc->hw_desc[num_sgs - 1]); +@@ -1042,7 +1042,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan + num++; + } + +- desc->hw_desc_count = num; ++ desc->nr_hw_descs = num; + + /* Set end-of-link to the last link descriptor of list */ + set_desc_last(&desc->hw_desc[num - 1]); +@@ -1092,7 +1092,7 @@ static void axi_chan_dump_lli(struct axi + static void axi_chan_list_dump_lli(struct axi_dma_chan *chan, + struct axi_dma_desc *desc_head) + { +- u32 count = desc_head->hw_desc_count; ++ int count = desc_head->nr_hw_descs; + int i; + + for (i = 0; i < count; i++) +@@ -1139,7 +1139,7 @@ static void axi_chan_block_xfer_complete + struct axi_dma_desc *desc; + struct virt_dma_desc *vd; + unsigned long flags; +- u32 count; ++ int count; + u64 llp; + int i; + +@@ -1161,7 +1161,7 @@ static void axi_chan_block_xfer_complete + if (chan->cyclic) { + desc = vd_to_axi_desc(vd); + if (desc) { +- count = desc->hw_desc_count; ++ count = desc->nr_hw_descs; + llp = lo_hi_readq(chan->chan_regs + CH_LLP); + for (i = 0; i < count; i++) { + hw_desc = &desc->hw_desc[i]; +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +@@ -101,7 +101,6 @@ struct axi_dma_desc { + + struct virt_dma_desc vd; + struct axi_dma_chan *chan; +- u32 hw_desc_count; + u32 completed_blocks; + u32 length; + u32 period_len;