--- /dev/null
+From fe10e3a0490f7259035dbdebb653f46093c10c9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 22:42:56 +0200
+Subject: ata: libata: disallow dev-initiated LPM transitions to unsupported
+ states
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <niklas.cassel@wdc.com>
+
+[ Upstream commit 24e0e61db3cb86a66824531989f1df80e0939f26 ]
+
+In AHCI 1.3.1, the register description for CAP.SSC:
+"When cleared to ‘0’, software must not allow the HBA to initiate
+transitions to the Slumber state via agressive link power management nor
+the PxCMD.ICC field in each port, and the PxSCTL.IPM field in each port
+must be programmed to disallow device initiated Slumber requests."
+
+In AHCI 1.3.1, the register description for CAP.PSC:
+"When cleared to ‘0’, software must not allow the HBA to initiate
+transitions to the Partial state via agressive link power management nor
+the PxCMD.ICC field in each port, and the PxSCTL.IPM field in each port
+must be programmed to disallow device initiated Partial requests."
+
+Ensure that we always set the corresponding bits in PxSCTL.IPM, such that
+a device is not allowed to initiate transitions to power states which are
+unsupported by the HBA.
+
+DevSleep is always initiated by the HBA, however, for completeness, set the
+corresponding bit in PxSCTL.IPM such that agressive link power management
+cannot transition to DevSleep if DevSleep is not supported.
+
+sata_link_scr_lpm() is used by libahci, ata_piix and libata-pmp.
+However, only libahci has the ability to read the CAP/CAP2 register to see
+if these features are supported. Therefore, in order to not introduce any
+regressions on ata_piix or libata-pmp, create flags that indicate that the
+respective feature is NOT supported. This way, the behavior for ata_piix
+and libata-pmp should remain unchanged.
+
+This change is based on a patch originally submitted by Runa Guo-oc.
+
+Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
+Fixes: 1152b2617a6e ("libata: implement sata_link_scr_lpm() and make ata_dev_set_feature() global")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c | 9 +++++++++
+ drivers/ata/libata-core.c | 19 ++++++++++++++++---
+ include/linux/libata.h | 4 ++++
+ 3 files changed, 29 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 4069c2a79daa2..aa35d1941d1fc 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -1838,6 +1838,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ else
+ dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n");
+
++ if (!(hpriv->cap & HOST_CAP_PART))
++ host->flags |= ATA_HOST_NO_PART;
++
++ if (!(hpriv->cap & HOST_CAP_SSC))
++ host->flags |= ATA_HOST_NO_SSC;
++
++ if (!(hpriv->cap2 & HOST_CAP2_SDS))
++ host->flags |= ATA_HOST_NO_DEVSLP;
++
+ if (pi.flags & ATA_FLAG_EM)
+ ahci_reset_em(host);
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 1e057162e00eb..cec1be2cae47d 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -4023,10 +4023,23 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
+ case ATA_LPM_MED_POWER_WITH_DIPM:
+ case ATA_LPM_MIN_POWER_WITH_PARTIAL:
+ case ATA_LPM_MIN_POWER:
+- if (ata_link_nr_enabled(link) > 0)
+- /* no restrictions on LPM transitions */
++ if (ata_link_nr_enabled(link) > 0) {
++ /* assume no restrictions on LPM transitions */
+ scontrol &= ~(0x7 << 8);
+- else {
++
++ /*
++ * If the controller does not support partial, slumber,
++ * or devsleep, then disallow these transitions.
++ */
++ if (link->ap->host->flags & ATA_HOST_NO_PART)
++ scontrol |= (0x1 << 8);
++
++ if (link->ap->host->flags & ATA_HOST_NO_SSC)
++ scontrol |= (0x2 << 8);
++
++ if (link->ap->host->flags & ATA_HOST_NO_DEVSLP)
++ scontrol |= (0x4 << 8);
++ } else {
+ /* empty port, power off */
+ scontrol &= ~0xf;
+ scontrol |= (0x1 << 2);
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index 2e448d65a04c7..3804988095f99 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -261,6 +261,10 @@ enum {
+ ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */
+ ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */
+
++ ATA_HOST_NO_PART = (1 << 4), /* Host does not support partial */
++ ATA_HOST_NO_SSC = (1 << 5), /* Host does not support slumber */
++ ATA_HOST_NO_DEVSLP = (1 << 6), /* Host does not support devslp */
++
+ /* bits 24:31 of host->flags are reserved for LLD specific flags */
+
+ /* various lengths of time */
+--
+2.40.1
+
--- /dev/null
+From 3220e54e9192d782d2ccfc243784332dcb0554c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Mar 2020 16:58:04 +0100
+Subject: ata: move EXPORT_SYMBOL_GPL()s close to exported code
+
+From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+
+[ Upstream commit a52fbcfc7b38b50b5b651bab80041a93ba7b29b9 ]
+
+Move EXPORT_SYMBOL_GPL()s close to exported code like it is
+done in other kernel subsystems. As a nice side effect this
+results in the removal of few ifdefs.
+
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 24e0e61db3cb ("ata: libata: disallow dev-initiated LPM transitions to unsupported states")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-core.c | 208 +++++++++++++++-----------------------
+ drivers/ata/libata-eh.c | 20 +++-
+ drivers/ata/libata-scsi.c | 8 ++
+ 3 files changed, 109 insertions(+), 127 deletions(-)
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index c06f618b1aa3c..1e057162e00eb 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -22,6 +22,11 @@
+ * http://www.compactflash.org (CF)
+ * http://www.qic.org (QIC157 - Tape and DSC)
+ * http://www.ce-ata.org (CE-ATA: not supported)
++ *
++ * libata is essentially a library of internal helper functions for
++ * low-level ATA host controller drivers. As such, the API/ABI is
++ * likely to change as new drivers are added and updated.
++ * Do not depend on ABI/API stability.
+ */
+
+ #include <linux/kernel.h>
+@@ -64,8 +69,11 @@
+
+ /* debounce timing parameters in msecs { interval, duration, timeout } */
+ const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
++EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
+ const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
++EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
+ const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };
++EXPORT_SYMBOL_GPL(sata_deb_timing_long);
+
+ const struct ata_port_operations ata_base_port_ops = {
+ .prereset = ata_std_prereset,
+@@ -74,6 +82,7 @@ const struct ata_port_operations ata_base_port_ops = {
+ .sched_eh = ata_std_sched_eh,
+ .end_eh = ata_std_end_eh,
+ };
++EXPORT_SYMBOL_GPL(ata_base_port_ops);
+
+ const struct ata_port_operations sata_port_ops = {
+ .inherits = &ata_base_port_ops,
+@@ -81,6 +90,7 @@ const struct ata_port_operations sata_port_ops = {
+ .qc_defer = ata_std_qc_defer,
+ .hardreset = sata_std_hardreset,
+ };
++EXPORT_SYMBOL_GPL(sata_port_ops);
+
+ static unsigned int ata_dev_init_params(struct ata_device *dev,
+ u16 heads, u16 sectors);
+@@ -223,6 +233,7 @@ struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap,
+
+ return NULL;
+ }
++EXPORT_SYMBOL_GPL(ata_link_next);
+
+ /**
+ * ata_dev_next - device iteration helper
+@@ -276,6 +287,7 @@ struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link,
+ goto next;
+ return dev;
+ }
++EXPORT_SYMBOL_GPL(ata_dev_next);
+
+ /**
+ * ata_dev_phys_link - find physical link for a device
+@@ -520,6 +532,7 @@ int atapi_cmd_type(u8 opcode)
+ return ATAPI_MISC;
+ }
+ }
++EXPORT_SYMBOL_GPL(atapi_cmd_type);
+
+ /**
+ * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
+@@ -564,6 +577,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
+ fis[18] = (tf->auxiliary >> 16) & 0xff;
+ fis[19] = (tf->auxiliary >> 24) & 0xff;
+ }
++EXPORT_SYMBOL_GPL(ata_tf_to_fis);
+
+ /**
+ * ata_tf_from_fis - Convert SATA FIS to ATA taskfile
+@@ -593,6 +607,7 @@ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
+ tf->nsect = fis[12];
+ tf->hob_nsect = fis[13];
+ }
++EXPORT_SYMBOL_GPL(ata_tf_from_fis);
+
+ static const u8 ata_rw_cmds[] = {
+ /* pio multi */
+@@ -867,6 +882,7 @@ unsigned long ata_pack_xfermask(unsigned long pio_mask,
+ ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
+ ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
+ }
++EXPORT_SYMBOL_GPL(ata_pack_xfermask);
+
+ /**
+ * ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks
+@@ -888,6 +904,7 @@ void ata_unpack_xfermask(unsigned long xfer_mask, unsigned long *pio_mask,
+ if (udma_mask)
+ *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA;
+ }
++EXPORT_SYMBOL_GPL(ata_unpack_xfermask);
+
+ static const struct ata_xfer_ent {
+ int shift, bits;
+@@ -922,6 +939,7 @@ u8 ata_xfer_mask2mode(unsigned long xfer_mask)
+ return ent->base + highbit - ent->shift;
+ return 0xff;
+ }
++EXPORT_SYMBOL_GPL(ata_xfer_mask2mode);
+
+ /**
+ * ata_xfer_mode2mask - Find matching xfer_mask for XFER_*
+@@ -945,6 +963,7 @@ unsigned long ata_xfer_mode2mask(u8 xfer_mode)
+ & ~((1 << ent->shift) - 1);
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_xfer_mode2mask);
+
+ /**
+ * ata_xfer_mode2shift - Find matching xfer_shift for XFER_*
+@@ -967,6 +986,7 @@ int ata_xfer_mode2shift(unsigned long xfer_mode)
+ return ent->shift;
+ return -1;
+ }
++EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
+
+ /**
+ * ata_mode_string - convert xfer_mask to string
+@@ -1013,6 +1033,7 @@ const char *ata_mode_string(unsigned long xfer_mask)
+ return xfer_mode_str[highbit];
+ return "<n/a>";
+ }
++EXPORT_SYMBOL_GPL(ata_mode_string);
+
+ const char *sata_spd_string(unsigned int spd)
+ {
+@@ -1093,6 +1114,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
+ DPRINTK("unknown device\n");
+ return ATA_DEV_UNKNOWN;
+ }
++EXPORT_SYMBOL_GPL(ata_dev_classify);
+
+ /**
+ * ata_id_string - Convert IDENTIFY DEVICE page into string
+@@ -1129,6 +1151,7 @@ void ata_id_string(const u16 *id, unsigned char *s,
+ len -= 2;
+ }
+ }
++EXPORT_SYMBOL_GPL(ata_id_string);
+
+ /**
+ * ata_id_c_string - Convert IDENTIFY DEVICE page into C string
+@@ -1156,6 +1179,7 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
+ p--;
+ *p = '\0';
+ }
++EXPORT_SYMBOL_GPL(ata_id_c_string);
+
+ static u64 ata_id_n_sectors(const u16 *id)
+ {
+@@ -1513,6 +1537,7 @@ unsigned long ata_id_xfermask(const u16 *id)
+
+ return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
+ }
++EXPORT_SYMBOL_GPL(ata_id_xfermask);
+
+ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
+ {
+@@ -1770,6 +1795,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
+ return 1;
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
+
+ /**
+ * ata_pio_mask_no_iordy - Return the non IORDY mask
+@@ -1810,6 +1836,7 @@ unsigned int ata_do_dev_read_id(struct ata_device *dev,
+ return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
+ id, sizeof(id[0]) * ATA_ID_WORDS, 0);
+ }
++EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
+
+ /**
+ * ata_dev_read_id - Read ID data from the specified device
+@@ -2808,6 +2835,7 @@ int ata_cable_40wire(struct ata_port *ap)
+ {
+ return ATA_CBL_PATA40;
+ }
++EXPORT_SYMBOL_GPL(ata_cable_40wire);
+
+ /**
+ * ata_cable_80wire - return 80 wire cable type
+@@ -2821,6 +2849,7 @@ int ata_cable_80wire(struct ata_port *ap)
+ {
+ return ATA_CBL_PATA80;
+ }
++EXPORT_SYMBOL_GPL(ata_cable_80wire);
+
+ /**
+ * ata_cable_unknown - return unknown PATA cable.
+@@ -2833,6 +2862,7 @@ int ata_cable_unknown(struct ata_port *ap)
+ {
+ return ATA_CBL_PATA_UNK;
+ }
++EXPORT_SYMBOL_GPL(ata_cable_unknown);
+
+ /**
+ * ata_cable_ignore - return ignored PATA cable.
+@@ -2845,6 +2875,7 @@ int ata_cable_ignore(struct ata_port *ap)
+ {
+ return ATA_CBL_PATA_IGN;
+ }
++EXPORT_SYMBOL_GPL(ata_cable_ignore);
+
+ /**
+ * ata_cable_sata - return SATA cable type
+@@ -2857,6 +2888,7 @@ int ata_cable_sata(struct ata_port *ap)
+ {
+ return ATA_CBL_SATA;
+ }
++EXPORT_SYMBOL_GPL(ata_cable_sata);
+
+ /**
+ * ata_bus_probe - Reset and probe ATA bus
+@@ -3039,6 +3071,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev)
+ return NULL;
+ return pair;
+ }
++EXPORT_SYMBOL_GPL(ata_dev_pair);
+
+ /**
+ * sata_down_spd_limit - adjust SATA spd limit downward
+@@ -3199,6 +3232,7 @@ int sata_set_spd(struct ata_link *link)
+
+ return 1;
+ }
++EXPORT_SYMBOL_GPL(sata_set_spd);
+
+ /*
+ * This mode timing computation functionality is ported over from
+@@ -3273,6 +3307,7 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
+ if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle);
+ if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma);
+ }
++EXPORT_SYMBOL_GPL(ata_timing_merge);
+
+ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
+ {
+@@ -3289,6 +3324,7 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
+
+ return NULL;
+ }
++EXPORT_SYMBOL_GPL(ata_timing_find_mode);
+
+ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
+ struct ata_timing *t, int T, int UT)
+@@ -3365,6 +3401,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_timing_compute);
+
+ /**
+ * ata_timing_cycle2mode - find xfer mode for the specified cycle duration
+@@ -3416,6 +3453,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle)
+
+ return last_mode;
+ }
++EXPORT_SYMBOL_GPL(ata_timing_cycle2mode);
+
+ /**
+ * ata_down_xfermask_limit - adjust dev xfer masks downward
+@@ -3687,6 +3725,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
+ *r_failed_dev = dev;
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(ata_do_set_mode);
+
+ /**
+ * ata_wait_ready - wait for link to become ready
+@@ -3796,6 +3835,7 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
+
+ return ata_wait_ready(link, deadline, check_ready);
+ }
++EXPORT_SYMBOL_GPL(ata_wait_after_reset);
+
+ /**
+ * sata_link_debounce - debounce SATA phy status
+@@ -3866,6 +3906,7 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params,
+ return -EPIPE;
+ }
+ }
++EXPORT_SYMBOL_GPL(sata_link_debounce);
+
+ /**
+ * sata_link_resume - resume SATA link
+@@ -3932,6 +3973,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
+
+ return rc != -EINVAL ? rc : 0;
+ }
++EXPORT_SYMBOL_GPL(sata_link_resume);
+
+ /**
+ * sata_link_scr_lpm - manipulate SControl IPM and SPM fields
+@@ -4006,6 +4048,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
+ ehc->i.serror &= ~SERR_PHYRDY_CHG;
+ return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG);
+ }
++EXPORT_SYMBOL_GPL(sata_link_scr_lpm);
+
+ /**
+ * ata_std_prereset - prepare for reset
+@@ -4051,6 +4094,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_std_prereset);
+
+ /**
+ * sata_link_hardreset - reset link via SATA phy reset
+@@ -4163,6 +4207,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
+ DPRINTK("EXIT, rc=%d\n", rc);
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(sata_link_hardreset);
+
+ /**
+ * sata_std_hardreset - COMRESET w/o waiting or classification
+@@ -4189,6 +4234,7 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
+ rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
+ return online ? -EAGAIN : rc;
+ }
++EXPORT_SYMBOL_GPL(sata_std_hardreset);
+
+ /**
+ * ata_std_postreset - standard postreset callback
+@@ -4217,6 +4263,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes)
+
+ DPRINTK("EXIT\n");
+ }
++EXPORT_SYMBOL_GPL(ata_std_postreset);
+
+ /**
+ * ata_dev_same_device - Determine whether new ID matches configured device
+@@ -5019,11 +5066,13 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc)
+
+ return ATA_DEFER_LINK;
+ }
++EXPORT_SYMBOL_GPL(ata_std_qc_defer);
+
+ enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc)
+ {
+ return AC_ERR_OK;
+ }
++EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
+
+ /**
+ * ata_sg_init - Associate command with scatter-gather table.
+@@ -5045,6 +5094,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
+ qc->n_elem = n_elem;
+ qc->cursg = qc->sg;
+ }
++EXPORT_SYMBOL_GPL(ata_sg_init);
+
+ #ifdef CONFIG_HAS_DMA
+
+@@ -5367,6 +5417,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
+ __ata_qc_complete(qc);
+ }
+ }
++EXPORT_SYMBOL_GPL(ata_qc_complete);
+
+ /**
+ * ata_qc_get_active - get bitmask of active qcs
+@@ -5449,6 +5500,7 @@ int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active)
+
+ return nr_done;
+ }
++EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
+
+ /**
+ * ata_qc_issue - issue taskfile to device
+@@ -5543,6 +5595,7 @@ int sata_scr_valid(struct ata_link *link)
+
+ return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
+ }
++EXPORT_SYMBOL_GPL(sata_scr_valid);
+
+ /**
+ * sata_scr_read - read SCR register of the specified port
+@@ -5570,6 +5623,7 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val)
+
+ return sata_pmp_scr_read(link, reg, val);
+ }
++EXPORT_SYMBOL_GPL(sata_scr_read);
+
+ /**
+ * sata_scr_write - write SCR register of the specified port
+@@ -5597,6 +5651,7 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val)
+
+ return sata_pmp_scr_write(link, reg, val);
+ }
++EXPORT_SYMBOL_GPL(sata_scr_write);
+
+ /**
+ * sata_scr_write_flush - write SCR register of the specified port and flush
+@@ -5629,6 +5684,7 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
+
+ return sata_pmp_scr_write(link, reg, val);
+ }
++EXPORT_SYMBOL_GPL(sata_scr_write_flush);
+
+ /**
+ * ata_phys_link_online - test whether the given link is online
+@@ -5703,6 +5759,7 @@ bool ata_link_online(struct ata_link *link)
+ return ata_phys_link_online(link) ||
+ (slave && ata_phys_link_online(slave));
+ }
++EXPORT_SYMBOL_GPL(ata_link_online);
+
+ /**
+ * ata_link_offline - test whether the given link is offline
+@@ -5729,6 +5786,7 @@ bool ata_link_offline(struct ata_link *link)
+ return ata_phys_link_offline(link) &&
+ (!slave || ata_phys_link_offline(slave));
+ }
++EXPORT_SYMBOL_GPL(ata_link_offline);
+
+ #ifdef CONFIG_PM
+ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
+@@ -5915,6 +5973,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
+ host->dev->power.power_state = mesg;
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_host_suspend);
+
+ /**
+ * ata_host_resume - resume host
+@@ -5926,6 +5985,7 @@ void ata_host_resume(struct ata_host *host)
+ {
+ host->dev->power.power_state = PMSG_ON;
+ }
++EXPORT_SYMBOL_GPL(ata_host_resume);
+ #endif
+
+ const struct device_type ata_port_type = {
+@@ -6140,11 +6200,13 @@ void ata_host_get(struct ata_host *host)
+ {
+ kref_get(&host->kref);
+ }
++EXPORT_SYMBOL_GPL(ata_host_get);
+
+ void ata_host_put(struct ata_host *host)
+ {
+ kref_put(&host->kref, ata_host_release);
+ }
++EXPORT_SYMBOL_GPL(ata_host_put);
+
+ /**
+ * ata_host_alloc - allocate and init basic ATA host resources
+@@ -6218,6 +6280,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports)
+ kfree(host);
+ return NULL;
+ }
++EXPORT_SYMBOL_GPL(ata_host_alloc);
+
+ /**
+ * ata_host_alloc_pinfo - alloc host and init with port_info array
+@@ -6266,6 +6329,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
+
+ return host;
+ }
++EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
+
+ /**
+ * ata_slave_link_init - initialize slave link
+@@ -6328,6 +6392,7 @@ int ata_slave_link_init(struct ata_port *ap)
+ ap->slave_link = link;
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_slave_link_init);
+
+ static void ata_host_stop(struct device *gendev, void *res)
+ {
+@@ -6476,6 +6541,7 @@ int ata_host_start(struct ata_host *host)
+ devres_free(start_dr);
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(ata_host_start);
+
+ /**
+ * ata_sas_host_init - Initialize a host struct for sas (ipr, libsas)
+@@ -6494,6 +6560,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
+ host->ops = ops;
+ kref_init(&host->kref);
+ }
++EXPORT_SYMBOL_GPL(ata_host_init);
+
+ void __ata_port_probe(struct ata_port *ap)
+ {
+@@ -6649,6 +6716,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
+ return rc;
+
+ }
++EXPORT_SYMBOL_GPL(ata_host_register);
+
+ /**
+ * ata_host_activate - start host, request IRQ and register it
+@@ -6711,6 +6779,7 @@ int ata_host_activate(struct ata_host *host, int irq,
+
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(ata_host_activate);
+
+ /**
+ * ata_port_detach - Detach ATA port in preparation of device removal
+@@ -6786,6 +6855,7 @@ void ata_host_detach(struct ata_host *host)
+ /* the host is dead now, dissociate ACPI */
+ ata_acpi_dissociate(host);
+ }
++EXPORT_SYMBOL_GPL(ata_host_detach);
+
+ #ifdef CONFIG_PCI
+
+@@ -6806,6 +6876,7 @@ void ata_pci_remove_one(struct pci_dev *pdev)
+
+ ata_host_detach(host);
+ }
++EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+
+ void ata_pci_shutdown_one(struct pci_dev *pdev)
+ {
+@@ -6826,6 +6897,7 @@ void ata_pci_shutdown_one(struct pci_dev *pdev)
+ ap->ops->port_stop(ap);
+ }
+ }
++EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
+
+ /* move to PCI subsystem */
+ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
+@@ -6860,6 +6932,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
+
+ return (tmp == bits->val) ? 1 : 0;
+ }
++EXPORT_SYMBOL_GPL(pci_test_config_bits);
+
+ #ifdef CONFIG_PM
+ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
+@@ -6870,6 +6943,7 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
+ if (mesg.event & PM_EVENT_SLEEP)
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
++EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
+
+ int ata_pci_device_do_resume(struct pci_dev *pdev)
+ {
+@@ -6888,6 +6962,7 @@ int ata_pci_device_do_resume(struct pci_dev *pdev)
+ pci_set_master(pdev);
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
+
+ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
+ {
+@@ -6902,6 +6977,7 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+
+ int ata_pci_device_resume(struct pci_dev *pdev)
+ {
+@@ -6913,8 +6989,8 @@ int ata_pci_device_resume(struct pci_dev *pdev)
+ ata_host_resume(host);
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(ata_pci_device_resume);
+ #endif /* CONFIG_PM */
+-
+ #endif /* CONFIG_PCI */
+
+ /**
+@@ -6936,6 +7012,7 @@ int ata_platform_remove_one(struct platform_device *pdev)
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_platform_remove_one);
+
+ static int __init ata_parse_force_one(char **cur,
+ struct ata_force_ent *force_ent,
+@@ -7162,6 +7239,7 @@ int ata_ratelimit(void)
+ {
+ return __ratelimit(&ratelimit);
+ }
++EXPORT_SYMBOL_GPL(ata_ratelimit);
+
+ /**
+ * ata_msleep - ATA EH owner aware msleep
+@@ -7194,6 +7272,7 @@ void ata_msleep(struct ata_port *ap, unsigned int msecs)
+ if (owns_eh)
+ ata_eh_acquire(ap);
+ }
++EXPORT_SYMBOL_GPL(ata_msleep);
+
+ /**
+ * ata_wait_register - wait until register value changes
+@@ -7240,6 +7319,7 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val,
+
+ return tmp;
+ }
++EXPORT_SYMBOL_GPL(ata_wait_register);
+
+ /**
+ * sata_lpm_ignore_phy_events - test if PHY event should be ignored
+@@ -7293,10 +7373,12 @@ struct ata_port_operations ata_dummy_port_ops = {
+ .sched_eh = ata_std_sched_eh,
+ .end_eh = ata_std_end_eh,
+ };
++EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
+
+ const struct ata_port_info ata_dummy_port_info = {
+ .port_ops = &ata_dummy_port_ops,
+ };
++EXPORT_SYMBOL_GPL(ata_dummy_port_info);
+
+ /*
+ * Utility print functions
+@@ -7364,127 +7446,3 @@ void ata_print_version(const struct device *dev, const char *version)
+ dev_printk(KERN_DEBUG, dev, "version %s\n", version);
+ }
+ EXPORT_SYMBOL(ata_print_version);
+-
+-/*
+- * libata is essentially a library of internal helper functions for
+- * low-level ATA host controller drivers. As such, the API/ABI is
+- * likely to change as new drivers are added and updated.
+- * Do not depend on ABI/API stability.
+- */
+-EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
+-EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
+-EXPORT_SYMBOL_GPL(sata_deb_timing_long);
+-EXPORT_SYMBOL_GPL(ata_base_port_ops);
+-EXPORT_SYMBOL_GPL(sata_port_ops);
+-EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
+-EXPORT_SYMBOL_GPL(ata_dummy_port_info);
+-EXPORT_SYMBOL_GPL(ata_link_next);
+-EXPORT_SYMBOL_GPL(ata_dev_next);
+-EXPORT_SYMBOL_GPL(ata_std_bios_param);
+-EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity);
+-EXPORT_SYMBOL_GPL(ata_host_init);
+-EXPORT_SYMBOL_GPL(ata_host_alloc);
+-EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
+-EXPORT_SYMBOL_GPL(ata_slave_link_init);
+-EXPORT_SYMBOL_GPL(ata_host_start);
+-EXPORT_SYMBOL_GPL(ata_host_register);
+-EXPORT_SYMBOL_GPL(ata_host_activate);
+-EXPORT_SYMBOL_GPL(ata_host_detach);
+-EXPORT_SYMBOL_GPL(ata_sg_init);
+-EXPORT_SYMBOL_GPL(ata_qc_complete);
+-EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
+-EXPORT_SYMBOL_GPL(atapi_cmd_type);
+-EXPORT_SYMBOL_GPL(ata_tf_to_fis);
+-EXPORT_SYMBOL_GPL(ata_tf_from_fis);
+-EXPORT_SYMBOL_GPL(ata_pack_xfermask);
+-EXPORT_SYMBOL_GPL(ata_unpack_xfermask);
+-EXPORT_SYMBOL_GPL(ata_xfer_mask2mode);
+-EXPORT_SYMBOL_GPL(ata_xfer_mode2mask);
+-EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
+-EXPORT_SYMBOL_GPL(ata_mode_string);
+-EXPORT_SYMBOL_GPL(ata_id_xfermask);
+-EXPORT_SYMBOL_GPL(ata_do_set_mode);
+-EXPORT_SYMBOL_GPL(ata_std_qc_defer);
+-EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
+-EXPORT_SYMBOL_GPL(ata_dev_disable);
+-EXPORT_SYMBOL_GPL(sata_set_spd);
+-EXPORT_SYMBOL_GPL(ata_wait_after_reset);
+-EXPORT_SYMBOL_GPL(sata_link_debounce);
+-EXPORT_SYMBOL_GPL(sata_link_resume);
+-EXPORT_SYMBOL_GPL(sata_link_scr_lpm);
+-EXPORT_SYMBOL_GPL(ata_std_prereset);
+-EXPORT_SYMBOL_GPL(sata_link_hardreset);
+-EXPORT_SYMBOL_GPL(sata_std_hardreset);
+-EXPORT_SYMBOL_GPL(ata_std_postreset);
+-EXPORT_SYMBOL_GPL(ata_dev_classify);
+-EXPORT_SYMBOL_GPL(ata_dev_pair);
+-EXPORT_SYMBOL_GPL(ata_ratelimit);
+-EXPORT_SYMBOL_GPL(ata_msleep);
+-EXPORT_SYMBOL_GPL(ata_wait_register);
+-EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
+-EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
+-EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
+-EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
+-EXPORT_SYMBOL_GPL(__ata_change_queue_depth);
+-EXPORT_SYMBOL_GPL(sata_scr_valid);
+-EXPORT_SYMBOL_GPL(sata_scr_read);
+-EXPORT_SYMBOL_GPL(sata_scr_write);
+-EXPORT_SYMBOL_GPL(sata_scr_write_flush);
+-EXPORT_SYMBOL_GPL(ata_link_online);
+-EXPORT_SYMBOL_GPL(ata_link_offline);
+-#ifdef CONFIG_PM
+-EXPORT_SYMBOL_GPL(ata_host_suspend);
+-EXPORT_SYMBOL_GPL(ata_host_resume);
+-#endif /* CONFIG_PM */
+-EXPORT_SYMBOL_GPL(ata_id_string);
+-EXPORT_SYMBOL_GPL(ata_id_c_string);
+-EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
+-EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+-
+-EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
+-EXPORT_SYMBOL_GPL(ata_timing_find_mode);
+-EXPORT_SYMBOL_GPL(ata_timing_compute);
+-EXPORT_SYMBOL_GPL(ata_timing_merge);
+-EXPORT_SYMBOL_GPL(ata_timing_cycle2mode);
+-
+-#ifdef CONFIG_PCI
+-EXPORT_SYMBOL_GPL(pci_test_config_bits);
+-EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
+-EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+-#ifdef CONFIG_PM
+-EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
+-EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
+-EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+-EXPORT_SYMBOL_GPL(ata_pci_device_resume);
+-#endif /* CONFIG_PM */
+-#endif /* CONFIG_PCI */
+-
+-EXPORT_SYMBOL_GPL(ata_platform_remove_one);
+-
+-EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
+-EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
+-EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
+-EXPORT_SYMBOL_GPL(ata_port_desc);
+-#ifdef CONFIG_PCI
+-EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
+-#endif /* CONFIG_PCI */
+-EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
+-EXPORT_SYMBOL_GPL(ata_link_abort);
+-EXPORT_SYMBOL_GPL(ata_port_abort);
+-EXPORT_SYMBOL_GPL(ata_port_freeze);
+-EXPORT_SYMBOL_GPL(sata_async_notification);
+-EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
+-EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
+-EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
+-EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
+-EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
+-EXPORT_SYMBOL_GPL(ata_do_eh);
+-EXPORT_SYMBOL_GPL(ata_std_error_handler);
+-
+-EXPORT_SYMBOL_GPL(ata_cable_40wire);
+-EXPORT_SYMBOL_GPL(ata_cable_80wire);
+-EXPORT_SYMBOL_GPL(ata_cable_unknown);
+-EXPORT_SYMBOL_GPL(ata_cable_ignore);
+-EXPORT_SYMBOL_GPL(ata_cable_sata);
+-EXPORT_SYMBOL_GPL(ata_host_get);
+-EXPORT_SYMBOL_GPL(ata_host_put);
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index 5c91183b5b736..fd054dc12a8c4 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -192,6 +192,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
+ __ata_ehi_pushv_desc(ehi, fmt, args);
+ va_end(args);
+ }
++EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
+
+ /**
+ * ata_ehi_push_desc - push error description with separator
+@@ -215,6 +216,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
+ __ata_ehi_pushv_desc(ehi, fmt, args);
+ va_end(args);
+ }
++EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
+
+ /**
+ * ata_ehi_clear_desc - clean error description
+@@ -230,6 +232,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi)
+ ehi->desc[0] = '\0';
+ ehi->desc_len = 0;
+ }
++EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
+
+ /**
+ * ata_port_desc - append port description
+@@ -257,9 +260,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...)
+ __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args);
+ va_end(args);
+ }
++EXPORT_SYMBOL_GPL(ata_port_desc);
+
+ #ifdef CONFIG_PCI
+-
+ /**
+ * ata_port_pbar_desc - append PCI BAR description
+ * @ap: target ATA port
+@@ -296,7 +299,7 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
+ ata_port_desc(ap, "%s 0x%llx", name,
+ start + (unsigned long long)offset);
+ }
+-
++EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
+ #endif /* CONFIG_PCI */
+
+ static int ata_lookup_timeout_table(u8 cmd)
+@@ -981,6 +984,7 @@ void ata_port_schedule_eh(struct ata_port *ap)
+ /* see: ata_std_sched_eh, unless you know better */
+ ap->ops->sched_eh(ap);
+ }
++EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
+
+ static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
+ {
+@@ -1023,6 +1027,7 @@ int ata_link_abort(struct ata_link *link)
+ {
+ return ata_do_link_abort(link->ap, link);
+ }
++EXPORT_SYMBOL_GPL(ata_link_abort);
+
+ /**
+ * ata_port_abort - abort all qc's on the port
+@@ -1040,6 +1045,7 @@ int ata_port_abort(struct ata_port *ap)
+ {
+ return ata_do_link_abort(ap, NULL);
+ }
++EXPORT_SYMBOL_GPL(ata_port_abort);
+
+ /**
+ * __ata_port_freeze - freeze port
+@@ -1096,6 +1102,7 @@ int ata_port_freeze(struct ata_port *ap)
+
+ return nr_aborted;
+ }
++EXPORT_SYMBOL_GPL(ata_port_freeze);
+
+ /**
+ * sata_async_notification - SATA async notification handler
+@@ -1169,6 +1176,7 @@ int sata_async_notification(struct ata_port *ap)
+ return 0;
+ }
+ }
++EXPORT_SYMBOL_GPL(sata_async_notification);
+
+ /**
+ * ata_eh_freeze_port - EH helper to freeze port
+@@ -1190,6 +1198,7 @@ void ata_eh_freeze_port(struct ata_port *ap)
+ __ata_port_freeze(ap);
+ spin_unlock_irqrestore(ap->lock, flags);
+ }
++EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
+
+ /**
+ * ata_port_thaw_port - EH helper to thaw port
+@@ -1218,6 +1227,7 @@ void ata_eh_thaw_port(struct ata_port *ap)
+
+ DPRINTK("ata%u port thawed\n", ap->print_id);
+ }
++EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
+
+ static void ata_eh_scsidone(struct scsi_cmnd *scmd)
+ {
+@@ -1252,6 +1262,7 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc)
+ scmd->retries = scmd->allowed;
+ __ata_eh_qc_complete(qc);
+ }
++EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
+
+ /**
+ * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
+@@ -1271,6 +1282,7 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc)
+ scmd->allowed++;
+ __ata_eh_qc_complete(qc);
+ }
++EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
+
+ /**
+ * ata_dev_disable - disable ATA device
+@@ -1297,6 +1309,7 @@ void ata_dev_disable(struct ata_device *dev)
+ */
+ ata_ering_clear(&dev->ering);
+ }
++EXPORT_SYMBOL_GPL(ata_dev_disable);
+
+ /**
+ * ata_eh_detach_dev - detach ATA device
+@@ -1739,6 +1752,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
+
+ ehc->i.err_mask &= ~AC_ERR_DEV;
+ }
++EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
+
+ /**
+ * ata_eh_analyze_tf - analyze taskfile of a failed qc
+@@ -4040,6 +4054,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
+
+ ata_eh_finish(ap);
+ }
++EXPORT_SYMBOL_GPL(ata_do_eh);
+
+ /**
+ * ata_std_error_handler - standard error handler
+@@ -4061,6 +4076,7 @@ void ata_std_error_handler(struct ata_port *ap)
+
+ ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
+ }
++EXPORT_SYMBOL_GPL(ata_std_error_handler);
+
+ #ifdef CONFIG_PM
+ /**
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 42309ceee21e9..c60d566c116f7 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -498,6 +498,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(ata_std_bios_param);
+
+ /**
+ * ata_scsi_unlock_native_capacity - unlock native capacity
+@@ -527,6 +528,7 @@ void ata_scsi_unlock_native_capacity(struct scsi_device *sdev)
+ spin_unlock_irqrestore(ap->lock, flags);
+ ata_port_wait_eh(ap);
+ }
++EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity);
+
+ /**
+ * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
+@@ -1335,6 +1337,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
+
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
+
+ /**
+ * ata_scsi_slave_destroy - SCSI device is about to be destroyed
+@@ -1374,6 +1377,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
+ q->dma_drain_buffer = NULL;
+ q->dma_drain_size = 0;
+ }
++EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
+
+ /**
+ * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth
+@@ -1417,6 +1421,7 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
+
+ return scsi_change_queue_depth(sdev, queue_depth);
+ }
++EXPORT_SYMBOL_GPL(__ata_change_queue_depth);
+
+ /**
+ * ata_scsi_change_queue_depth - SCSI callback for queue depth config
+@@ -1439,6 +1444,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+
+ return __ata_change_queue_depth(ap, sdev, queue_depth);
+ }
++EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
+
+ /**
+ * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
+@@ -4436,6 +4442,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
+
+ return rc;
+ }
++EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
+
+ /**
+ * ata_scsi_simulate - simulate SCSI command on ATA device
+@@ -4559,6 +4566,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
+
+ cmd->scsi_done(cmd);
+ }
++EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+
+ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
+ {
+--
+2.40.1
+
--- /dev/null
+From 363e575ead0d6ffb20739c373b2c406be5deccbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 02:07:02 +0000
+Subject: bpf: Fix issue in verifying allow_ptr_leaks
+
+From: Yafang Shao <laoar.shao@gmail.com>
+
+[ Upstream commit d75e30dddf73449bc2d10bb8e2f1a2c446bc67a2 ]
+
+After we converted the capabilities of our networking-bpf program from
+cap_sys_admin to cap_net_admin+cap_bpf, our networking-bpf program
+failed to start. Because it failed the bpf verifier, and the error log
+is "R3 pointer comparison prohibited".
+
+A simple reproducer as follows,
+
+SEC("cls-ingress")
+int ingress(struct __sk_buff *skb)
+{
+ struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
+
+ if ((long)(iph + 1) > (long)skb->data_end)
+ return TC_ACT_STOLEN;
+ return TC_ACT_OK;
+}
+
+Per discussion with Yonghong and Alexei [1], comparison of two packet
+pointers is not a pointer leak. This patch fixes it.
+
+Our local kernel is 6.1.y and we expect this fix to be backported to
+6.1.y, so stable is CCed.
+
+[1]. https://lore.kernel.org/bpf/CAADnVQ+Nmspr7Si+pxWn8zkE7hX-7s93ugwC+94aXSy4uQ9vBg@mail.gmail.com/
+
+Suggested-by: Yonghong Song <yonghong.song@linux.dev>
+Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
+Acked-by: Eduard Zingerman <eddyz87@gmail.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230823020703.3790-2-laoar.shao@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 530664693ac48..0676cf0d5d91d 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -6113,6 +6113,12 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+ return -EINVAL;
+ }
+
++ /* check src2 operand */
++ err = check_reg_arg(env, insn->dst_reg, SRC_OP);
++ if (err)
++ return err;
++
++ dst_reg = ®s[insn->dst_reg];
+ if (BPF_SRC(insn->code) == BPF_X) {
+ if (insn->imm != 0) {
+ verbose(env, "BPF_JMP/JMP32 uses reserved fields\n");
+@@ -6124,12 +6130,13 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+ if (err)
+ return err;
+
+- if (is_pointer_value(env, insn->src_reg)) {
++ src_reg = ®s[insn->src_reg];
++ if (!(reg_is_pkt_pointer_any(dst_reg) && reg_is_pkt_pointer_any(src_reg)) &&
++ is_pointer_value(env, insn->src_reg)) {
+ verbose(env, "R%d pointer comparison prohibited\n",
+ insn->src_reg);
+ return -EACCES;
+ }
+- src_reg = ®s[insn->src_reg];
+ } else {
+ if (insn->src_reg != BPF_REG_0) {
+ verbose(env, "BPF_JMP/JMP32 uses reserved fields\n");
+@@ -6137,12 +6144,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+ }
+ }
+
+- /* check src2 operand */
+- err = check_reg_arg(env, insn->dst_reg, SRC_OP);
+- if (err)
+- return err;
+-
+- dst_reg = ®s[insn->dst_reg];
+ is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
+
+ if (BPF_SRC(insn->code) == BPF_K)
+--
+2.40.1
+
--- /dev/null
+From 22a6712e82afda3ca57926c49bddbf00a0514871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2019 15:19:08 +0800
+Subject: clk: imx: clk-pll14xx: Make two variables static
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit 8f2d3c1759d19232edf1e9ef43d40a44e31493d6 ]
+
+Fix sparse warnings:
+
+drivers/clk/imx/clk-pll14xx.c:44:37:
+ warning: symbol 'imx_pll1416x_tbl' was not declared. Should it be static?
+drivers/clk/imx/clk-pll14xx.c:57:37:
+ warning: symbol 'imx_pll1443x_tbl' was not declared. Should it be static?
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Reviewed-by: Anson Huang <Anson.Huang@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 72d00e560d10 ("clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pll14xx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index c43e9653b4156..129a28c3366eb 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -41,7 +41,7 @@ struct clk_pll14xx {
+
+ #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
+
+-const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
++static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
+ PLL_1416X_RATE(1800000000U, 225, 3, 0),
+ PLL_1416X_RATE(1600000000U, 200, 3, 0),
+ PLL_1416X_RATE(1200000000U, 300, 3, 1),
+@@ -52,7 +52,7 @@ const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
+ PLL_1416X_RATE(600000000U, 300, 3, 2),
+ };
+
+-const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
++static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+ PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+ PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+--
+2.40.1
+
--- /dev/null
+From 32c96caaae61ea95b21ddcb5d14a13c8296e5158 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jan 2020 14:50:49 +0800
+Subject: clk: imx: pll14xx: Add new frequency entries for pll1443x table
+
+From: Anson Huang <Anson.Huang@nxp.com>
+
+[ Upstream commit 57795654fb553a78f07a9f92d87fb2582379cd93 ]
+
+Add new frequency entries to pll1443x table to meet different
+display settings requirement.
+
+Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 72d00e560d10 ("clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pll14xx.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index 129a28c3366eb..e7bf6babc28b4 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -53,8 +53,10 @@ static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
+ };
+
+ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
++ PLL_1443X_RATE(1039500000U, 173, 2, 1, 16384),
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+ PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
++ PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),
+ PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+ PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+ };
+--
+2.40.1
+
--- /dev/null
+From 9edd1ba5da4ad98d039a988d0251b6a7086bded9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 10:47:44 +0200
+Subject: clk: imx: pll14xx: dynamically configure PLL for
+ 393216000/361267200Hz
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit 72d00e560d10665e6139c9431956a87ded6e9880 ]
+
+Since commit b09c68dc57c9 ("clk: imx: pll14xx: Support dynamic rates"),
+the driver has the ability to dynamically compute PLL parameters to
+approximate the requested rates. This is not always used, because the
+logic is as follows:
+
+ - Check if the target rate is hardcoded in the frequency table
+ - Check if varying only kdiv is possible, so switch over is glitch free
+ - Compute rate dynamically by iterating over pdiv range
+
+If we skip the frequency table for the 1443x PLL, we find that the
+computed values differ to the hardcoded ones. This can be valid if the
+hardcoded values guarantee for example an earlier lock-in or if the
+divisors are chosen, so that other important rates are more likely to
+be reached glitch-free.
+
+For rates (393216000 and 361267200, this doesn't seem to be the case:
+They are only approximated by existing parameters (393215995 and
+361267196 Hz, respectively) and they aren't reachable glitch-free from
+other hardcoded frequencies. Dropping them from the table allows us
+to lock-in to these frequencies exactly.
+
+This is immediately noticeable because they are the assigned-clock-rates
+for IMX8MN_AUDIO_PLL1 and IMX8MN_AUDIO_PLL2, respectively and a look
+into clk_summary so far showed that they were a few Hz short of the target:
+
+imx8mn-board:~# grep audio_pll[12]_out /sys/kernel/debug/clk/clk_summary
+audio_pll2_out 0 0 0 361267196 0 0 50000 N
+audio_pll1_out 1 1 0 393215995 0 0 50000 Y
+
+and afterwards:
+
+imx8mn-board:~# grep audio_pll[12]_out /sys/kernel/debug/clk/clk_summary
+audio_pll2_out 0 0 0 361267200 0 0 50000 N
+audio_pll1_out 1 1 0 393216000 0 0 50000 Y
+
+This change is equivalent to adding following hardcoded values:
+
+ /* rate mdiv pdiv sdiv kdiv */
+ PLL_1443X_RATE(393216000, 655, 5, 3, 23593),
+ PLL_1443X_RATE(361267200, 497, 33, 0, -16882),
+
+Fixes: 053a4ffe2988 ("clk: imx: imx8mm: fix audio pll setting")
+Cc: stable@vger.kernel.org # v5.18+
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
+Link: https://lore.kernel.org/r/20230807084744.1184791-2-m.felsch@pengutronix.de
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pll14xx.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index e7bf6babc28b4..0dbe8c05af478 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -57,8 +57,6 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+ PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+ PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),
+- PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+- PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+ };
+
+ struct imx_pll14xx_clk imx_1443x_pll = {
+--
+2.40.1
+
--- /dev/null
+From a0c100cb5fee17cce5cd3c7831bc365573418ab4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jul 2020 17:33:27 -0400
+Subject: drm/amd/display: Fix LFC multiplier changing erratically
+
+From: Anthony Koo <Anthony.Koo@amd.com>
+
+[ Upstream commit 575da8db31572d1d8de572d0b6ffb113624c2f8f ]
+
+[Why]
+1. There is a calculation that is using frame_time_in_us instead of
+last_render_time_in_us to calculate whether choosing an LFC multiplier
+would cause the inserted frame duration to be outside of range.
+
+2. We do not handle unsigned integer subtraction correctly and it underflows
+to a really large value, which causes some logic errors.
+
+[How]
+1. Fix logic to calculate 'within range' using last_render_time_in_us
+2. Split out delta_from_mid_point_delta_in_us calculation to ensure
+we don't underflow and wrap around
+
+Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 07e388aab042 ("drm/amd/display: prevent potential division by zero errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/modules/freesync/freesync.c | 36 +++++++++++++++----
+ 1 file changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+index dbbd7d2765ea5..5835b968cac5d 100644
+--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
++++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+@@ -320,22 +320,44 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+
+ /* Choose number of frames to insert based on how close it
+ * can get to the mid point of the variable range.
++ * - Delta for CEIL: delta_from_mid_point_in_us_1
++ * - Delta for FLOOR: delta_from_mid_point_in_us_2
+ */
+- if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us &&
+- (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 ||
+- mid_point_frames_floor < 2)) {
++ if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) {
++ /* Check for out of range.
++ * If using CEIL produces a value that is out of range,
++ * then we are forced to use FLOOR.
++ */
++ frames_to_insert = mid_point_frames_floor;
++ } else if (mid_point_frames_floor < 2) {
++ /* Check if FLOOR would result in non-LFC. In this case
++ * choose to use CEIL
++ */
++ frames_to_insert = mid_point_frames_ceil;
++ } else if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
++ /* If choosing CEIL results in a frame duration that is
++ * closer to the mid point of the range.
++ * Choose CEIL
++ */
+ frames_to_insert = mid_point_frames_ceil;
+- delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
+- delta_from_mid_point_in_us_1;
+ } else {
++ /* If choosing FLOOR results in a frame duration that is
++ * closer to the mid point of the range.
++ * Choose FLOOR
++ */
+ frames_to_insert = mid_point_frames_floor;
+- delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 -
+- delta_from_mid_point_in_us_2;
+ }
+
+ /* Prefer current frame multiplier when BTR is enabled unless it drifts
+ * too far from the midpoint
+ */
++ if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
++ delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
++ delta_from_mid_point_in_us_1;
++ } else {
++ delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 -
++ delta_from_mid_point_in_us_2;
++ }
+ if (in_out_vrr->btr.frames_to_insert != 0 &&
+ delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) {
+ if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) <
+--
+2.40.1
+
--- /dev/null
+From c7d685580d9efc3e88f12cff3c2b5ac86d2580e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Sep 2023 13:27:22 -0400
+Subject: drm/amd/display: prevent potential division by zero errors
+
+From: Hamza Mahfooz <hamza.mahfooz@amd.com>
+
+[ Upstream commit 07e388aab042774f284a2ad75a70a194517cdad4 ]
+
+There are two places in apply_below_the_range() where it's possible for
+a divide by zero error to occur. So, to fix this make sure the divisor
+is non-zero before attempting the computation in both cases.
+
+Cc: stable@vger.kernel.org
+Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2637
+Fixes: a463b263032f ("drm/amd/display: Fix frames_to_insert math")
+Fixes: ded6119e825a ("drm/amd/display: Reinstate LFC optimization")
+Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+index 5835b968cac5d..ed5c9edfdcc56 100644
+--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
++++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+@@ -323,7 +323,9 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ * - Delta for CEIL: delta_from_mid_point_in_us_1
+ * - Delta for FLOOR: delta_from_mid_point_in_us_2
+ */
+- if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) {
++ if (mid_point_frames_ceil &&
++ (last_render_time_in_us / mid_point_frames_ceil) <
++ in_out_vrr->min_duration_in_us) {
+ /* Check for out of range.
+ * If using CEIL produces a value that is out of range,
+ * then we are forced to use FLOOR.
+@@ -370,8 +372,9 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ /* Either we've calculated the number of frames to insert,
+ * or we need to insert min duration frames
+ */
+- if (last_render_time_in_us / frames_to_insert <
+- in_out_vrr->min_duration_in_us){
++ if (frames_to_insert &&
++ (last_render_time_in_us / frames_to_insert) <
++ in_out_vrr->min_duration_in_us){
+ frames_to_insert -= (frames_to_insert > 1) ?
+ 1 : 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From d512d34f9e44e5fa0b0823bbaed7c2ae422321c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Nov 2019 16:06:57 -0500
+Subject: drm/amd/display: Reinstate LFC optimization
+
+From: Amanda Liu <amanda.liu@amd.com>
+
+[ Upstream commit ded6119e825aaf0bfc7f2a578b549d610da852a7 ]
+
+[why]
+We want to streamline the calculations made when entering LFC.
+Previously, the optimizations led to screen tearing and were backed out
+to unblock development.
+
+[how]
+Integrate other calculations parameters, as well as screen tearing,
+fixes with the original LFC calculation optimizations.
+
+Signed-off-by: Amanda Liu <amanda.liu@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 07e388aab042 ("drm/amd/display: prevent potential division by zero errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/modules/freesync/freesync.c | 32 +++++++++++--------
+ .../amd/display/modules/inc/mod_freesync.h | 1 +
+ 2 files changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+index 7d67cb2c61f04..dbbd7d2765ea5 100644
+--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
++++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+@@ -37,8 +37,8 @@
+ #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)
+ /* Number of elements in the render times cache array */
+ #define RENDER_TIMES_MAX_COUNT 10
+-/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
+-#define BTR_EXIT_MARGIN 2000
++/* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower limit) */
++#define BTR_MAX_MARGIN 2500
+ /* Threshold to change BTR multiplier (to avoid frequent changes) */
+ #define BTR_DRIFT_MARGIN 2000
+ /*Threshold to exit fixed refresh rate*/
+@@ -250,24 +250,22 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF;
+ unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF;
+ unsigned int frames_to_insert = 0;
+- unsigned int min_frame_duration_in_ns = 0;
+- unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us;
+ unsigned int delta_from_mid_point_delta_in_us;
+-
+- min_frame_duration_in_ns = ((unsigned int) (div64_u64(
+- (1000000000ULL * 1000000),
+- in_out_vrr->max_refresh_in_uhz)));
++ unsigned int max_render_time_in_us =
++ in_out_vrr->max_duration_in_us - in_out_vrr->btr.margin_in_us;
+
+ /* Program BTR */
+- if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) {
++ if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < max_render_time_in_us) {
+ /* Exit Below the Range */
+ if (in_out_vrr->btr.btr_active) {
+ in_out_vrr->btr.frame_counter = 0;
+ in_out_vrr->btr.btr_active = false;
+ }
+- } else if (last_render_time_in_us > max_render_time_in_us) {
++ } else if (last_render_time_in_us > (max_render_time_in_us + in_out_vrr->btr.margin_in_us / 2)) {
+ /* Enter Below the Range */
+- in_out_vrr->btr.btr_active = true;
++ if (!in_out_vrr->btr.btr_active) {
++ in_out_vrr->btr.btr_active = true;
++ }
+ }
+
+ /* BTR set to "not active" so disengage */
+@@ -323,7 +321,9 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ /* Choose number of frames to insert based on how close it
+ * can get to the mid point of the variable range.
+ */
+- if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
++ if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us &&
++ (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 ||
++ mid_point_frames_floor < 2)) {
+ frames_to_insert = mid_point_frames_ceil;
+ delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
+ delta_from_mid_point_in_us_1;
+@@ -339,7 +339,7 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ if (in_out_vrr->btr.frames_to_insert != 0 &&
+ delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) {
+ if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) <
+- in_out_vrr->max_duration_in_us) &&
++ max_render_time_in_us) &&
+ ((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) >
+ in_out_vrr->min_duration_in_us))
+ frames_to_insert = in_out_vrr->btr.frames_to_insert;
+@@ -792,6 +792,11 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
+ refresh_range = in_out_vrr->max_refresh_in_uhz -
+ in_out_vrr->min_refresh_in_uhz;
+
++ in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us -
++ 2 * in_out_vrr->min_duration_in_us;
++ if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN)
++ in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN;
++
+ in_out_vrr->supported = true;
+ }
+
+@@ -808,6 +813,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
+ in_out_vrr->btr.inserted_duration_in_us = 0;
+ in_out_vrr->btr.frames_to_insert = 0;
+ in_out_vrr->btr.frame_counter = 0;
++
+ in_out_vrr->btr.mid_point_in_us =
+ (in_out_vrr->min_duration_in_us +
+ in_out_vrr->max_duration_in_us) / 2;
+diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+index dc187844d10b1..dbe7835aabcf7 100644
+--- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+@@ -92,6 +92,7 @@ struct mod_vrr_params_btr {
+ uint32_t inserted_duration_in_us;
+ uint32_t frames_to_insert;
+ uint32_t frame_counter;
++ uint32_t margin_in_us;
+ };
+
+ struct mod_vrr_params_fixed_refresh {
+--
+2.40.1
+
--- /dev/null
+From e67a1c30e08c503961e8b1037277d258985c8839 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 11:56:51 -0700
+Subject: Input: i8042 - add quirk for TUXEDO Gemini 17 Gen1/Clevo PD70PN
+
+From: Werner Sembach <wse@tuxedocomputers.com>
+
+[ Upstream commit eb09074bdb05ffd6bfe77f8b4a41b76ef78c997b ]
+
+The touchpad of this device is both connected via PS/2 and i2c. This causes
+strange behavior when both driver fight for control. The easy fix is to
+prevent the PS/2 driver from accessing the mouse port as the full feature
+set of the touchpad is only supported in the i2c interface anyway.
+
+The strange behavior in this case is, that when an external screen is
+connected and the notebook is closed, the pointer on the external screen is
+moving to the lower right corner. When the notebook is opened again, this
+movement stops, but the touchpad clicks are unresponsive afterwards until
+reboot.
+
+Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230607173331.851192-1-wse@tuxedocomputers.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/serio/i8042-x86ia64io.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index 92fb2f72511e8..700655741bf28 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -1184,6 +1184,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+ },
++ /* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */
++ {
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"),
++ },
++ .driver_data = (void *)(SERIO_QUIRK_NOAUX)
++ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
+--
+2.40.1
+
--- /dev/null
+From 26feebd1d2da2e353a5a3760be1bbc7823ad820b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 19:24:46 -0700
+Subject: perf build: Update build rule for generated files
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 7822a8913f4c51c7d1aff793b525d60c3384fb5b ]
+
+The bison and flex generate C files from the source (.y and .l)
+files. When O= option is used, they are saved in a separate directory
+but the default build rule assumes the .C files are in the source
+directory. So it might read invalid file if there are generated files
+from an old version. The same is true for the pmu-events files.
+
+For example, the following command would cause a build failure:
+
+ $ git checkout v6.3
+ $ make -C tools/perf # build in the same directory
+
+ $ git checkout v6.5-rc2
+ $ mkdir build # create a build directory
+ $ make -C tools/perf O=build # build in a different directory but it
+ # refers files in the source directory
+
+Let's update the build rule to specify those cases explicitly to depend
+on the files in the output directory.
+
+Note that it's not a complete fix and it needs the next patch for the
+include path too.
+
+Fixes: 80eeb67fe577aa76 ("perf jevents: Program to convert JSON file")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Anup Sharma <anupnewsmail@gmail.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230728022447.1323563-1-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/build/Makefile.build | 10 ++++++++++
+ tools/perf/pmu-events/Build | 6 ++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build
+index cd72016c3cfa7..5a727094ae832 100644
+--- a/tools/build/Makefile.build
++++ b/tools/build/Makefile.build
+@@ -116,6 +116,16 @@ $(OUTPUT)%.s: %.c FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,cc_s_c)
+
++# bison and flex files are generated in the OUTPUT directory
++# so it needs a separate rule to depend on them properly
++$(OUTPUT)%-bison.o: $(OUTPUT)%-bison.c FORCE
++ $(call rule_mkdir)
++ $(call if_changed_dep,$(host)cc_o_c)
++
++$(OUTPUT)%-flex.o: $(OUTPUT)%-flex.c FORCE
++ $(call rule_mkdir)
++ $(call if_changed_dep,$(host)cc_o_c)
++
+ # Gather build data:
+ # obj-y - list of build objects
+ # subdir-y - list of directories to nest
+diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
+index 5ec5ce8c31bab..ea8c41f9c7398 100644
+--- a/tools/perf/pmu-events/Build
++++ b/tools/perf/pmu-events/Build
+@@ -25,3 +25,9 @@ $(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS_PY)
+ $(call rule_mkdir)
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(SRCARCH) pmu-events/arch $@
+ endif
++
++# pmu-events.c file is generated in the OUTPUT directory so it needs a
++# separate rule to depend on it properly
++$(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C)
++ $(call rule_mkdir)
++ $(call if_changed_dep,cc_o_c)
+--
+2.40.1
+
--- /dev/null
+From 1e36316a137ae3efc9a190db022f9dc8719f2060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 11:25:04 -0700
+Subject: perf jevents: Switch build to use jevents.py
+
+From: Ian Rogers <rogers.email@gmail.com>
+
+[ Upstream commit 00facc760903be6675870c2749e2cd72140e396e ]
+
+Generate pmu-events.c using jevents.py rather than the binary built from
+jevents.c.
+
+Add a new config variable NO_JEVENTS that is set when there is no
+architecture json or an appropriate python interpreter isn't present.
+
+When NO_JEVENTS is defined the file pmu-events/empty-pmu-events.c is
+copied and used as the pmu-events.c file.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: John Garry <john.garry@huawei.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ananth Narayan <ananth.narayan@amd.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Andrew Kilroy <andrew.kilroy@arm.com>
+Cc: Caleb Biggers <caleb.biggers@intel.com>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Ian Rogers <rogers.email@gmail.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kshipra Bopardikar <kshipra.bopardikar@intel.com>
+Cc: Like Xu <likexu@tencent.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nick Forrington <nick.forrington@arm.com>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Perry Taylor <perry.taylor@intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Qi Liu <liuqi115@huawei.com>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Sandipan Das <sandipan.das@amd.com>
+Cc: Santosh Shukla <santosh.shukla@amd.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
+Link: https://lore.kernel.org/r/20220629182505.406269-4-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 7822a8913f4c ("perf build: Update build rule for generated files")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Makefile.config | 19 +++
+ tools/perf/Makefile.perf | 1 +
+ tools/perf/pmu-events/Build | 13 +-
+ tools/perf/pmu-events/empty-pmu-events.c | 158 +++++++++++++++++++++++
+ 4 files changed, 189 insertions(+), 2 deletions(-)
+ create mode 100644 tools/perf/pmu-events/empty-pmu-events.c
+
+diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
+index e95281586f65e..b76800bbc632a 100644
+--- a/tools/perf/Makefile.config
++++ b/tools/perf/Makefile.config
+@@ -752,6 +752,25 @@ else
+ endif
+ endif
+
++ifneq ($(NO_JEVENTS),1)
++ ifeq ($(wildcard pmu-events/arch/$(SRCARCH)/mapfile.csv),)
++ NO_JEVENTS := 1
++ endif
++endif
++ifneq ($(NO_JEVENTS),1)
++ NO_JEVENTS := 0
++ ifndef PYTHON
++ $(warning No python interpreter disabling jevent generation)
++ NO_JEVENTS := 1
++ else
++ # jevents.py uses f-strings present in Python 3.6 released in Dec. 2016.
++ JEVENTS_PYTHON_GOOD := $(shell $(PYTHON) -c 'import sys;print("1" if(sys.version_info.major >= 3 and sys.version_info.minor >= 6) else "0")' 2> /dev/null)
++ ifneq ($(JEVENTS_PYTHON_GOOD), 1)
++ $(warning Python interpreter too old (older than 3.6) disabling jevent generation)
++ NO_JEVENTS := 1
++ endif
++ endif
++endif
+
+ ifndef NO_LIBBFD
+ ifeq ($(feature-libbfd), 1)
+diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
+index 961f5e4fd6566..b0314f31e5a37 100644
+--- a/tools/perf/Makefile.perf
++++ b/tools/perf/Makefile.perf
+@@ -584,6 +584,7 @@ JEVENTS := $(OUTPUT)pmu-events/jevents
+ JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o
+
+ PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o
++export NO_JEVENTS
+
+ export JEVENTS
+
+diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
+index a055dee6a46af..5ec5ce8c31bab 100644
+--- a/tools/perf/pmu-events/Build
++++ b/tools/perf/pmu-events/Build
+@@ -9,10 +9,19 @@ JSON = $(shell [ -d $(JDIR) ] && \
+ JDIR_TEST = pmu-events/arch/test
+ JSON_TEST = $(shell [ -d $(JDIR_TEST) ] && \
+ find $(JDIR_TEST) -name '*.json')
++JEVENTS_PY = pmu-events/jevents.py
+
+ #
+ # Locate/process JSON files in pmu-events/arch/
+ # directory and create tables in pmu-events.c.
+ #
+-$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS)
+- $(Q)$(call echo-cmd,gen)$(JEVENTS) $(SRCARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
++
++ifeq ($(NO_JEVENTS),1)
++$(OUTPUT)pmu-events/pmu-events.c: pmu-events/empty-pmu-events.c
++ $(call rule_mkdir)
++ $(Q)$(call echo-cmd,gen)cp $< $@
++else
++$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS_PY)
++ $(call rule_mkdir)
++ $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(SRCARCH) pmu-events/arch $@
++endif
+diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
+new file mode 100644
+index 0000000000000..77e655c6f1162
+--- /dev/null
++++ b/tools/perf/pmu-events/empty-pmu-events.c
+@@ -0,0 +1,158 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * An empty pmu-events.c file used when there is no architecture json files in
++ * arch or when the jevents.py script cannot be run.
++ *
++ * The test cpu/soc is provided for testing.
++ */
++#include "pmu-events/pmu-events.h"
++
++static const struct pmu_event pme_test_soc_cpu[] = {
++ {
++ .name = "l3_cache_rd",
++ .event = "event=0x40",
++ .desc = "L3 cache access, read",
++ .topic = "cache",
++ .long_desc = "Attributable Level 3 cache access, read",
++ },
++ {
++ .name = "segment_reg_loads.any",
++ .event = "event=0x6,period=200000,umask=0x80",
++ .desc = "Number of segment register loads",
++ .topic = "other",
++ },
++ {
++ .name = "dispatch_blocked.any",
++ .event = "event=0x9,period=200000,umask=0x20",
++ .desc = "Memory cluster signals to block micro-op dispatch for any reason",
++ .topic = "other",
++ },
++ {
++ .name = "eist_trans",
++ .event = "event=0x3a,period=200000,umask=0x0",
++ .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions",
++ .topic = "other",
++ },
++ {
++ .name = "uncore_hisi_ddrc.flux_wcmd",
++ .event = "event=0x2",
++ .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ",
++ .topic = "uncore",
++ .long_desc = "DDRC write commands",
++ .pmu = "hisi_sccl,ddrc",
++ },
++ {
++ .name = "unc_cbo_xsnp_response.miss_eviction",
++ .event = "event=0x22,umask=0x81",
++ .desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core. Unit: uncore_cbox ",
++ .topic = "uncore",
++ .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core",
++ .pmu = "uncore_cbox",
++ },
++ {
++ .name = "event-hyphen",
++ .event = "event=0xe0,umask=0x00",
++ .desc = "UNC_CBO_HYPHEN. Unit: uncore_cbox ",
++ .topic = "uncore",
++ .long_desc = "UNC_CBO_HYPHEN",
++ .pmu = "uncore_cbox",
++ },
++ {
++ .name = "event-two-hyph",
++ .event = "event=0xc0,umask=0x00",
++ .desc = "UNC_CBO_TWO_HYPH. Unit: uncore_cbox ",
++ .topic = "uncore",
++ .long_desc = "UNC_CBO_TWO_HYPH",
++ .pmu = "uncore_cbox",
++ },
++ {
++ .name = "uncore_hisi_l3c.rd_hit_cpipe",
++ .event = "event=0x7",
++ .desc = "Total read hits. Unit: hisi_sccl,l3c ",
++ .topic = "uncore",
++ .long_desc = "Total read hits",
++ .pmu = "hisi_sccl,l3c",
++ },
++ {
++ .name = "uncore_imc_free_running.cache_miss",
++ .event = "event=0x12",
++ .desc = "Total cache misses. Unit: uncore_imc_free_running ",
++ .topic = "uncore",
++ .long_desc = "Total cache misses",
++ .pmu = "uncore_imc_free_running",
++ },
++ {
++ .name = "uncore_imc.cache_hits",
++ .event = "event=0x34",
++ .desc = "Total cache hits. Unit: uncore_imc ",
++ .topic = "uncore",
++ .long_desc = "Total cache hits",
++ .pmu = "uncore_imc",
++ },
++ {
++ .name = "bp_l1_btb_correct",
++ .event = "event=0x8a",
++ .desc = "L1 BTB Correction",
++ .topic = "branch",
++ },
++ {
++ .name = "bp_l2_btb_correct",
++ .event = "event=0x8b",
++ .desc = "L2 BTB Correction",
++ .topic = "branch",
++ },
++ {
++ .name = 0,
++ .event = 0,
++ .desc = 0,
++ },
++};
++
++const struct pmu_events_map pmu_events_map[] = {
++ {
++ .cpuid = "testcpu",
++ .version = "v1",
++ .type = "core",
++ .table = pme_test_soc_cpu,
++ },
++ {
++ .cpuid = 0,
++ .version = 0,
++ .type = 0,
++ .table = 0,
++ },
++};
++
++static const struct pmu_event pme_test_soc_sys[] = {
++ {
++ .name = "sys_ddr_pmu.write_cycles",
++ .event = "event=0x2b",
++ .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ",
++ .compat = "v8",
++ .topic = "uncore",
++ .pmu = "uncore_sys_ddr_pmu",
++ },
++ {
++ .name = "sys_ccn_pmu.read_cycles",
++ .event = "config=0x2c",
++ .desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ",
++ .compat = "0x01",
++ .topic = "uncore",
++ .pmu = "uncore_sys_ccn_pmu",
++ },
++ {
++ .name = 0,
++ .event = 0,
++ .desc = 0,
++ },
++};
++
++const struct pmu_sys_events pmu_sys_event_tables[] = {
++ {
++ .table = pme_test_soc_sys,
++ .name = "pme_test_soc_sys",
++ },
++ {
++ .table = 0
++ },
++};
+--
+2.40.1
+
--- /dev/null
+From 01b9bcb37f64d218e091f1f0404bfea17eb08584 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 12:30:55 +0530
+Subject: scsi: qla2xxx: Fix deletion race condition
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 6dfe4344c168c6ca20fe7640649aacfcefcccb26 ]
+
+System crash when using debug kernel due to link list corruption. The cause
+of the link list corruption is due to session deletion was allowed to queue
+up twice. Here's the internal trace that show the same port was allowed to
+double queue for deletion on different cpu.
+
+20808683956 015 qla2xxx [0000:13:00.1]-e801:4: Scheduling sess ffff93ebf9306800 for deletion 50:06:0e:80:12:48:ff:50 fc4_type 1
+20808683957 027 qla2xxx [0000:13:00.1]-e801:4: Scheduling sess ffff93ebf9306800 for deletion 50:06:0e:80:12:48:ff:50 fc4_type 1
+
+Move the clearing/setting of deleted flag lock.
+
+Cc: stable@vger.kernel.org
+Fixes: 726b85487067 ("qla2xxx: Add framework for async fabric discovery")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Link: https://lore.kernel.org/r/20230714070104.40052-2-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 16 ++++++++++++++--
+ drivers/scsi/qla2xxx/qla_target.c | 12 ++++++------
+ 2 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 28ba87cd227a2..8a0ac87f70a9d 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -485,6 +485,7 @@ static
+ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
+ {
+ struct fc_port *fcport = ea->fcport;
++ unsigned long flags;
+
+ ql_dbg(ql_dbg_disc, vha, 0x20d2,
+ "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
+@@ -499,9 +500,15 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
+ ql_dbg(ql_dbg_disc, vha, 0x2066,
+ "%s %8phC: adisc fail: post delete\n",
+ __func__, ea->fcport->port_name);
++
++ spin_lock_irqsave(&vha->work_lock, flags);
+ /* deleted = 0 & logout_on_delete = force fw cleanup */
+- fcport->deleted = 0;
++ if (fcport->deleted == QLA_SESS_DELETED)
++ fcport->deleted = 0;
++
+ fcport->logout_on_delete = 1;
++ spin_unlock_irqrestore(&vha->work_lock, flags);
++
+ qlt_schedule_sess_for_deletion(ea->fcport);
+ return;
+ }
+@@ -1402,7 +1409,6 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
+
+ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+ ea->fcport->login_gen++;
+- ea->fcport->deleted = 0;
+ ea->fcport->logout_on_delete = 1;
+
+ if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) {
+@@ -5475,6 +5481,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
+ void
+ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
+ {
++ unsigned long flags;
++
+ if (IS_SW_RESV_ADDR(fcport->d_id))
+ return;
+
+@@ -5484,7 +5492,11 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
+ qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
+ fcport->login_retry = vha->hw->login_retry_count;
+ fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
++
++ spin_lock_irqsave(&vha->work_lock, flags);
+ fcport->deleted = 0;
++ spin_unlock_irqrestore(&vha->work_lock, flags);
++
+ if (vha->hw->current_topology == ISP_CFG_NL)
+ fcport->logout_on_delete = 0;
+ else
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index cb97565b6a333..a95ea2f70f97f 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -1046,10 +1046,6 @@ void qlt_free_session_done(struct work_struct *work)
+ (struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO);
+ }
+
+- spin_lock_irqsave(&vha->work_lock, flags);
+- sess->flags &= ~FCF_ASYNC_SENT;
+- spin_unlock_irqrestore(&vha->work_lock, flags);
+-
+ spin_lock_irqsave(&ha->tgt.sess_lock, flags);
+ if (sess->se_sess) {
+ sess->se_sess = NULL;
+@@ -1059,7 +1055,6 @@ void qlt_free_session_done(struct work_struct *work)
+
+ qla2x00_set_fcport_disc_state(sess, DSC_DELETED);
+ sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
+- sess->deleted = QLA_SESS_DELETED;
+
+ if (sess->login_succ && !IS_SW_RESV_ADDR(sess->d_id)) {
+ vha->fcport_count--;
+@@ -1111,7 +1106,12 @@ void qlt_free_session_done(struct work_struct *work)
+
+ sess->explicit_logout = 0;
+ spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
++
++ spin_lock_irqsave(&vha->work_lock, flags);
++ sess->flags &= ~FCF_ASYNC_SENT;
++ sess->deleted = QLA_SESS_DELETED;
+ sess->free_pending = 0;
++ spin_unlock_irqrestore(&vha->work_lock, flags);
+
+ ql_dbg(ql_dbg_disc, vha, 0xf001,
+ "Unregistration of sess %p %8phC finished fcp_cnt %d\n",
+@@ -1161,12 +1161,12 @@ void qlt_unreg_sess(struct fc_port *sess)
+ * management from being sent.
+ */
+ sess->flags |= FCF_ASYNC_SENT;
++ sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
+ spin_unlock_irqrestore(&sess->vha->work_lock, flags);
+
+ if (sess->se_sess)
+ vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
+
+- sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
+ qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND);
+ sess->last_rscn_gen = sess->rscn_gen;
+ sess->last_login_gen = sess->login_gen;
+--
+2.40.1
+
--- /dev/null
+From f3f0a2b6c156204c668041d109b3ed4b220e5e6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Dec 2019 14:06:08 -0800
+Subject: scsi: qla2xxx: Fix update_fcport for current_topology
+
+From: Himanshu Madhani <hmadhani@marvell.com>
+
+[ Upstream commit 89eb2e7e794da2691e5aca02ed102bb287e3575a ]
+
+logout_on_delete flag should not be set if the topology is Loop. This patch
+fixes unintentional logout during loop topology.
+
+Link: https://lore.kernel.org/r/20191217220617.28084-6-hmadhani@marvell.com
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 6dfe4344c168 ("scsi: qla2xxx: Fix deletion race condition")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index f6d5d77ea45bb..28ba87cd227a2 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -5485,7 +5485,10 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
+ fcport->login_retry = vha->hw->login_retry_count;
+ fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
+ fcport->deleted = 0;
+- fcport->logout_on_delete = 1;
++ if (vha->hw->current_topology == ISP_CFG_NL)
++ fcport->logout_on_delete = 0;
++ else
++ fcport->logout_on_delete = 1;
+ fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
+
+ switch (vha->hw->current_topology) {
+--
+2.40.1
+
netfilter-ipset-fix-race-between-ipset_cmd_create-an.patch
gpio-tb10x-fix-an-error-handling-path-in-tb10x_gpio_.patch
i2c-mux-demux-pinctrl-check-the-return-value-of-devm.patch
+input-i8042-add-quirk-for-tuxedo-gemini-17-gen1-clev.patch
+scsi-qla2xxx-fix-update_fcport-for-current_topology.patch
+scsi-qla2xxx-fix-deletion-race-condition.patch
+perf-jevents-switch-build-to-use-jevents.py.patch
+perf-build-update-build-rule-for-generated-files.patch
+clk-imx-clk-pll14xx-make-two-variables-static.patch
+clk-imx-pll14xx-add-new-frequency-entries-for-pll144.patch
+clk-imx-pll14xx-dynamically-configure-pll-for-393216.patch
+bpf-fix-issue-in-verifying-allow_ptr_leaks.patch
+drm-amd-display-reinstate-lfc-optimization.patch
+drm-amd-display-fix-lfc-multiplier-changing-erratica.patch
+drm-amd-display-prevent-potential-division-by-zero-e.patch
+ata-move-export_symbol_gpl-s-close-to-exported-code.patch
+ata-libata-disallow-dev-initiated-lpm-transitions-to.patch