All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5.15 000/107] 5.15.66-rc1 review
@ 2022-09-06 13:29 Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 001/107] drm/msm/dsi: fix the inconsistent indenting Greg Kroah-Hartman
                   ` (115 more replies)
  0 siblings, 116 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, slade

This is the start of the stable review cycle for the 5.15.66 release.
There are 107 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
or in the git tree and branch at:
	git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Linux 5.15.66-rc1

Johan Hovold <johan@kernel.org>
    USB: serial: ch341: fix disabled rx timer on older devices

Johan Hovold <johan@kernel.org>
    USB: serial: ch341: fix lost character on LCR updates

Johan Hovold <johan+linaro@kernel.org>
    usb: dwc3: disable USB core PHY management

Johan Hovold <johan+linaro@kernel.org>
    usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup

Johan Hovold <johan+linaro@kernel.org>
    usb: dwc3: fix PHY disable sequence

Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    kbuild: Add skip_encoding_btf_enum64 option to pahole

Jiri Olsa <jolsa@redhat.com>
    kbuild: Unify options for BTF generation for vmlinux and modules

Mazin Al Haddad <mazinalhaddad05@gmail.com>
    tty: n_gsm: add sanity check for gsm->receive in gsm_receive_buf()

Ville Syrjälä <ville.syrjala@linux.intel.com>
    drm/i915: Skip wm/ddb readout for disabled pipes

Diego Santa Cruz <Diego.SantaCruz@spinetix.com>
    drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk

Takashi Iwai <tiwai@suse.de>
    ALSA: seq: Fix data-race at module auto-loading

Takashi Iwai <tiwai@suse.de>
    ALSA: seq: oss: Fix data-race for max_midi_devs access

Kacper Michajłow <kasper93@gmail.com>
    ALSA: hda/realtek: Add speaker AMP init for Samsung laptops with ALC298

Miquel Raynal <miquel.raynal@bootlin.com>
    net: mac802154: Fix a condition in the receive path

Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    net: Use u64_stats_fetch_begin_irq() for stats fetch.

Nicolas Dichtel <nicolas.dichtel@6wind.com>
    ip: fix triggering of 'icmp redirect'

Siddh Raman Pant <code@siddh.me>
    wifi: mac80211: Fix UAF in ieee80211_scan_rx()

Siddh Raman Pant <code@siddh.me>
    wifi: mac80211: Don't finalize CSA in IBSS mode if state is disconnected

Isaac J. Manjarres <isaacmanjarres@google.com>
    driver core: Don't probe devices after bus_type.match() probe deferral

Krishna Kurapati <quic_kriskura@quicinc.com>
    usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS

Chunfeng Yun <chunfeng.yun@mediatek.com>
    usb: xhci-mtk: fix bandwidth release issue

Chunfeng Yun <chunfeng.yun@mediatek.com>
    usb: xhci-mtk: relax TT periodic bandwidth allocation

Alan Stern <stern@rowland.harvard.edu>
    USB: core: Prevent nested device-reset calls

Josh Poimboeuf <jpoimboe@kernel.org>
    s390: fix nospec table alignments

Gerald Schaefer <gerald.schaefer@linux.ibm.com>
    s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages

Witold Lipieta <witold.lipieta@thaumatec.com>
    usb-storage: Add ignore-residue quirk for NXP PN7462AU

Thierry GUIBERT <thierry.guibert@croix-rouge.fr>
    USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020)

Pawel Laszczak <pawell@cadence.com>
    usb: cdns3: fix incorrect handling TRB_SMM flag for ISOC transfer

Pawel Laszczak <pawell@cadence.com>
    usb: cdns3: fix issue with rearming ISO OUT endpoint

Heiner Kallweit <hkallweit1@gmail.com>
    usb: dwc2: fix wrong order of phy_power_on and phy_init

Badhri Jagan Sridharan <badhri@google.com>
    usb: typec: tcpm: Return ENOTSUPP for power supply prop writes

Utkarsh Patel <utkarsh.h.patel@intel.com>
    usb: typec: intel_pmc_mux: Add new ACPI ID for Meteor Lake IOM device

Pablo Sun <pablo.sun@mediatek.com>
    usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles

Slark Xiao <slark_xiao@163.com>
    USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode

Yonglin Tan <yonglin.tan@outlook.com>
    USB: serial: option: add Quectel EM060K modem

Yan Xinyu <sdlyyxy@bupt.edu.cn>
    USB: serial: option: add support for OPPO R11 diag port

Johan Hovold <johan@kernel.org>
    USB: serial: cp210x: add Decagon UCA device id

Mathias Nyman <mathias.nyman@linux.intel.com>
    xhci: Add grace period after xHC start to prevent premature runtime suspend.

Alan Stern <stern@rowland.harvard.edu>
    media: mceusb: Use new usb_control_msg_*() routines

Heikki Krogerus <heikki.krogerus@linux.intel.com>
    usb: dwc3: pci: Add support for Intel Raptor Lake

Mika Westerberg <mika.westerberg@linux.intel.com>
    thunderbolt: Use the actual buffer in tb_async_error()

SeongJae Park <sj@kernel.org>
    xen-blkfront: Cache feature_persistent value before advertisement

SeongJae Park <sj@kernel.org>
    xen-blkfront: Advertise feature-persistent as user requested

SeongJae Park <sj@kernel.org>
    xen-blkback: Advertise feature-persistent as user requested

Steven Price <steven.price@arm.com>
    mm: pagewalk: Fix race between unmap and page walker

Dan Carpenter <dan.carpenter@oracle.com>
    xen/grants: prevent integer overflow in gnttab_dma_alloc_pages()

Jim Mattson <jmattson@google.com>
    KVM: x86: Mask off unsupported and unknown bits of IA32_ARCH_CAPABILITIES

Haibo Chen <haibo.chen@nxp.com>
    gpio: pca953x: Add mutex_lock for regcache sync in PM

Armin Wolf <W_Armin@gmx.de>
    hwmon: (gpio-fan) Fix array out of bounds access

Stefan Wahren <stefan.wahren@i2se.com>
    clk: bcm: rpi: Add missing newline

Stefan Wahren <stefan.wahren@i2se.com>
    clk: bcm: rpi: Prevent out-of-bounds access

Christophe JAILLET <christophe.jaillet@wanadoo.fr>
    clk: bcm: rpi: Use correct order for the parameters of devm_kcalloc()

Stefan Wahren <stefan.wahren@i2se.com>
    clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate

Peter Robinson <pbrobinson@gmail.com>
    Input: rk805-pwrkey - fix module autoloading

Chen-Yu Tsai <wenst@chromium.org>
    clk: core: Fix runtime PM sequence in clk_core_unprepare()

Stephen Boyd <sboyd@kernel.org>
    Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops"

Chen-Yu Tsai <wenst@chromium.org>
    clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops

Colin Ian King <colin.i.king@gmail.com>
    drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported"

Jim Mattson <jmattson@google.com>
    KVM: VMX: Heed the 'msr' argument in msr_write_intercepted()

Enzo Matsumiya <ematsumiya@suse.de>
    cifs: fix small mempool leak in SMB2_negotiate()

Carlos Llamas <cmllamas@google.com>
    binder: fix alloc->vma_vm_mm null-ptr dereference

Carlos Llamas <cmllamas@google.com>
    binder: fix UAF of ref->proc caused by race condition

Adrian Hunter <adrian.hunter@intel.com>
    mmc: core: Fix inconsistent sd3_bus_mode at UHS-I SD voltage switch failure

Adrian Hunter <adrian.hunter@intel.com>
    mmc: core: Fix UHS-I SD 1.8V workaround branch

Niek Nooijens <niek.nooijens@omron.com>
    USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id

Johan Hovold <johan+linaro@kernel.org>
    misc: fastrpc: fix memory corruption on open

Johan Hovold <johan+linaro@kernel.org>
    misc: fastrpc: fix memory corruption on probe

Marcus Folkesson <marcus.folkesson@gmail.com>
    iio: adc: mcp3911: use correct formula for AD conversion

Matti Vaittinen <mazziesaccount@gmail.com>
    iio: ad7292: Prevent regulator double disable

Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
    Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag

Sherry Sun <sherry.sun@nxp.com>
    tty: serial: lpuart: disable flow control while waiting for the transmit engine to complete

Arnd Bergmann <arnd@arndb.de>
    musb: fix USB_MUSB_TUSB6010 dependency

Helge Deller <deller@gmx.de>
    vt: Clear selection before changing the font

Masahiro Yamada <masahiroy@kernel.org>
    powerpc: align syscall table for ppc32

Grzegorz Szymaszek <gszymaszek@short.pl>
    staging: r8188eu: add firmware dependency

Dan Carpenter <dan.carpenter@oracle.com>
    staging: rtl8712: fix use after free bugs

Shenwei Wang <shenwei.wang@nxp.com>
    serial: fsl_lpuart: RS485 RTS polariy is inverse

Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
    soundwire: qcom: fix device status array range

Yacan Liu <liuyacan@corp.netease.com>
    net/smc: Remove redundant refcount increase

Jakub Kicinski <kuba@kernel.org>
    Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb"

Eric Dumazet <edumazet@google.com>
    tcp: annotate data-race around challenge_timestamp

Toke Høiland-Jørgensen <toke@toke.dk>
    sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb

Cong Wang <cong.wang@bytedance.com>
    kcm: fix strp_init() order and cleanup

David Thompson <davthompson@nvidia.com>
    mlxbf_gige: compute MDIO period based on i1clk

Duoming Zhou <duoming@zju.edu.cn>
    ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler

Wang Hai <wanghai38@huawei.com>
    net/sched: fix netdevice reference leaks in attach_default_qdiscs()

Zhengchao Shao <shaozhengchao@huawei.com>
    net: sched: tbf: don't call qdisc_put() while holding tree lock

Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    net: dsa: xrs700x: Use irqsave variant for u64 stats update

Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
    openvswitch: fix memory leak at failed datapath creation

Florian Fainelli <f.fainelli@gmail.com>
    net: smsc911x: Stop and start PHY during suspend and resume

Casper Andersson <casper.casan@gmail.com>
    net: sparx5: fix handling uneven length packets in manual extraction

Mathias Nyman <mathias.nyman@linux.intel.com>
    Revert "xhci: turn off port power in shutdown"

Dan Carpenter <dan.carpenter@oracle.com>
    wifi: cfg80211: debugfs: fix return type in ht40allow_map_read()

Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
    ALSA: hda: intel-nhlt: Correct the handling of fmt_config flexible array

Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
    ALSA: hda: intel-nhlt: remove use of __func__ in dev_dbg

Arun R Murthy <arun.r.murthy@intel.com>
    drm/i915/display: avoid warnings when registering dual panel backlight

Jani Nikula <jani.nikula@intel.com>
    drm/i915/backlight: extract backlight code to a separate file

Lin Ma <linma@zju.edu.cn>
    ieee802154/adf7242: defer destroy_workqueue call

Pu Lehui <pulehui@huawei.com>
    bpf, cgroup: Fix kernel BUG in purge_effective_progs

YiFei Zhu <zhuyifei@google.com>
    bpf: Restrict bpf_sys_bpf to CAP_PERFMON

Liu Jian <liujian56@huawei.com>
    skmsg: Fix wrong last sg check in sk_msg_recvmsg()

Marcus Folkesson <marcus.folkesson@gmail.com>
    iio: adc: mcp3911: make use of the sign bit

Andy Shevchenko <andriy.shevchenko@linux.intel.com>
    platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask

Douglas Anderson <dianders@chromium.org>
    drm/msm/dsi: Fix number of regulators for SDM660

Douglas Anderson <dianders@chromium.org>
    drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg

Kuogee Hsieh <quic_khsieh@quicinc.com>
    drm/msm/dp: delete DP_RECOVERED_CLOCK_OUT_EN to fix tps4

sunliming <sunliming@kylinos.cn>
    drm/msm/dsi: fix the inconsistent indenting


-------------

Diffstat:

 Makefile                                           |    7 +-
 arch/powerpc/kernel/systbl.S                       |    1 +
 arch/riscv/mm/pageattr.c                           |    4 +-
 arch/s390/include/asm/hugetlb.h                    |    6 +-
 arch/s390/kernel/vmlinux.lds.S                     |    1 +
 arch/x86/kvm/vmx/vmx.c                             |    3 +-
 arch/x86/kvm/x86.c                                 |   25 +-
 drivers/android/binder.c                           |   12 +
 drivers/android/binder_alloc.c                     |    4 +-
 drivers/base/dd.c                                  |   10 +
 drivers/block/xen-blkback/common.h                 |    3 +
 drivers/block/xen-blkback/xenbus.c                 |    6 +-
 drivers/block/xen-blkfront.c                       |   20 +-
 drivers/clk/bcm/clk-raspberrypi.c                  |   13 +-
 drivers/clk/clk.c                                  |    3 +-
 drivers/gpio/gpio-pca953x.c                        |    8 +-
 drivers/gpu/drm/i915/Makefile                      |    1 +
 drivers/gpu/drm/i915/display/g4x_dp.c              |    2 +-
 drivers/gpu/drm/i915/display/icl_dsi.c             |    1 +
 drivers/gpu/drm/i915/display/intel_backlight.c     | 1776 ++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_backlight.h     |   51 +
 drivers/gpu/drm/i915/display/intel_connector.c     |    4 +-
 drivers/gpu/drm/i915/display/intel_ddi.c           |    2 +-
 drivers/gpu/drm/i915/display/intel_dp.c            |    1 +
 .../gpu/drm/i915/display/intel_dp_aux_backlight.c  |    2 +-
 drivers/gpu/drm/i915/display/intel_lvds.c          |    1 +
 drivers/gpu/drm/i915/display/intel_opregion.c      |    3 +-
 drivers/gpu/drm/i915/display/intel_panel.c         | 1767 +------------------
 drivers/gpu/drm/i915/display/intel_panel.h         |   34 +-
 drivers/gpu/drm/i915/display/intel_quirks.c        |    3 +
 drivers/gpu/drm/i915/display/vlv_dsi.c             |    1 +
 drivers/gpu/drm/i915/gvt/handlers.c                |    2 +-
 drivers/gpu/drm/i915/intel_pm.c                    |    8 +-
 drivers/gpu/drm/msm/dp/dp_ctrl.c                   |    2 +-
 drivers/gpu/drm/msm/dsi/dsi_cfg.c                  |    4 +-
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c              |    2 +-
 drivers/hwmon/gpio-fan.c                           |    3 +
 drivers/iio/adc/ad7292.c                           |    4 +-
 drivers/iio/adc/mcp3911.c                          |   19 +-
 drivers/input/joystick/iforce/iforce-serio.c       |    6 +-
 drivers/input/joystick/iforce/iforce-usb.c         |    8 +-
 drivers/input/joystick/iforce/iforce.h             |    6 +
 drivers/input/misc/rk805-pwrkey.c                  |    1 +
 drivers/media/rc/mceusb.c                          |   35 +-
 drivers/misc/fastrpc.c                             |   12 +-
 drivers/mmc/core/sd.c                              |   46 +-
 drivers/net/dsa/xrs700x/xrs700x.c                  |    5 +-
 drivers/net/ethernet/cortina/gemini.c              |   24 +-
 drivers/net/ethernet/google/gve/gve_ethtool.c      |   16 +-
 drivers/net/ethernet/google/gve/gve_main.c         |   12 +-
 drivers/net/ethernet/huawei/hinic/hinic_rx.c       |    4 +-
 drivers/net/ethernet/huawei/hinic/hinic_tx.c       |    4 +-
 .../net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h  |    4 +-
 .../ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c |  122 +-
 .../ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h |    2 +
 .../net/ethernet/microchip/sparx5/sparx5_packet.c  |    2 +
 .../net/ethernet/netronome/nfp/nfp_net_common.c    |    8 +-
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   |    8 +-
 drivers/net/ethernet/rocker/rocker_ofdpa.c         |    2 +-
 drivers/net/ethernet/smsc/smsc911x.c               |    6 +
 drivers/net/ieee802154/adf7242.c                   |    3 +-
 drivers/net/netdevsim/netdev.c                     |    4 +-
 drivers/platform/x86/pmc_atom.c                    |    2 +-
 drivers/soundwire/qcom.c                           |    6 +-
 drivers/staging/r8188eu/os_dep/os_intfs.c          |    1 +
 drivers/staging/rtl8712/rtl8712_cmd.c              |   36 -
 drivers/thunderbolt/ctl.c                          |    2 +-
 drivers/tty/n_gsm.c                                |    3 +-
 drivers/tty/serial/fsl_lpuart.c                    |    5 +-
 drivers/tty/vt/vt.c                                |   12 +-
 drivers/usb/cdns3/cdns3-gadget.c                   |    4 +-
 drivers/usb/class/cdc-acm.c                        |    3 +
 drivers/usb/core/hub.c                             |   10 +
 drivers/usb/dwc2/platform.c                        |    8 +-
 drivers/usb/dwc3/core.c                            |   19 +-
 drivers/usb/dwc3/dwc3-pci.c                        |    4 +
 drivers/usb/dwc3/dwc3-qcom.c                       |   14 +-
 drivers/usb/dwc3/host.c                            |   11 +
 drivers/usb/gadget/function/storage_common.c       |    6 +-
 drivers/usb/host/xhci-hub.c                        |   13 +-
 drivers/usb/host/xhci-mtk-sch.c                    |   15 +-
 drivers/usb/host/xhci.c                            |   19 +-
 drivers/usb/host/xhci.h                            |    4 +-
 drivers/usb/musb/Kconfig                           |    2 +-
 drivers/usb/serial/ch341.c                         |   16 +-
 drivers/usb/serial/cp210x.c                        |    1 +
 drivers/usb/serial/ftdi_sio.c                      |    2 +
 drivers/usb/serial/ftdi_sio_ids.h                  |    6 +
 drivers/usb/serial/option.c                        |   15 +
 drivers/usb/storage/unusual_devs.h                 |    7 +
 drivers/usb/typec/altmodes/displayport.c           |    4 +-
 drivers/usb/typec/mux/intel_pmc_mux.c              |    9 +-
 drivers/usb/typec/tcpm/tcpm.c                      |    7 +
 drivers/xen/grant-table.c                          |    3 +
 fs/cifs/smb2pdu.c                                  |   12 +-
 include/linux/platform_data/x86/pmc_atom.h         |    6 +-
 include/linux/usb.h                                |    2 +
 include/linux/usb/typec_dp.h                       |    5 +
 kernel/bpf/cgroup.c                                |    4 +-
 kernel/bpf/syscall.c                               |    2 +-
 mm/pagewalk.c                                      |   21 +-
 mm/ptdump.c                                        |    4 +-
 net/core/skmsg.c                                   |    4 +-
 net/ipv4/fib_frontend.c                            |    4 +-
 net/ipv4/tcp_input.c                               |    4 +-
 net/kcm/kcmsock.c                                  |   15 +-
 net/mac80211/ibss.c                                |    4 +
 net/mac80211/scan.c                                |   11 +-
 net/mac80211/sta_info.c                            |    8 +-
 net/mac802154/rx.c                                 |    2 +-
 net/mpls/af_mpls.c                                 |    4 +-
 net/openvswitch/datapath.c                         |    4 +-
 net/sched/sch_generic.c                            |   31 +-
 net/sched/sch_tbf.c                                |    4 +-
 net/smc/af_smc.c                                   |    1 -
 net/wireless/debugfs.c                             |    3 +-
 scripts/Makefile.modfinal                          |    2 +-
 scripts/link-vmlinux.sh                            |   11 +-
 scripts/pahole-flags.sh                            |   24 +
 sound/core/seq/oss/seq_oss_midi.c                  |    2 +
 sound/core/seq/seq_clientmgr.c                     |   12 +-
 sound/hda/intel-nhlt.c                             |   25 +-
 sound/pci/hda/patch_realtek.c                      |   63 +-
 123 files changed, 2550 insertions(+), 2172 deletions(-)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 001/107] drm/msm/dsi: fix the inconsistent indenting
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 002/107] drm/msm/dp: delete DP_RECOVERED_CLOCK_OUT_EN to fix tps4 Greg Kroah-Hartman
                   ` (114 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, kernel test robot, sunliming,
	Abhinav Kumar, Sasha Levin

From: sunliming <sunliming@kylinos.cn>

[ Upstream commit 2f25a1fb4ec516c5ad67afd754334b491b9f09a5 ]

Fix the inconsistent indenting in function msm_dsi_dphy_timing_calc_v3().

Fix the following smatch warnings:

drivers/gpu/drm/msm/dsi/phy/dsi_phy.c:350 msm_dsi_dphy_timing_calc_v3() warn: inconsistent indenting

Fixes: f1fa7ff44056 ("drm/msm/dsi: implement auto PHY timing calculator for 10nm PHY")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: sunliming <sunliming@kylinos.cn>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/494662/
Link: https://lore.kernel.org/r/20220719015622.646718-1-sunliming@kylinos.cn
Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index a878b8b079c64..6a917fe69a833 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -347,7 +347,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
 	} else {
 		timing->shared_timings.clk_pre =
 			linear_inter(tmax, tmin, pcnt2, 0, false);
-			timing->shared_timings.clk_pre_inc_by_2 = 0;
+		timing->shared_timings.clk_pre_inc_by_2 = 0;
 	}
 
 	timing->ta_go = 3;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 002/107] drm/msm/dp: delete DP_RECOVERED_CLOCK_OUT_EN to fix tps4
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 001/107] drm/msm/dsi: fix the inconsistent indenting Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 003/107] drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg Greg Kroah-Hartman
                   ` (113 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Kuogee Hsieh, Abhinav Kumar,
	Stephen Boyd, Dmitry Baryshkov, Sasha Levin

From: Kuogee Hsieh <quic_khsieh@quicinc.com>

[ Upstream commit 032d57960176ac01cc5adff5bcc5eb51317f8781 ]

Data Symbols scrambled is required for tps4 at link training 2.
Therefore SCRAMBLING_DISABLE bit should not be set for tps4 to
work.

RECOVERED_CLOCK_OUT_EN is for enable simple EYE test for jitter
measurement with minimal equipment for embedded applications purpose
and is not required to be set during normal operation. Current
implementation always have RECOVERED_CLOCK_OUT_EN bit set which
cause SCRAMBLING_DISABLE bit wrongly set at tps4 which prevent
tps4 from working.

This patch delete setting RECOVERED_CLOCK_OUT_EN to fix
SCRAMBLING_DISABLE be wrongly set at tps4.

Changes in v2:
-- fix Fixes tag

Changes in v3:
-- revise commit text

Changes in v4:
-- fix commit text newline

Changes in v5:
-- fix commit text line over 75 chars

Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com>

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/497194/
Link: https://lore.kernel.org/r/1660258670-4200-1-git-send-email-quic_khsieh@quicinc.com
Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/msm/dp/dp_ctrl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index b6f4ce2a48afe..6d9eec98e0d38 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1198,7 +1198,7 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl,
 	if (ret)
 		return ret;
 
-	dp_ctrl_train_pattern_set(ctrl, pattern | DP_RECOVERED_CLOCK_OUT_EN);
+	dp_ctrl_train_pattern_set(ctrl, pattern);
 
 	for (tries = 0; tries <= maximum_retries; tries++) {
 		drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 003/107] drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 001/107] drm/msm/dsi: fix the inconsistent indenting Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 002/107] drm/msm/dp: delete DP_RECOVERED_CLOCK_OUT_EN to fix tps4 Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 004/107] drm/msm/dsi: Fix number of regulators for SDM660 Greg Kroah-Hartman
                   ` (112 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Douglas Anderson, Dmitry Baryshkov,
	Abhinav Kumar, Sasha Levin

From: Douglas Anderson <dianders@chromium.org>

[ Upstream commit 1e00d6ac8a3422765bae37aeac2002dfd3c0bda6 ]

3 regulators are listed but the number 2 is specified. Fix it.

Fixes: 3a3ff88a0fc1 ("drm/msm/dsi: Add 8x96 info in dsi_cfg")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/496318/
Link: https://lore.kernel.org/r/20220804073608.v4.1.I1056ee3f77f71287f333279efe4c85f88d403f65@changeid
Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 96bbc8b6d0092..2981dd7c79cc8 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -109,7 +109,7 @@ static const char * const dsi_8996_bus_clk_names[] = {
 static const struct msm_dsi_config msm8996_dsi_cfg = {
 	.io_offset = DSI_6G_REG_SHIFT,
 	.reg_cfg = {
-		.num = 2,
+		.num = 3,
 		.regs = {
 			{"vdda", 18160, 1 },	/* 1.25 V */
 			{"vcca", 17000, 32 },	/* 0.925 V */
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 004/107] drm/msm/dsi: Fix number of regulators for SDM660
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (2 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 003/107] drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 005/107] platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask Greg Kroah-Hartman
                   ` (111 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Douglas Anderson, Dmitry Baryshkov,
	Marijn Suijten, Abhinav Kumar, Sasha Levin

From: Douglas Anderson <dianders@chromium.org>

[ Upstream commit a1653a75987749ba6dba94fa2e62f0f36b387d1a ]

1 regulator is listed but the number 2 is specified. This presumably
means we try to get a regulator with no name. Fix it.

Fixes: 462f7017a691 ("drm/msm/dsi: Fix DSI and DSI PHY regulator config from SDM660")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/496323/
Link: https://lore.kernel.org/r/20220804073608.v4.2.I94b3c3e412b7c208061349f05659e126483171b1@changeid
Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 2981dd7c79cc8..ce3901439c69c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -148,7 +148,7 @@ static const char * const dsi_sdm660_bus_clk_names[] = {
 static const struct msm_dsi_config sdm660_dsi_cfg = {
 	.io_offset = DSI_6G_REG_SHIFT,
 	.reg_cfg = {
-		.num = 2,
+		.num = 1,
 		.regs = {
 			{"vdda", 12560, 4 },	/* 1.2 V */
 		},
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 005/107] platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (3 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 004/107] drm/msm/dsi: Fix number of regulators for SDM660 Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 006/107] iio: adc: mcp3911: make use of the sign bit Greg Kroah-Hartman
                   ` (110 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Andy Shevchenko, Hans de Goede, Sasha Levin

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

[ Upstream commit 0a90ed8d0cfa29735a221eba14d9cb6c735d35b6 ]

On Intel hardware the SLP_TYPx bitfield occupies bits 10-12 as per ACPI
specification (see Table 4.13 "PM1 Control Registers Fixed Hardware
Feature Control Bits" for the details).

Fix the mask and other related definitions accordingly.

Fixes: 93e5eadd1f6e ("x86/platform: New Intel Atom SOC power management controller driver")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20220801113734.36131-1-andriy.shevchenko@linux.intel.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/platform/x86/pmc_atom.c            | 2 +-
 include/linux/platform_data/x86/pmc_atom.h | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index a9d2a4b98e570..4b0739f95f8b9 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -244,7 +244,7 @@ static void pmc_power_off(void)
 	pm1_cnt_port = acpi_base_addr + PM1_CNT;
 
 	pm1_cnt_value = inl(pm1_cnt_port);
-	pm1_cnt_value &= SLEEP_TYPE_MASK;
+	pm1_cnt_value &= ~SLEEP_TYPE_MASK;
 	pm1_cnt_value |= SLEEP_TYPE_S5;
 	pm1_cnt_value |= SLEEP_ENABLE;
 
diff --git a/include/linux/platform_data/x86/pmc_atom.h b/include/linux/platform_data/x86/pmc_atom.h
index 022bcea9edec5..99a9b09dc839d 100644
--- a/include/linux/platform_data/x86/pmc_atom.h
+++ b/include/linux/platform_data/x86/pmc_atom.h
@@ -7,6 +7,8 @@
 #ifndef PMC_ATOM_H
 #define PMC_ATOM_H
 
+#include <linux/bits.h>
+
 /* ValleyView Power Control Unit PCI Device ID */
 #define	PCI_DEVICE_ID_VLV_PMC	0x0F1C
 /* CherryTrail Power Control Unit PCI Device ID */
@@ -139,9 +141,9 @@
 #define	ACPI_MMIO_REG_LEN	0x100
 
 #define	PM1_CNT			0x4
-#define	SLEEP_TYPE_MASK		0xFFFFECFF
+#define	SLEEP_TYPE_MASK		GENMASK(12, 10)
 #define	SLEEP_TYPE_S5		0x1C00
-#define	SLEEP_ENABLE		0x2000
+#define	SLEEP_ENABLE		BIT(13)
 
 extern int pmc_atom_read(int offset, u32 *value);
 extern int pmc_atom_write(int offset, u32 value);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 006/107] iio: adc: mcp3911: make use of the sign bit
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (4 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 005/107] platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 007/107] skmsg: Fix wrong last sg check in sk_msg_recvmsg() Greg Kroah-Hartman
                   ` (109 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Marcus Folkesson, Andy Shevchenko,
	Jonathan Cameron, Sasha Levin

From: Marcus Folkesson <marcus.folkesson@gmail.com>

[ Upstream commit 8f89e33bf040bbef66386c426198622180233178 ]

The device supports negative values as well.

Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20220722130726.7627-2-marcus.folkesson@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/iio/adc/mcp3911.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index e573da5397bb3..81eeb00842112 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -111,6 +111,8 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
 		if (ret)
 			goto out;
 
+		*val = sign_extend32(*val, 23);
+
 		ret = IIO_VAL_INT;
 		break;
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 007/107] skmsg: Fix wrong last sg check in sk_msg_recvmsg()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (5 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 006/107] iio: adc: mcp3911: make use of the sign bit Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 008/107] bpf: Restrict bpf_sys_bpf to CAP_PERFMON Greg Kroah-Hartman
                   ` (108 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Liu Jian, Daniel Borkmann,
	John Fastabend, Jakub Sitnicki, Sasha Levin

From: Liu Jian <liujian56@huawei.com>

[ Upstream commit 583585e48d965338e73e1eb383768d16e0922d73 ]

Fix one kernel NULL pointer dereference as below:

[  224.462334] Call Trace:
[  224.462394]  __tcp_bpf_recvmsg+0xd3/0x380
[  224.462441]  ? sock_has_perm+0x78/0xa0
[  224.462463]  tcp_bpf_recvmsg+0x12e/0x220
[  224.462494]  inet_recvmsg+0x5b/0xd0
[  224.462534]  __sys_recvfrom+0xc8/0x130
[  224.462574]  ? syscall_trace_enter+0x1df/0x2e0
[  224.462606]  ? __do_page_fault+0x2de/0x500
[  224.462635]  __x64_sys_recvfrom+0x24/0x30
[  224.462660]  do_syscall_64+0x5d/0x1d0
[  224.462709]  entry_SYSCALL_64_after_hwframe+0x65/0xca

In commit 9974d37ea75f ("skmsg: Fix invalid last sg check in
sk_msg_recvmsg()"), we change last sg check to sg_is_last(),
but in sockmap redirection case (without stream_parser/stream_verdict/
skb_verdict), we did not mark the end of the scatterlist. Check the
sk_msg_alloc, sk_msg_page_add, and bpf_msg_push_data functions, they all
do not mark the end of sg. They are expected to use sg.end for end
judgment. So the judgment of '(i != msg_rx->sg.end)' is added back here.

Fixes: 9974d37ea75f ("skmsg: Fix invalid last sg check in sk_msg_recvmsg()")
Signed-off-by: Liu Jian <liujian56@huawei.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
Link: https://lore.kernel.org/bpf/20220809094915.150391-1-liujian56@huawei.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/skmsg.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 4ddcfac344984..054073c7cbb95 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -462,7 +462,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
 
 			if (copied == len)
 				break;
-		} while (!sg_is_last(sge));
+		} while ((i != msg_rx->sg.end) && !sg_is_last(sge));
 
 		if (unlikely(peek)) {
 			msg_rx = sk_psock_next_msg(psock, msg_rx);
@@ -472,7 +472,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
 		}
 
 		msg_rx->sg.start = i;
-		if (!sge->length && sg_is_last(sge)) {
+		if (!sge->length && (i == msg_rx->sg.end || sg_is_last(sge))) {
 			msg_rx = sk_psock_dequeue_msg(psock);
 			kfree_sk_msg(msg_rx);
 		}
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 008/107] bpf: Restrict bpf_sys_bpf to CAP_PERFMON
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (6 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 007/107] skmsg: Fix wrong last sg check in sk_msg_recvmsg() Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 009/107] bpf, cgroup: Fix kernel BUG in purge_effective_progs Greg Kroah-Hartman
                   ` (107 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, YiFei Zhu, Daniel Borkmann,
	Alexei Starovoitov, Sasha Levin

From: YiFei Zhu <zhuyifei@google.com>

[ Upstream commit 14b20b784f59bdd95f6f1cfb112c9818bcec4d84 ]

The verifier cannot perform sufficient validation of any pointers passed
into bpf_attr and treats them as integers rather than pointers. The helper
will then read from arbitrary pointers passed into it. Restrict the helper
to CAP_PERFMON since the security model in BPF of arbitrary kernel read is
CAP_BPF + CAP_PERFMON.

Fixes: af2ac3e13e45 ("bpf: Prepare bpf syscall to be used from kernel and user space.")
Signed-off-by: YiFei Zhu <zhuyifei@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20220816205517.682470-1-zhuyifei@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/syscall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 48e02a725563f..99ce46f518893 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -4785,7 +4785,7 @@ syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
 	switch (func_id) {
 	case BPF_FUNC_sys_bpf:
-		return &bpf_sys_bpf_proto;
+		return !perfmon_capable() ? NULL : &bpf_sys_bpf_proto;
 	case BPF_FUNC_btf_find_by_name_kind:
 		return &bpf_btf_find_by_name_kind_proto;
 	case BPF_FUNC_sys_close:
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 009/107] bpf, cgroup: Fix kernel BUG in purge_effective_progs
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (7 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 008/107] bpf: Restrict bpf_sys_bpf to CAP_PERFMON Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 010/107] ieee802154/adf7242: defer destroy_workqueue call Greg Kroah-Hartman
                   ` (106 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Pu Lehui, Daniel Borkmann,
	Andrii Nakryiko, Sasha Levin

From: Pu Lehui <pulehui@huawei.com>

[ Upstream commit 7d6620f107bae6ed687ff07668e8e8f855487aa9 ]

Syzkaller reported a triggered kernel BUG as follows:

  ------------[ cut here ]------------
  kernel BUG at kernel/bpf/cgroup.c:925!
  invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
  CPU: 1 PID: 194 Comm: detach Not tainted 5.19.0-14184-g69dac8e431af #8
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
  rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
  RIP: 0010:__cgroup_bpf_detach+0x1f2/0x2a0
  Code: 00 e8 92 60 30 00 84 c0 75 d8 4c 89 e0 31 f6 85 f6 74 19 42 f6 84
  28 48 05 00 00 02 75 0e 48 8b 80 c0 00 00 00 48 85 c0 75 e5 <0f> 0b 48
  8b 0c5
  RSP: 0018:ffffc9000055bdb0 EFLAGS: 00000246
  RAX: 0000000000000000 RBX: ffff888100ec0800 RCX: ffffc900000f1000
  RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff888100ec4578
  RBP: 0000000000000000 R08: ffff888100ec0800 R09: 0000000000000040
  R10: 0000000000000000 R11: 0000000000000000 R12: ffff888100ec4000
  R13: 000000000000000d R14: ffffc90000199000 R15: ffff888100effb00
  FS:  00007f68213d2b80(0000) GS:ffff88813bc80000(0000)
  knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 000055f74a0e5850 CR3: 0000000102836000 CR4: 00000000000006e0
  Call Trace:
   <TASK>
   cgroup_bpf_prog_detach+0xcc/0x100
   __sys_bpf+0x2273/0x2a00
   __x64_sys_bpf+0x17/0x20
   do_syscall_64+0x3b/0x90
   entry_SYSCALL_64_after_hwframe+0x63/0xcd
  RIP: 0033:0x7f68214dbcb9
  Code: 08 44 89 e0 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 48 89 f8 48 89
  f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01
  f0 ff8
  RSP: 002b:00007ffeb487db68 EFLAGS: 00000246 ORIG_RAX: 0000000000000141
  RAX: ffffffffffffffda RBX: 000000000000000b RCX: 00007f68214dbcb9
  RDX: 0000000000000090 RSI: 00007ffeb487db70 RDI: 0000000000000009
  RBP: 0000000000000003 R08: 0000000000000012 R09: 0000000b00000003
  R10: 00007ffeb487db70 R11: 0000000000000246 R12: 00007ffeb487dc20
  R13: 0000000000000004 R14: 0000000000000001 R15: 000055f74a1011b0
   </TASK>
  Modules linked in:
  ---[ end trace 0000000000000000 ]---

Repetition steps:

For the following cgroup tree,

  root
   |
  cg1
   |
  cg2

  1. attach prog2 to cg2, and then attach prog1 to cg1, both bpf progs
     attach type is NONE or OVERRIDE.
  2. write 1 to /proc/thread-self/fail-nth for failslab.
  3. detach prog1 for cg1, and then kernel BUG occur.

Failslab injection will cause kmalloc fail and fall back to
purge_effective_progs. The problem is that cg2 have attached another prog,
so when go through cg2 layer, iteration will add pos to 1, and subsequent
operations will be skipped by the following condition, and cg will meet
NULL in the end.

  `if (pos && !(cg->bpf.flags[atype] & BPF_F_ALLOW_MULTI))`

The NULL cg means no link or prog match, this is as expected, and it's not
a bug. So here just skip the no match situation.

Fixes: 4c46091ee985 ("bpf: Fix KASAN use-after-free Read in compute_effective_progs")
Signed-off-by: Pu Lehui <pulehui@huawei.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20220813134030.1972696-1-pulehui@huawei.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/cgroup.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 565e4c59db660..eb3e787a3a977 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -709,8 +709,10 @@ static void purge_effective_progs(struct cgroup *cgrp, struct bpf_prog *prog,
 				pos++;
 			}
 		}
+
+		/* no link or prog match, skip the cgroup of this layer */
+		continue;
 found:
-		BUG_ON(!cg);
 		progs = rcu_dereference_protected(
 				desc->bpf.effective[atype],
 				lockdep_is_held(&cgroup_mutex));
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 010/107] ieee802154/adf7242: defer destroy_workqueue call
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (8 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 009/107] bpf, cgroup: Fix kernel BUG in purge_effective_progs Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file Greg Kroah-Hartman
                   ` (105 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Lin Ma, Michael Hennerich,
	Stefan Schmidt, Sasha Levin

From: Lin Ma <linma@zju.edu.cn>

[ Upstream commit afe7116f6d3b888778ed6d95e3cf724767b9aedf ]

There is a possible race condition (use-after-free) like below

  (FREE)                     |  (USE)
  adf7242_remove             |  adf7242_channel
   cancel_delayed_work_sync  |
    destroy_workqueue (1)    |   adf7242_cmd_rx
                             |    mod_delayed_work (2)
                             |

The root cause for this race is that the upper layer (ieee802154) is
unaware of this detaching event and the function adf7242_channel can
be called without any checks.

To fix this, we can add a flag write at the beginning of adf7242_remove
and add flag check in adf7242_channel. Or we can just defer the
destructive operation like other commit 3e0588c291d6 ("hamradio: defer
ax25 kfree after unregister_netdev") which let the
ieee802154_unregister_hw() to handle the synchronization. This patch
takes the second option.

Fixes: 58e9683d1475 ("net: ieee802154: adf7242: Fix OCL calibration
runs")
Signed-off-by: Lin Ma <linma@zju.edu.cn>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Link: https://lore.kernel.org/r/20220808034224.12642-1-linma@zju.edu.cn
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ieee802154/adf7242.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c
index 7db9cbd0f5ded..07adbeec19787 100644
--- a/drivers/net/ieee802154/adf7242.c
+++ b/drivers/net/ieee802154/adf7242.c
@@ -1310,10 +1310,11 @@ static int adf7242_remove(struct spi_device *spi)
 
 	debugfs_remove_recursive(lp->debugfs_root);
 
+	ieee802154_unregister_hw(lp->hw);
+
 	cancel_delayed_work_sync(&lp->work);
 	destroy_workqueue(lp->wqueue);
 
-	ieee802154_unregister_hw(lp->hw);
 	mutex_destroy(&lp->bmux);
 	ieee802154_free_hw(lp->hw);
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (9 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 010/107] ieee802154/adf7242: defer destroy_workqueue call Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 22:13   ` Lyude Paul
  2022-09-06 13:29 ` [PATCH 5.15 012/107] drm/i915/display: avoid warnings when registering dual panel backlight Greg Kroah-Hartman
                   ` (104 subsequent siblings)
  115 siblings, 1 reply; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Lyude Paul, Jani Nikula, Sasha Levin

From: Jani Nikula <jani.nikula@intel.com>

[ Upstream commit 6cc42fbeb150ff33b17cbf108713ca4be23994d8 ]

In a long overdue refactoring, split out backlight code to new
intel_backlight.[ch]. Simple code movement, leave renames for follow-up
work. No functional changes.

Cc: Lyude Paul <lyude@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/97d310848f03061473b9b2328e2c5c4dcf263cfa.1629888677.git.jani.nikula@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/i915/Makefile                 |    1 +
 drivers/gpu/drm/i915/display/g4x_dp.c         |    2 +-
 drivers/gpu/drm/i915/display/icl_dsi.c        |    1 +
 .../gpu/drm/i915/display/intel_backlight.c    | 1778 +++++++++++++++++
 .../gpu/drm/i915/display/intel_backlight.h    |   51 +
 .../gpu/drm/i915/display/intel_connector.c    |    4 +-
 drivers/gpu/drm/i915/display/intel_ddi.c      |    2 +-
 drivers/gpu/drm/i915/display/intel_dp.c       |    1 +
 .../drm/i915/display/intel_dp_aux_backlight.c |    2 +-
 drivers/gpu/drm/i915/display/intel_lvds.c     |    1 +
 drivers/gpu/drm/i915/display/intel_opregion.c |    3 +-
 drivers/gpu/drm/i915/display/intel_panel.c    | 1767 +---------------
 drivers/gpu/drm/i915/display/intel_panel.h    |   34 +-
 drivers/gpu/drm/i915/display/vlv_dsi.c        |    1 +
 14 files changed, 1843 insertions(+), 1805 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_backlight.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_backlight.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 26cf754229451..9d371be7dc5cd 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -249,6 +249,7 @@ i915-y += \
 	display/g4x_dp.o \
 	display/g4x_hdmi.o \
 	display/icl_dsi.o \
+	display/intel_backlight.o \
 	display/intel_crt.o \
 	display/intel_ddi.o \
 	display/intel_ddi_buf_trans.o \
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index de0f358184aa3..29c0eca647e34 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -7,6 +7,7 @@
 
 #include "g4x_dp.h"
 #include "intel_audio.h"
+#include "intel_backlight.h"
 #include "intel_connector.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
@@ -16,7 +17,6 @@
 #include "intel_fifo_underrun.h"
 #include "intel_hdmi.h"
 #include "intel_hotplug.h"
-#include "intel_panel.h"
 #include "intel_pps.h"
 #include "intel_sideband.h"
 
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 638a00b2dc2d2..2601873e15466 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -29,6 +29,7 @@
 #include <drm/drm_mipi_dsi.h>
 
 #include "intel_atomic.h"
+#include "intel_backlight.h"
 #include "intel_combo_phy.h"
 #include "intel_connector.h"
 #include "intel_crtc.h"
diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c
new file mode 100644
index 0000000000000..4b0086ee48519
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_backlight.c
@@ -0,0 +1,1778 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include <linux/kernel.h>
+#include <linux/pwm.h>
+
+#include "intel_backlight.h"
+#include "intel_connector.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_dp_aux_backlight.h"
+#include "intel_dsi_dcs_backlight.h"
+#include "intel_panel.h"
+
+/**
+ * scale - scale values from one range to another
+ * @source_val: value in range [@source_min..@source_max]
+ * @source_min: minimum legal value for @source_val
+ * @source_max: maximum legal value for @source_val
+ * @target_min: corresponding target value for @source_min
+ * @target_max: corresponding target value for @source_max
+ *
+ * Return @source_val in range [@source_min..@source_max] scaled to range
+ * [@target_min..@target_max].
+ */
+static u32 scale(u32 source_val,
+		 u32 source_min, u32 source_max,
+		 u32 target_min, u32 target_max)
+{
+	u64 target_val;
+
+	WARN_ON(source_min > source_max);
+	WARN_ON(target_min > target_max);
+
+	/* defensive */
+	source_val = clamp(source_val, source_min, source_max);
+
+	/* avoid overflows */
+	target_val = mul_u32_u32(source_val - source_min,
+				 target_max - target_min);
+	target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min);
+	target_val += target_min;
+
+	return target_val;
+}
+
+/*
+ * Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
+ * to [hw_min..hw_max].
+ */
+static u32 clamp_user_to_hw(struct intel_connector *connector,
+			    u32 user_level, u32 user_max)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 hw_level;
+
+	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
+	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
+
+	return hw_level;
+}
+
+/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
+static u32 scale_hw_to_user(struct intel_connector *connector,
+			    u32 hw_level, u32 user_max)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	return scale(hw_level, panel->backlight.min, panel->backlight.max,
+		     0, user_max);
+}
+
+u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
+
+	if (dev_priv->params.invert_brightness < 0)
+		return val;
+
+	if (dev_priv->params.invert_brightness > 0 ||
+	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
+		return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min;
+	}
+
+	return val;
+}
+
+void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val);
+	panel->backlight.pwm_funcs->set(conn_state, val);
+}
+
+u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	drm_WARN_ON_ONCE(&dev_priv->drm,
+			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
+
+	val = scale(val, panel->backlight.min, panel->backlight.max,
+		    panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
+
+	return intel_panel_invert_pwm_level(connector, val);
+}
+
+u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	drm_WARN_ON_ONCE(&dev_priv->drm,
+			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
+
+	if (dev_priv->params.invert_brightness > 0 ||
+	    (dev_priv->params.invert_brightness == 0 && dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS))
+		val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min);
+
+	return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max,
+		     panel->backlight.min, panel->backlight.max);
+}
+
+static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 val;
+
+	val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+	if (DISPLAY_VER(dev_priv) < 4)
+		val >>= 1;
+
+	if (panel->backlight.combination_mode) {
+		u8 lbpc;
+
+		pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc);
+		val *= lbpc;
+	}
+
+	return val;
+}
+
+static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
+		return 0;
+
+	return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	return intel_de_read(dev_priv,
+			     BXT_BLC_PWM_DUTY(panel->backlight.controller));
+}
+
+static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct intel_panel *panel = &connector->panel;
+	struct pwm_state state;
+
+	pwm_get_state(panel->backlight.pwm, &state);
+	return pwm_get_relative_duty_cycle(&state, 100);
+}
+
+static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level);
+}
+
+static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level);
+}
+
+static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 tmp, mask;
+
+	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
+
+	if (panel->backlight.combination_mode) {
+		u8 lbpc;
+
+		lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1;
+		level /= lbpc;
+		pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc);
+	}
+
+	if (DISPLAY_VER(dev_priv) == 4) {
+		mask = BACKLIGHT_DUTY_CYCLE_MASK;
+	} else {
+		level <<= 1;
+		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
+	}
+
+	tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask;
+	intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level);
+}
+
+static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
+	u32 tmp;
+
+	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level);
+}
+
+static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	intel_de_write(dev_priv,
+		       BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
+}
+
+static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
+
+	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
+	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
+}
+
+static void
+intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level);
+
+	panel->backlight.funcs->set(conn_state, level);
+}
+
+/* set backlight brightness to level in range [0..max], assuming hw min is
+ * respected.
+ */
+void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
+				    u32 user_level, u32 user_max)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 hw_level;
+
+	/*
+	 * Lack of crtc may occur during driver init because
+	 * connection_mutex isn't held across the entire backlight
+	 * setup + modeset readout, and the BIOS can issue the
+	 * requests at any time.
+	 */
+	if (!panel->backlight.present || !conn_state->crtc)
+		return;
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
+
+	hw_level = clamp_user_to_hw(connector, user_level, user_max);
+	panel->backlight.level = hw_level;
+
+	if (panel->backlight.device)
+		panel->backlight.device->props.brightness =
+			scale_hw_to_user(connector,
+					 panel->backlight.level,
+					 panel->backlight.device->props.max_brightness);
+
+	if (panel->backlight.enabled)
+		intel_panel_actually_set_backlight(conn_state, hw_level);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	intel_panel_set_pwm_level(old_conn_state, level);
+
+	/*
+	 * Although we don't support or enable CPU PWM with LPT/SPT based
+	 * systems, it may have been enabled prior to loading the
+	 * driver. Disable to avoid warnings on LCPLL disable.
+	 *
+	 * This needs rework if we need to add support for CPU PWM on PCH split
+	 * platforms.
+	 */
+	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+	if (tmp & BLM_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "cpu backlight was enabled, disabling\n");
+		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
+			       tmp & ~BLM_PWM_ENABLE);
+	}
+
+	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	intel_panel_set_pwm_level(old_conn_state, val);
+
+	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
+
+	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
+{
+	intel_panel_set_pwm_level(old_conn_state, val);
+}
+
+static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
+{
+	struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev);
+	u32 tmp;
+
+	intel_panel_set_pwm_level(old_conn_state, val);
+
+	tmp = intel_de_read(dev_priv, BLC_PWM_CTL2);
+	intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
+}
+
+static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe;
+	u32 tmp;
+
+	intel_panel_set_pwm_level(old_conn_state, val);
+
+	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
+	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
+		       tmp & ~BLM_PWM_ENABLE);
+}
+
+static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 tmp;
+
+	intel_panel_set_pwm_level(old_conn_state, val);
+
+	tmp = intel_de_read(dev_priv,
+			    BXT_BLC_PWM_CTL(panel->backlight.controller));
+	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
+		       tmp & ~BXT_BLC_PWM_ENABLE);
+
+	if (panel->backlight.controller == 1) {
+		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
+		val &= ~UTIL_PIN_ENABLE;
+		intel_de_write(dev_priv, UTIL_PIN_CTL, val);
+	}
+}
+
+static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 tmp;
+
+	intel_panel_set_pwm_level(old_conn_state, val);
+
+	tmp = intel_de_read(dev_priv,
+			    BXT_BLC_PWM_CTL(panel->backlight.controller));
+	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
+		       tmp & ~BXT_BLC_PWM_ENABLE);
+}
+
+static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct intel_panel *panel = &connector->panel;
+
+	panel->backlight.pwm_state.enabled = false;
+	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
+}
+
+void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state)
+{
+	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	if (!panel->backlight.present)
+		return;
+
+	/*
+	 * Do not disable backlight on the vga_switcheroo path. When switching
+	 * away from i915, the other client may depend on i915 to handle the
+	 * backlight. This will leave the backlight on unnecessarily when
+	 * another client is not activated.
+	 */
+	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "Skipping backlight disable on vga switch\n");
+		return;
+	}
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	if (panel->backlight.device)
+		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
+	panel->backlight.enabled = false;
+	panel->backlight.funcs->disable(old_conn_state, 0);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pch_ctl1, pch_ctl2, schicken;
+
+	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
+	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
+		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
+	}
+
+	if (HAS_PCH_LPT(dev_priv)) {
+		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2);
+		if (panel->backlight.alternate_pwm_increment)
+			schicken |= LPT_PWM_GRANULARITY;
+		else
+			schicken &= ~LPT_PWM_GRANULARITY;
+		intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken);
+	} else {
+		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1);
+		if (panel->backlight.alternate_pwm_increment)
+			schicken |= SPT_PWM_GRANULARITY;
+		else
+			schicken &= ~SPT_PWM_GRANULARITY;
+		intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken);
+	}
+
+	pch_ctl2 = panel->backlight.pwm_level_max << 16;
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
+
+	pch_ctl1 = 0;
+	if (panel->backlight.active_low_pwm)
+		pch_ctl1 |= BLM_PCH_POLARITY;
+
+	/* After LPT, override is the default. */
+	if (HAS_PCH_LPT(dev_priv))
+		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
+
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
+	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
+		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
+
+	/* This won't stick until the above enable. */
+	intel_panel_set_pwm_level(conn_state, level);
+}
+
+static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
+
+	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+	if (cpu_ctl2 & BLM_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n");
+		cpu_ctl2 &= ~BLM_PWM_ENABLE;
+		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
+	}
+
+	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
+	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
+		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
+	}
+
+	if (cpu_transcoder == TRANSCODER_EDP)
+		cpu_ctl2 = BLM_TRANSCODER_EDP;
+	else
+		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
+	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
+	intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2);
+	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
+
+	/* This won't stick until the above enable. */
+	intel_panel_set_pwm_level(conn_state, level);
+
+	pch_ctl2 = panel->backlight.pwm_level_max << 16;
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
+
+	pch_ctl1 = 0;
+	if (panel->backlight.active_low_pwm)
+		pch_ctl1 |= BLM_PCH_POLARITY;
+
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
+	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
+	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
+		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
+}
+
+static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, freq;
+
+	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
+	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
+		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
+		intel_de_write(dev_priv, BLC_PWM_CTL, 0);
+	}
+
+	freq = panel->backlight.pwm_level_max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
+
+	ctl = freq << 17;
+	if (panel->backlight.combination_mode)
+		ctl |= BLM_LEGACY_MODE;
+	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
+		ctl |= BLM_POLARITY_PNV;
+
+	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
+	intel_de_posting_read(dev_priv, BLC_PWM_CTL);
+
+	/* XXX: combine this into above write? */
+	intel_panel_set_pwm_level(conn_state, level);
+
+	/*
+	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
+	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
+	 * that has backlight.
+	 */
+	if (DISPLAY_VER(dev_priv) == 2)
+		intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
+}
+
+static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
+	u32 ctl, ctl2, freq;
+
+	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
+	if (ctl2 & BLM_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
+	}
+
+	freq = panel->backlight.pwm_level_max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
+
+	ctl = freq << 16;
+	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
+
+	ctl2 = BLM_PIPE(pipe);
+	if (panel->backlight.combination_mode)
+		ctl2 |= BLM_COMBINATION_MODE;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
+	intel_de_posting_read(dev_priv, BLC_PWM_CTL2);
+	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
+
+	intel_panel_set_pwm_level(conn_state, level);
+}
+
+static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+	u32 ctl, ctl2;
+
+	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
+	if (ctl2 & BLM_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
+	}
+
+	ctl = panel->backlight.pwm_level_max << 16;
+	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl);
+
+	/* XXX: combine this into above write? */
+	intel_panel_set_pwm_level(conn_state, level);
+
+	ctl2 = 0;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
+	intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
+	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
+		       ctl2 | BLM_PWM_ENABLE);
+}
+
+static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+	u32 pwm_ctl, val;
+
+	/* Controller 1 uses the utility pin. */
+	if (panel->backlight.controller == 1) {
+		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
+		if (val & UTIL_PIN_ENABLE) {
+			drm_dbg_kms(&dev_priv->drm,
+				    "util pin already enabled\n");
+			val &= ~UTIL_PIN_ENABLE;
+			intel_de_write(dev_priv, UTIL_PIN_CTL, val);
+		}
+
+		val = 0;
+		if (panel->backlight.util_pin_active_low)
+			val |= UTIL_PIN_POLARITY;
+		intel_de_write(dev_priv, UTIL_PIN_CTL,
+			       val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
+	}
+
+	pwm_ctl = intel_de_read(dev_priv,
+				BXT_BLC_PWM_CTL(panel->backlight.controller));
+	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
+		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
+		intel_de_write(dev_priv,
+			       BXT_BLC_PWM_CTL(panel->backlight.controller),
+			       pwm_ctl);
+	}
+
+	intel_de_write(dev_priv,
+		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
+		       panel->backlight.pwm_level_max);
+
+	intel_panel_set_pwm_level(conn_state, level);
+
+	pwm_ctl = 0;
+	if (panel->backlight.active_low_pwm)
+		pwm_ctl |= BXT_BLC_PWM_POLARITY;
+
+	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
+		       pwm_ctl);
+	intel_de_posting_read(dev_priv,
+			      BXT_BLC_PWM_CTL(panel->backlight.controller));
+	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
+		       pwm_ctl | BXT_BLC_PWM_ENABLE);
+}
+
+static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pwm_ctl;
+
+	pwm_ctl = intel_de_read(dev_priv,
+				BXT_BLC_PWM_CTL(panel->backlight.controller));
+	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
+		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
+		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
+		intel_de_write(dev_priv,
+			       BXT_BLC_PWM_CTL(panel->backlight.controller),
+			       pwm_ctl);
+	}
+
+	intel_de_write(dev_priv,
+		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
+		       panel->backlight.pwm_level_max);
+
+	intel_panel_set_pwm_level(conn_state, level);
+
+	pwm_ctl = 0;
+	if (panel->backlight.active_low_pwm)
+		pwm_ctl |= BXT_BLC_PWM_POLARITY;
+
+	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
+		       pwm_ctl);
+	intel_de_posting_read(dev_priv,
+			      BXT_BLC_PWM_CTL(panel->backlight.controller));
+	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
+		       pwm_ctl | BXT_BLC_PWM_ENABLE);
+}
+
+static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
+				     const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct intel_panel *panel = &connector->panel;
+
+	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
+	panel->backlight.pwm_state.enabled = true;
+	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
+}
+
+static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
+					   const struct drm_connector_state *conn_state)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct intel_panel *panel = &connector->panel;
+
+	WARN_ON(panel->backlight.max == 0);
+
+	if (panel->backlight.level <= panel->backlight.min) {
+		panel->backlight.level = panel->backlight.max;
+		if (panel->backlight.device)
+			panel->backlight.device->props.brightness =
+				scale_hw_to_user(connector,
+						 panel->backlight.level,
+						 panel->backlight.device->props.max_brightness);
+	}
+
+	panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level);
+	panel->backlight.enabled = true;
+	if (panel->backlight.device)
+		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
+}
+
+void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+
+	if (!panel->backlight.present)
+		return;
+
+	drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe));
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	__intel_panel_enable_backlight(crtc_state, conn_state);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
+static u32 intel_panel_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 val = 0;
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	if (panel->backlight.enabled)
+		val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector));
+
+	mutex_unlock(&dev_priv->backlight_lock);
+
+	drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val);
+	return val;
+}
+
+/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
+static u32 scale_user_to_hw(struct intel_connector *connector,
+			    u32 user_level, u32 user_max)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	return scale(user_level, 0, user_max,
+		     panel->backlight.min, panel->backlight.max);
+}
+
+/* set backlight brightness to level in range [0..max], scaling wrt hw min */
+static void intel_panel_set_backlight(const struct drm_connector_state *conn_state,
+				      u32 user_level, u32 user_max)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 hw_level;
+
+	if (!panel->backlight.present)
+		return;
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
+
+	hw_level = scale_user_to_hw(connector, user_level, user_max);
+	panel->backlight.level = hw_level;
+
+	if (panel->backlight.enabled)
+		intel_panel_actually_set_backlight(conn_state, hw_level);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+static int intel_backlight_device_update_status(struct backlight_device *bd)
+{
+	struct intel_connector *connector = bl_get_data(bd);
+	struct intel_panel *panel = &connector->panel;
+	struct drm_device *dev = connector->base.dev;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
+		      bd->props.brightness, bd->props.max_brightness);
+	intel_panel_set_backlight(connector->base.state, bd->props.brightness,
+				  bd->props.max_brightness);
+
+	/*
+	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
+	 * backlight class device does not make it easy to differentiate
+	 * between callbacks for brightness and bl_power, so our backlight_power
+	 * callback needs to take this into account.
+	 */
+	if (panel->backlight.enabled) {
+		if (panel->backlight.power) {
+			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
+				bd->props.brightness != 0;
+			panel->backlight.power(connector, enable);
+		}
+	} else {
+		bd->props.power = FB_BLANK_POWERDOWN;
+	}
+
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+	return 0;
+}
+
+static int intel_backlight_device_get_brightness(struct backlight_device *bd)
+{
+	struct intel_connector *connector = bl_get_data(bd);
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	intel_wakeref_t wakeref;
+	int ret = 0;
+
+	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
+		u32 hw_level;
+
+		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+
+		hw_level = intel_panel_get_backlight(connector);
+		ret = scale_hw_to_user(connector,
+				       hw_level, bd->props.max_brightness);
+
+		drm_modeset_unlock(&dev->mode_config.connection_mutex);
+	}
+
+	return ret;
+}
+
+static const struct backlight_ops intel_backlight_device_ops = {
+	.update_status = intel_backlight_device_update_status,
+	.get_brightness = intel_backlight_device_get_brightness,
+};
+
+int intel_backlight_device_register(struct intel_connector *connector)
+{
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	struct backlight_properties props;
+	struct backlight_device *bd;
+	const char *name;
+	int ret = 0;
+
+	if (WARN_ON(panel->backlight.device))
+		return -ENODEV;
+
+	if (!panel->backlight.present)
+		return 0;
+
+	WARN_ON(panel->backlight.max == 0);
+
+	memset(&props, 0, sizeof(props));
+	props.type = BACKLIGHT_RAW;
+
+	/*
+	 * Note: Everything should work even if the backlight device max
+	 * presented to the userspace is arbitrarily chosen.
+	 */
+	props.max_brightness = panel->backlight.max;
+	props.brightness = scale_hw_to_user(connector,
+					    panel->backlight.level,
+					    props.max_brightness);
+
+	if (panel->backlight.enabled)
+		props.power = FB_BLANK_UNBLANK;
+	else
+		props.power = FB_BLANK_POWERDOWN;
+
+	name = kstrdup("intel_backlight", GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	bd = backlight_device_register(name, connector->base.kdev, connector,
+				       &intel_backlight_device_ops, &props);
+
+	/*
+	 * Using the same name independent of the drm device or connector
+	 * prevents registration of multiple backlight devices in the
+	 * driver. However, we need to use the default name for backward
+	 * compatibility. Use unique names for subsequent backlight devices as a
+	 * fallback when the default name already exists.
+	 */
+	if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) {
+		kfree(name);
+		name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
+				 i915->drm.primary->index, connector->base.name);
+		if (!name)
+			return -ENOMEM;
+
+		bd = backlight_device_register(name, connector->base.kdev, connector,
+					       &intel_backlight_device_ops, &props);
+	}
+
+	if (IS_ERR(bd)) {
+		drm_err(&i915->drm,
+			"[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n",
+			connector->base.base.id, connector->base.name, name, PTR_ERR(bd));
+		ret = PTR_ERR(bd);
+		goto out;
+	}
+
+	panel->backlight.device = bd;
+
+	drm_dbg_kms(&i915->drm,
+		    "[CONNECTOR:%d:%s] backlight device %s registered\n",
+		    connector->base.base.id, connector->base.name, name);
+
+out:
+	kfree(name);
+
+	return ret;
+}
+
+void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	if (panel->backlight.device) {
+		backlight_device_unregister(panel->backlight.device);
+		panel->backlight.device = NULL;
+	}
+}
+#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+/*
+ * CNP: PWM clock frequency is 19.2 MHz or 24 MHz.
+ *      PWM increment = 1
+ */
+static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
+				 pwm_freq_hz);
+}
+
+/*
+ * BXT: PWM clock frequency = 19.2 MHz.
+ */
+static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
+}
+
+/*
+ * SPT: This value represents the period of the PWM stream in clock periods
+ * multiplied by 16 (default increment) or 128 (alternate increment selected in
+ * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
+ */
+static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 mul;
+
+	if (panel->backlight.alternate_pwm_increment)
+		mul = 128;
+	else
+		mul = 16;
+
+	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
+}
+
+/*
+ * LPT: This value represents the period of the PWM stream in clock periods
+ * multiplied by 128 (default increment) or 16 (alternate increment, selected in
+ * LPT SOUTH_CHICKEN2 register bit 5).
+ */
+static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 mul, clock;
+
+	if (panel->backlight.alternate_pwm_increment)
+		mul = 16;
+	else
+		mul = 128;
+
+	if (HAS_PCH_LPT_H(dev_priv))
+		clock = MHz(135); /* LPT:H */
+	else
+		clock = MHz(24); /* LPT:LP */
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
+}
+
+/*
+ * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
+ * display raw clocks multiplied by 128.
+ */
+static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
+				 pwm_freq_hz * 128);
+}
+
+/*
+ * Gen2: This field determines the number of time base events (display core
+ * clock frequency/32) in total for a complete cycle of modulated backlight
+ * control.
+ *
+ * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
+ * divided by 32.
+ */
+static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int clock;
+
+	if (IS_PINEVIEW(dev_priv))
+		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
+	else
+		clock = KHz(dev_priv->cdclk.hw.cdclk);
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
+}
+
+/*
+ * Gen4: This value represents the period of the PWM stream in display core
+ * clocks ([DevCTG] HRAW clocks) multiplied by 128.
+ *
+ */
+static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int clock;
+
+	if (IS_G4X(dev_priv))
+		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
+	else
+		clock = KHz(dev_priv->cdclk.hw.cdclk);
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
+}
+
+/*
+ * VLV: This value represents the period of the PWM stream in display core
+ * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
+ * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
+ */
+static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int mul, clock;
+
+	if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
+		if (IS_CHERRYVIEW(dev_priv))
+			clock = KHz(19200);
+		else
+			clock = MHz(25);
+		mul = 16;
+	} else {
+		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
+		mul = 128;
+	}
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
+}
+
+static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv)
+{
+	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
+
+	if (pwm_freq_hz) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "VBT defined backlight frequency %u Hz\n",
+			    pwm_freq_hz);
+	} else {
+		pwm_freq_hz = 200;
+		drm_dbg_kms(&dev_priv->drm,
+			    "default backlight frequency %u Hz\n",
+			    pwm_freq_hz);
+	}
+
+	return pwm_freq_hz;
+}
+
+static u32 get_backlight_max_vbt(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
+	u32 pwm;
+
+	if (!panel->backlight.pwm_funcs->hz_to_pwm) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "backlight frequency conversion not supported\n");
+		return 0;
+	}
+
+	pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz);
+	if (!pwm) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "backlight frequency conversion failed\n");
+		return 0;
+	}
+
+	return pwm;
+}
+
+/*
+ * Note: The setup hooks can't assume pipe is set!
+ */
+static u32 get_backlight_min_vbt(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	int min;
+
+	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
+
+	/*
+	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
+	 * to problems. There are such machines out there. Either our
+	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
+	 * against this by letting the minimum be at most (arbitrarily chosen)
+	 * 25% of the max.
+	 */
+	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
+	if (min != dev_priv->vbt.backlight.min_brightness) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "clamping VBT min backlight %d/255 to %d/255\n",
+			    dev_priv->vbt.backlight.min_brightness, min);
+	}
+
+	/* vbt value is a coefficient in range [0..255] */
+	return scale(min, 0, 255, 0, panel->backlight.pwm_level_max);
+}
+
+static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
+	bool alt, cpu_mode;
+
+	if (HAS_PCH_LPT(dev_priv))
+		alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
+	else
+		alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
+	panel->backlight.alternate_pwm_increment = alt;
+
+	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
+	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
+	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
+
+	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+
+	if (!panel->backlight.pwm_level_max)
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
+
+	cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) &&
+		   !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) &&
+		   (cpu_ctl2 & BLM_PWM_ENABLE);
+
+	if (cpu_mode) {
+		val = pch_get_backlight(connector, unused);
+
+		drm_dbg_kms(&dev_priv->drm,
+			    "CPU backlight register was enabled, switching to PCH override\n");
+
+		/* Write converted CPU PWM value to PCH override register */
+		lpt_set_backlight(connector->base.state, val);
+		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
+			       pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE);
+
+		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
+			       cpu_ctl2 & ~BLM_PWM_ENABLE);
+	}
+
+	return 0;
+}
+
+static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
+
+	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
+	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
+	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
+
+	if (!panel->backlight.pwm_level_max)
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+	panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
+		(pch_ctl1 & BLM_PCH_PWM_ENABLE);
+
+	return 0;
+}
+
+static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, val;
+
+	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
+
+	if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
+		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
+
+	if (IS_PINEVIEW(dev_priv))
+		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
+
+	panel->backlight.pwm_level_max = ctl >> 17;
+
+	if (!panel->backlight.pwm_level_max) {
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+		panel->backlight.pwm_level_max >>= 1;
+	}
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	if (panel->backlight.combination_mode)
+		panel->backlight.pwm_level_max *= 0xff;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	val = i9xx_get_backlight(connector, unused);
+	val = intel_panel_invert_pwm_level(connector, val);
+	val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
+
+	panel->backlight.pwm_enabled = val != 0;
+
+	return 0;
+}
+
+static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, ctl2;
+
+	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
+	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
+	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
+	panel->backlight.pwm_level_max = ctl >> 16;
+
+	if (!panel->backlight.pwm_level_max)
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	if (panel->backlight.combination_mode)
+		panel->backlight.pwm_level_max *= 0xff;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
+
+	return 0;
+}
+
+static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, ctl2;
+
+	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
+		return -ENODEV;
+
+	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
+	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+	ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe));
+	panel->backlight.pwm_level_max = ctl >> 16;
+
+	if (!panel->backlight.pwm_level_max)
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
+
+	return 0;
+}
+
+static int
+bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pwm_ctl, val;
+
+	panel->backlight.controller = dev_priv->vbt.backlight.controller;
+
+	pwm_ctl = intel_de_read(dev_priv,
+				BXT_BLC_PWM_CTL(panel->backlight.controller));
+
+	/* Controller 1 uses the utility pin. */
+	if (panel->backlight.controller == 1) {
+		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
+		panel->backlight.util_pin_active_low =
+					val & UTIL_PIN_POLARITY;
+	}
+
+	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
+	panel->backlight.pwm_level_max =
+		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
+
+	if (!panel->backlight.pwm_level_max)
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
+
+	return 0;
+}
+
+static int
+cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pwm_ctl;
+
+	/*
+	 * CNP has the BXT implementation of backlight, but with only one
+	 * controller. TODO: ICP has multiple controllers but we only use
+	 * controller 0 for now.
+	 */
+	panel->backlight.controller = 0;
+
+	pwm_ctl = intel_de_read(dev_priv,
+				BXT_BLC_PWM_CTL(panel->backlight.controller));
+
+	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
+	panel->backlight.pwm_level_max =
+		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
+
+	if (!panel->backlight.pwm_level_max)
+		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.pwm_level_max)
+		return -ENODEV;
+
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
+
+	return 0;
+}
+
+static int ext_pwm_setup_backlight(struct intel_connector *connector,
+				   enum pipe pipe)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_panel *panel = &connector->panel;
+	const char *desc;
+	u32 level;
+
+	/* Get the right PWM chip for DSI backlight according to VBT */
+	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
+		panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
+		desc = "PMIC";
+	} else {
+		panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight");
+		desc = "SoC";
+	}
+
+	if (IS_ERR(panel->backlight.pwm)) {
+		drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n",
+			desc);
+		panel->backlight.pwm = NULL;
+		return -ENODEV;
+	}
+
+	panel->backlight.pwm_level_max = 100; /* 100% */
+	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+	if (pwm_is_enabled(panel->backlight.pwm)) {
+		/* PWM is already enabled, use existing settings */
+		pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state);
+
+		level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state,
+						    100);
+		level = intel_panel_invert_pwm_level(connector, level);
+		panel->backlight.pwm_enabled = true;
+
+		drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",
+			    NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,
+			    get_vbt_pwm_freq(dev_priv), level);
+	} else {
+		/* Set period from VBT frequency, leave other settings at 0. */
+		panel->backlight.pwm_state.period =
+			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
+	}
+
+	drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
+		 desc);
+	return 0;
+}
+
+static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct intel_panel *panel = &connector->panel;
+
+	panel->backlight.pwm_funcs->set(conn_state,
+				       intel_panel_invert_pwm_level(connector, level));
+}
+
+static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	return intel_panel_invert_pwm_level(connector,
+					    panel->backlight.pwm_funcs->get(connector, pipe));
+}
+
+static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
+				       const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct intel_panel *panel = &connector->panel;
+
+	panel->backlight.pwm_funcs->enable(crtc_state, conn_state,
+					   intel_panel_invert_pwm_level(connector, level));
+}
+
+static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct intel_panel *panel = &connector->panel;
+
+	panel->backlight.pwm_funcs->disable(conn_state,
+					    intel_panel_invert_pwm_level(connector, level));
+}
+
+static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe)
+{
+	struct intel_panel *panel = &connector->panel;
+	int ret = panel->backlight.pwm_funcs->setup(connector, pipe);
+
+	if (ret < 0)
+		return ret;
+
+	panel->backlight.min = panel->backlight.pwm_level_min;
+	panel->backlight.max = panel->backlight.pwm_level_max;
+	panel->backlight.level = intel_pwm_get_backlight(connector, pipe);
+	panel->backlight.enabled = panel->backlight.pwm_enabled;
+
+	return 0;
+}
+
+void intel_panel_update_backlight(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
+				  const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state)
+{
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	if (!panel->backlight.present)
+		return;
+
+	mutex_lock(&dev_priv->backlight_lock);
+	if (!panel->backlight.enabled)
+		__intel_panel_enable_backlight(crtc_state, conn_state);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_panel *panel = &intel_connector->panel;
+	int ret;
+
+	if (!dev_priv->vbt.backlight.present) {
+		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
+			drm_dbg_kms(&dev_priv->drm,
+				    "no backlight present per VBT, but present per quirk\n");
+		} else {
+			drm_dbg_kms(&dev_priv->drm,
+				    "no backlight present per VBT\n");
+			return 0;
+		}
+	}
+
+	/* ensure intel_panel has been initialized first */
+	if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs))
+		return -ENODEV;
+
+	/* set level and max in panel struct */
+	mutex_lock(&dev_priv->backlight_lock);
+	ret = panel->backlight.funcs->setup(intel_connector, pipe);
+	mutex_unlock(&dev_priv->backlight_lock);
+
+	if (ret) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "failed to setup backlight for connector %s\n",
+			    connector->name);
+		return ret;
+	}
+
+	panel->backlight.present = true;
+
+	drm_dbg_kms(&dev_priv->drm,
+		    "Connector %s backlight initialized, %s, brightness %u/%u\n",
+		    connector->name,
+		    enableddisabled(panel->backlight.enabled),
+		    panel->backlight.level, panel->backlight.max);
+
+	return 0;
+}
+
+void intel_panel_destroy_backlight(struct intel_panel *panel)
+{
+	/* dispose of the pwm */
+	if (panel->backlight.pwm)
+		pwm_put(panel->backlight.pwm);
+
+	panel->backlight.present = false;
+}
+
+static const struct intel_panel_bl_funcs bxt_pwm_funcs = {
+	.setup = bxt_setup_backlight,
+	.enable = bxt_enable_backlight,
+	.disable = bxt_disable_backlight,
+	.set = bxt_set_backlight,
+	.get = bxt_get_backlight,
+	.hz_to_pwm = bxt_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs cnp_pwm_funcs = {
+	.setup = cnp_setup_backlight,
+	.enable = cnp_enable_backlight,
+	.disable = cnp_disable_backlight,
+	.set = bxt_set_backlight,
+	.get = bxt_get_backlight,
+	.hz_to_pwm = cnp_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs lpt_pwm_funcs = {
+	.setup = lpt_setup_backlight,
+	.enable = lpt_enable_backlight,
+	.disable = lpt_disable_backlight,
+	.set = lpt_set_backlight,
+	.get = lpt_get_backlight,
+	.hz_to_pwm = lpt_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs spt_pwm_funcs = {
+	.setup = lpt_setup_backlight,
+	.enable = lpt_enable_backlight,
+	.disable = lpt_disable_backlight,
+	.set = lpt_set_backlight,
+	.get = lpt_get_backlight,
+	.hz_to_pwm = spt_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs pch_pwm_funcs = {
+	.setup = pch_setup_backlight,
+	.enable = pch_enable_backlight,
+	.disable = pch_disable_backlight,
+	.set = pch_set_backlight,
+	.get = pch_get_backlight,
+	.hz_to_pwm = pch_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs ext_pwm_funcs = {
+	.setup = ext_pwm_setup_backlight,
+	.enable = ext_pwm_enable_backlight,
+	.disable = ext_pwm_disable_backlight,
+	.set = ext_pwm_set_backlight,
+	.get = ext_pwm_get_backlight,
+};
+
+static const struct intel_panel_bl_funcs vlv_pwm_funcs = {
+	.setup = vlv_setup_backlight,
+	.enable = vlv_enable_backlight,
+	.disable = vlv_disable_backlight,
+	.set = vlv_set_backlight,
+	.get = vlv_get_backlight,
+	.hz_to_pwm = vlv_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs i965_pwm_funcs = {
+	.setup = i965_setup_backlight,
+	.enable = i965_enable_backlight,
+	.disable = i965_disable_backlight,
+	.set = i9xx_set_backlight,
+	.get = i9xx_get_backlight,
+	.hz_to_pwm = i965_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs i9xx_pwm_funcs = {
+	.setup = i9xx_setup_backlight,
+	.enable = i9xx_enable_backlight,
+	.disable = i9xx_disable_backlight,
+	.set = i9xx_set_backlight,
+	.get = i9xx_get_backlight,
+	.hz_to_pwm = i9xx_hz_to_pwm,
+};
+
+static const struct intel_panel_bl_funcs pwm_bl_funcs = {
+	.setup = intel_pwm_setup_backlight,
+	.enable = intel_pwm_enable_backlight,
+	.disable = intel_pwm_disable_backlight,
+	.set = intel_pwm_set_backlight,
+	.get = intel_pwm_get_backlight,
+};
+
+/* Set up chip specific backlight functions */
+void
+intel_panel_init_backlight_funcs(struct intel_panel *panel)
+{
+	struct intel_connector *connector =
+		container_of(panel, struct intel_connector, panel);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
+	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
+		return;
+
+	if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
+		panel->backlight.pwm_funcs = &bxt_pwm_funcs;
+	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
+		panel->backlight.pwm_funcs = &cnp_pwm_funcs;
+	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) {
+		if (HAS_PCH_LPT(dev_priv))
+			panel->backlight.pwm_funcs = &lpt_pwm_funcs;
+		else
+			panel->backlight.pwm_funcs = &spt_pwm_funcs;
+	} else if (HAS_PCH_SPLIT(dev_priv)) {
+		panel->backlight.pwm_funcs = &pch_pwm_funcs;
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
+			panel->backlight.pwm_funcs = &ext_pwm_funcs;
+		} else {
+			panel->backlight.pwm_funcs = &vlv_pwm_funcs;
+		}
+	} else if (DISPLAY_VER(dev_priv) == 4) {
+		panel->backlight.pwm_funcs = &i965_pwm_funcs;
+	} else {
+		panel->backlight.pwm_funcs = &i9xx_pwm_funcs;
+	}
+
+	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
+	    intel_dp_aux_init_backlight_funcs(connector) == 0)
+		return;
+
+	/* We're using a standard PWM backlight interface */
+	panel->backlight.funcs = &pwm_bl_funcs;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_backlight.h b/drivers/gpu/drm/i915/display/intel_backlight.h
new file mode 100644
index 0000000000000..282020cb47d5b
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_backlight.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#ifndef __INTEL_BACKLIGHT_H__
+#define __INTEL_BACKLIGHT_H__
+
+#include <linux/types.h>
+
+struct drm_connector;
+struct drm_connector_state;
+struct intel_atomic_state;
+struct intel_connector;
+struct intel_crtc_state;
+struct intel_encoder;
+struct intel_panel;
+enum pipe;
+
+void intel_panel_init_backlight_funcs(struct intel_panel *panel);
+void intel_panel_destroy_backlight(struct intel_panel *panel);
+void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
+				    u32 level, u32 max);
+int intel_panel_setup_backlight(struct drm_connector *connector,
+				enum pipe pipe);
+void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state);
+void intel_panel_update_backlight(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
+				  const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state);
+void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state);
+void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level);
+u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level);
+u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level);
+u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val);
+
+#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
+int intel_backlight_device_register(struct intel_connector *connector);
+void intel_backlight_device_unregister(struct intel_connector *connector);
+#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+static inline int intel_backlight_device_register(struct intel_connector *connector)
+{
+	return 0;
+}
+static inline void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+}
+#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+#endif /* __INTEL_BACKLIGHT_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 9bed1ccecea0d..4f49d782eca23 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -29,13 +29,13 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_edid.h>
 
-#include "display/intel_panel.h"
-
 #include "i915_drv.h"
+#include "intel_backlight.h"
 #include "intel_connector.h"
 #include "intel_display_debugfs.h"
 #include "intel_display_types.h"
 #include "intel_hdcp.h"
+#include "intel_panel.h"
 
 int intel_connector_init(struct intel_connector *connector)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index f61901e26409e..68489c7298302 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -29,6 +29,7 @@
 
 #include "i915_drv.h"
 #include "intel_audio.h"
+#include "intel_backlight.h"
 #include "intel_combo_phy.h"
 #include "intel_connector.h"
 #include "intel_crtc.h"
@@ -49,7 +50,6 @@
 #include "intel_hdmi.h"
 #include "intel_hotplug.h"
 #include "intel_lspcon.h"
-#include "intel_panel.h"
 #include "intel_pps.h"
 #include "intel_psr.h"
 #include "intel_snps_phy.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 631cf7d4323c8..f87e4d510ea5e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -45,6 +45,7 @@
 #include "i915_drv.h"
 #include "intel_atomic.h"
 #include "intel_audio.h"
+#include "intel_backlight.h"
 #include "intel_connector.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index e7b90863aa43d..0a77f0e48aa11 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -34,10 +34,10 @@
  * for some reason.
  */
 
+#include "intel_backlight.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dp_aux_backlight.h"
-#include "intel_panel.h"
 
 /* TODO:
  * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index e0381b0fce914..8f5741ebd58dd 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -40,6 +40,7 @@
 
 #include "i915_drv.h"
 #include "intel_atomic.h"
+#include "intel_backlight.h"
 #include "intel_connector.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c
index f7f49b69830fa..aad5c1cd3898e 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.c
+++ b/drivers/gpu/drm/i915/display/intel_opregion.c
@@ -30,10 +30,9 @@
 #include <linux/firmware.h>
 #include <acpi/video.h>
 
-#include "display/intel_panel.h"
-
 #include "i915_drv.h"
 #include "intel_acpi.h"
+#include "intel_backlight.h"
 #include "intel_display_types.h"
 #include "intel_opregion.h"
 
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 7d7a60b4d2de7..ad54767440c15 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -28,17 +28,13 @@
  *      Chris Wilson <chris@chris-wilson.co.uk>
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/kernel.h>
-#include <linux/moduleparam.h>
 #include <linux/pwm.h>
 
+#include "intel_backlight.h"
 #include "intel_connector.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
-#include "intel_dp_aux_backlight.h"
-#include "intel_dsi_dcs_backlight.h"
 #include "intel_panel.h"
 
 void
@@ -456,1767 +452,6 @@ int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state,
 	return 0;
 }
 
-/**
- * scale - scale values from one range to another
- * @source_val: value in range [@source_min..@source_max]
- * @source_min: minimum legal value for @source_val
- * @source_max: maximum legal value for @source_val
- * @target_min: corresponding target value for @source_min
- * @target_max: corresponding target value for @source_max
- *
- * Return @source_val in range [@source_min..@source_max] scaled to range
- * [@target_min..@target_max].
- */
-static u32 scale(u32 source_val,
-		 u32 source_min, u32 source_max,
-		 u32 target_min, u32 target_max)
-{
-	u64 target_val;
-
-	WARN_ON(source_min > source_max);
-	WARN_ON(target_min > target_max);
-
-	/* defensive */
-	source_val = clamp(source_val, source_min, source_max);
-
-	/* avoid overflows */
-	target_val = mul_u32_u32(source_val - source_min,
-				 target_max - target_min);
-	target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min);
-	target_val += target_min;
-
-	return target_val;
-}
-
-/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
- * to [hw_min..hw_max]. */
-static u32 clamp_user_to_hw(struct intel_connector *connector,
-			    u32 user_level, u32 user_max)
-{
-	struct intel_panel *panel = &connector->panel;
-	u32 hw_level;
-
-	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
-	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
-
-	return hw_level;
-}
-
-/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
-static u32 scale_hw_to_user(struct intel_connector *connector,
-			    u32 hw_level, u32 user_max)
-{
-	struct intel_panel *panel = &connector->panel;
-
-	return scale(hw_level, panel->backlight.min, panel->backlight.max,
-		     0, user_max);
-}
-
-u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
-
-	if (dev_priv->params.invert_brightness < 0)
-		return val;
-
-	if (dev_priv->params.invert_brightness > 0 ||
-	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
-		return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min;
-	}
-
-	return val;
-}
-
-void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *i915 = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val);
-	panel->backlight.pwm_funcs->set(conn_state, val);
-}
-
-u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	drm_WARN_ON_ONCE(&dev_priv->drm,
-			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
-
-	val = scale(val, panel->backlight.min, panel->backlight.max,
-		    panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
-
-	return intel_panel_invert_pwm_level(connector, val);
-}
-
-u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	drm_WARN_ON_ONCE(&dev_priv->drm,
-			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
-
-	if (dev_priv->params.invert_brightness > 0 ||
-	    (dev_priv->params.invert_brightness == 0 && dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS))
-		val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min);
-
-	return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max,
-		     panel->backlight.min, panel->backlight.max);
-}
-
-static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
-}
-
-static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-}
-
-static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 val;
-
-	val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-	if (DISPLAY_VER(dev_priv) < 4)
-		val >>= 1;
-
-	if (panel->backlight.combination_mode) {
-		u8 lbpc;
-
-		pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc);
-		val *= lbpc;
-	}
-
-	return val;
-}
-
-static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
-		return 0;
-
-	return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
-}
-
-static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	return intel_de_read(dev_priv,
-			     BXT_BLC_PWM_DUTY(panel->backlight.controller));
-}
-
-static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct intel_panel *panel = &connector->panel;
-	struct pwm_state state;
-
-	pwm_get_state(panel->backlight.pwm, &state);
-	return pwm_get_relative_duty_cycle(&state, 100);
-}
-
-static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level);
-}
-
-static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	u32 tmp;
-
-	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-	intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level);
-}
-
-static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 tmp, mask;
-
-	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
-
-	if (panel->backlight.combination_mode) {
-		u8 lbpc;
-
-		lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1;
-		level /= lbpc;
-		pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc);
-	}
-
-	if (DISPLAY_VER(dev_priv) == 4) {
-		mask = BACKLIGHT_DUTY_CYCLE_MASK;
-	} else {
-		level <<= 1;
-		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
-	}
-
-	tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask;
-	intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level);
-}
-
-static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
-	u32 tmp;
-
-	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level);
-}
-
-static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	intel_de_write(dev_priv,
-		       BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
-}
-
-static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
-
-	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
-	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
-}
-
-static void
-intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *i915 = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level);
-
-	panel->backlight.funcs->set(conn_state, level);
-}
-
-/* set backlight brightness to level in range [0..max], assuming hw min is
- * respected.
- */
-void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
-				    u32 user_level, u32 user_max)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 hw_level;
-
-	/*
-	 * Lack of crtc may occur during driver init because
-	 * connection_mutex isn't held across the entire backlight
-	 * setup + modeset readout, and the BIOS can issue the
-	 * requests at any time.
-	 */
-	if (!panel->backlight.present || !conn_state->crtc)
-		return;
-
-	mutex_lock(&dev_priv->backlight_lock);
-
-	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
-
-	hw_level = clamp_user_to_hw(connector, user_level, user_max);
-	panel->backlight.level = hw_level;
-
-	if (panel->backlight.device)
-		panel->backlight.device->props.brightness =
-			scale_hw_to_user(connector,
-					 panel->backlight.level,
-					 panel->backlight.device->props.max_brightness);
-
-	if (panel->backlight.enabled)
-		intel_panel_actually_set_backlight(conn_state, hw_level);
-
-	mutex_unlock(&dev_priv->backlight_lock);
-}
-
-static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	u32 tmp;
-
-	intel_panel_set_pwm_level(old_conn_state, level);
-
-	/*
-	 * Although we don't support or enable CPU PWM with LPT/SPT based
-	 * systems, it may have been enabled prior to loading the
-	 * driver. Disable to avoid warnings on LCPLL disable.
-	 *
-	 * This needs rework if we need to add support for CPU PWM on PCH split
-	 * platforms.
-	 */
-	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
-	if (tmp & BLM_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "cpu backlight was enabled, disabling\n");
-		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
-			       tmp & ~BLM_PWM_ENABLE);
-	}
-
-	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
-}
-
-static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	u32 tmp;
-
-	intel_panel_set_pwm_level(old_conn_state, val);
-
-	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
-	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
-
-	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
-}
-
-static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
-{
-	intel_panel_set_pwm_level(old_conn_state, val);
-}
-
-static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
-{
-	struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev);
-	u32 tmp;
-
-	intel_panel_set_pwm_level(old_conn_state, val);
-
-	tmp = intel_de_read(dev_priv, BLC_PWM_CTL2);
-	intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
-}
-
-static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe;
-	u32 tmp;
-
-	intel_panel_set_pwm_level(old_conn_state, val);
-
-	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
-	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
-		       tmp & ~BLM_PWM_ENABLE);
-}
-
-static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 tmp;
-
-	intel_panel_set_pwm_level(old_conn_state, val);
-
-	tmp = intel_de_read(dev_priv,
-			    BXT_BLC_PWM_CTL(panel->backlight.controller));
-	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
-		       tmp & ~BXT_BLC_PWM_ENABLE);
-
-	if (panel->backlight.controller == 1) {
-		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
-		val &= ~UTIL_PIN_ENABLE;
-		intel_de_write(dev_priv, UTIL_PIN_CTL, val);
-	}
-}
-
-static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 tmp;
-
-	intel_panel_set_pwm_level(old_conn_state, val);
-
-	tmp = intel_de_read(dev_priv,
-			    BXT_BLC_PWM_CTL(panel->backlight.controller));
-	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
-		       tmp & ~BXT_BLC_PWM_ENABLE);
-}
-
-static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct intel_panel *panel = &connector->panel;
-
-	panel->backlight.pwm_state.enabled = false;
-	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
-}
-
-void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state)
-{
-	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	if (!panel->backlight.present)
-		return;
-
-	/*
-	 * Do not disable backlight on the vga_switcheroo path. When switching
-	 * away from i915, the other client may depend on i915 to handle the
-	 * backlight. This will leave the backlight on unnecessarily when
-	 * another client is not activated.
-	 */
-	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Skipping backlight disable on vga switch\n");
-		return;
-	}
-
-	mutex_lock(&dev_priv->backlight_lock);
-
-	if (panel->backlight.device)
-		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
-	panel->backlight.enabled = false;
-	panel->backlight.funcs->disable(old_conn_state, 0);
-
-	mutex_unlock(&dev_priv->backlight_lock);
-}
-
-static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
-				 const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 pch_ctl1, pch_ctl2, schicken;
-
-	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
-	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
-		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
-		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
-	}
-
-	if (HAS_PCH_LPT(dev_priv)) {
-		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2);
-		if (panel->backlight.alternate_pwm_increment)
-			schicken |= LPT_PWM_GRANULARITY;
-		else
-			schicken &= ~LPT_PWM_GRANULARITY;
-		intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken);
-	} else {
-		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1);
-		if (panel->backlight.alternate_pwm_increment)
-			schicken |= SPT_PWM_GRANULARITY;
-		else
-			schicken &= ~SPT_PWM_GRANULARITY;
-		intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken);
-	}
-
-	pch_ctl2 = panel->backlight.pwm_level_max << 16;
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
-
-	pch_ctl1 = 0;
-	if (panel->backlight.active_low_pwm)
-		pch_ctl1 |= BLM_PCH_POLARITY;
-
-	/* After LPT, override is the default. */
-	if (HAS_PCH_LPT(dev_priv))
-		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
-
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
-	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
-		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
-
-	/* This won't stick until the above enable. */
-	intel_panel_set_pwm_level(conn_state, level);
-}
-
-static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
-				 const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
-
-	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
-	if (cpu_ctl2 & BLM_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n");
-		cpu_ctl2 &= ~BLM_PWM_ENABLE;
-		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
-	}
-
-	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
-	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
-		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
-		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
-	}
-
-	if (cpu_transcoder == TRANSCODER_EDP)
-		cpu_ctl2 = BLM_TRANSCODER_EDP;
-	else
-		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
-	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
-	intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2);
-	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
-
-	/* This won't stick until the above enable. */
-	intel_panel_set_pwm_level(conn_state, level);
-
-	pch_ctl2 = panel->backlight.pwm_level_max << 16;
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
-
-	pch_ctl1 = 0;
-	if (panel->backlight.active_low_pwm)
-		pch_ctl1 |= BLM_PCH_POLARITY;
-
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
-	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
-	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
-		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
-}
-
-static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 ctl, freq;
-
-	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
-	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
-		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
-		intel_de_write(dev_priv, BLC_PWM_CTL, 0);
-	}
-
-	freq = panel->backlight.pwm_level_max;
-	if (panel->backlight.combination_mode)
-		freq /= 0xff;
-
-	ctl = freq << 17;
-	if (panel->backlight.combination_mode)
-		ctl |= BLM_LEGACY_MODE;
-	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
-		ctl |= BLM_POLARITY_PNV;
-
-	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
-	intel_de_posting_read(dev_priv, BLC_PWM_CTL);
-
-	/* XXX: combine this into above write? */
-	intel_panel_set_pwm_level(conn_state, level);
-
-	/*
-	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
-	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
-	 * that has backlight.
-	 */
-	if (DISPLAY_VER(dev_priv) == 2)
-		intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
-}
-
-static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
-	u32 ctl, ctl2, freq;
-
-	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
-	if (ctl2 & BLM_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
-		ctl2 &= ~BLM_PWM_ENABLE;
-		intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
-	}
-
-	freq = panel->backlight.pwm_level_max;
-	if (panel->backlight.combination_mode)
-		freq /= 0xff;
-
-	ctl = freq << 16;
-	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
-
-	ctl2 = BLM_PIPE(pipe);
-	if (panel->backlight.combination_mode)
-		ctl2 |= BLM_COMBINATION_MODE;
-	if (panel->backlight.active_low_pwm)
-		ctl2 |= BLM_POLARITY_I965;
-	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
-	intel_de_posting_read(dev_priv, BLC_PWM_CTL2);
-	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
-
-	intel_panel_set_pwm_level(conn_state, level);
-}
-
-static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
-				 const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
-	u32 ctl, ctl2;
-
-	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
-	if (ctl2 & BLM_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
-		ctl2 &= ~BLM_PWM_ENABLE;
-		intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
-	}
-
-	ctl = panel->backlight.pwm_level_max << 16;
-	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl);
-
-	/* XXX: combine this into above write? */
-	intel_panel_set_pwm_level(conn_state, level);
-
-	ctl2 = 0;
-	if (panel->backlight.active_low_pwm)
-		ctl2 |= BLM_POLARITY_I965;
-	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
-	intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
-	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
-		       ctl2 | BLM_PWM_ENABLE);
-}
-
-static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
-				 const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
-	u32 pwm_ctl, val;
-
-	/* Controller 1 uses the utility pin. */
-	if (panel->backlight.controller == 1) {
-		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
-		if (val & UTIL_PIN_ENABLE) {
-			drm_dbg_kms(&dev_priv->drm,
-				    "util pin already enabled\n");
-			val &= ~UTIL_PIN_ENABLE;
-			intel_de_write(dev_priv, UTIL_PIN_CTL, val);
-		}
-
-		val = 0;
-		if (panel->backlight.util_pin_active_low)
-			val |= UTIL_PIN_POLARITY;
-		intel_de_write(dev_priv, UTIL_PIN_CTL,
-			       val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
-	}
-
-	pwm_ctl = intel_de_read(dev_priv,
-				BXT_BLC_PWM_CTL(panel->backlight.controller));
-	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
-		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
-		intel_de_write(dev_priv,
-			       BXT_BLC_PWM_CTL(panel->backlight.controller),
-			       pwm_ctl);
-	}
-
-	intel_de_write(dev_priv,
-		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
-		       panel->backlight.pwm_level_max);
-
-	intel_panel_set_pwm_level(conn_state, level);
-
-	pwm_ctl = 0;
-	if (panel->backlight.active_low_pwm)
-		pwm_ctl |= BXT_BLC_PWM_POLARITY;
-
-	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
-		       pwm_ctl);
-	intel_de_posting_read(dev_priv,
-			      BXT_BLC_PWM_CTL(panel->backlight.controller));
-	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
-		       pwm_ctl | BXT_BLC_PWM_ENABLE);
-}
-
-static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
-				 const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 pwm_ctl;
-
-	pwm_ctl = intel_de_read(dev_priv,
-				BXT_BLC_PWM_CTL(panel->backlight.controller));
-	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
-		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
-		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
-		intel_de_write(dev_priv,
-			       BXT_BLC_PWM_CTL(panel->backlight.controller),
-			       pwm_ctl);
-	}
-
-	intel_de_write(dev_priv,
-		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
-		       panel->backlight.pwm_level_max);
-
-	intel_panel_set_pwm_level(conn_state, level);
-
-	pwm_ctl = 0;
-	if (panel->backlight.active_low_pwm)
-		pwm_ctl |= BXT_BLC_PWM_POLARITY;
-
-	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
-		       pwm_ctl);
-	intel_de_posting_read(dev_priv,
-			      BXT_BLC_PWM_CTL(panel->backlight.controller));
-	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
-		       pwm_ctl | BXT_BLC_PWM_ENABLE);
-}
-
-static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
-				     const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct intel_panel *panel = &connector->panel;
-
-	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
-	panel->backlight.pwm_state.enabled = true;
-	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
-}
-
-static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
-					   const struct drm_connector_state *conn_state)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct intel_panel *panel = &connector->panel;
-
-	WARN_ON(panel->backlight.max == 0);
-
-	if (panel->backlight.level <= panel->backlight.min) {
-		panel->backlight.level = panel->backlight.max;
-		if (panel->backlight.device)
-			panel->backlight.device->props.brightness =
-				scale_hw_to_user(connector,
-						 panel->backlight.level,
-						 panel->backlight.device->props.max_brightness);
-	}
-
-	panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level);
-	panel->backlight.enabled = true;
-	if (panel->backlight.device)
-		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
-}
-
-void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
-
-	if (!panel->backlight.present)
-		return;
-
-	drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe));
-
-	mutex_lock(&dev_priv->backlight_lock);
-
-	__intel_panel_enable_backlight(crtc_state, conn_state);
-
-	mutex_unlock(&dev_priv->backlight_lock);
-}
-
-#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
-static u32 intel_panel_get_backlight(struct intel_connector *connector)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 val = 0;
-
-	mutex_lock(&dev_priv->backlight_lock);
-
-	if (panel->backlight.enabled)
-		val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector));
-
-	mutex_unlock(&dev_priv->backlight_lock);
-
-	drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val);
-	return val;
-}
-
-/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
-static u32 scale_user_to_hw(struct intel_connector *connector,
-			    u32 user_level, u32 user_max)
-{
-	struct intel_panel *panel = &connector->panel;
-
-	return scale(user_level, 0, user_max,
-		     panel->backlight.min, panel->backlight.max);
-}
-
-/* set backlight brightness to level in range [0..max], scaling wrt hw min */
-static void intel_panel_set_backlight(const struct drm_connector_state *conn_state,
-				      u32 user_level, u32 user_max)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 hw_level;
-
-	if (!panel->backlight.present)
-		return;
-
-	mutex_lock(&dev_priv->backlight_lock);
-
-	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
-
-	hw_level = scale_user_to_hw(connector, user_level, user_max);
-	panel->backlight.level = hw_level;
-
-	if (panel->backlight.enabled)
-		intel_panel_actually_set_backlight(conn_state, hw_level);
-
-	mutex_unlock(&dev_priv->backlight_lock);
-}
-
-static int intel_backlight_device_update_status(struct backlight_device *bd)
-{
-	struct intel_connector *connector = bl_get_data(bd);
-	struct intel_panel *panel = &connector->panel;
-	struct drm_device *dev = connector->base.dev;
-
-	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
-	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
-		      bd->props.brightness, bd->props.max_brightness);
-	intel_panel_set_backlight(connector->base.state, bd->props.brightness,
-				  bd->props.max_brightness);
-
-	/*
-	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
-	 * backlight class device does not make it easy to to differentiate
-	 * between callbacks for brightness and bl_power, so our backlight_power
-	 * callback needs to take this into account.
-	 */
-	if (panel->backlight.enabled) {
-		if (panel->backlight.power) {
-			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
-				bd->props.brightness != 0;
-			panel->backlight.power(connector, enable);
-		}
-	} else {
-		bd->props.power = FB_BLANK_POWERDOWN;
-	}
-
-	drm_modeset_unlock(&dev->mode_config.connection_mutex);
-	return 0;
-}
-
-static int intel_backlight_device_get_brightness(struct backlight_device *bd)
-{
-	struct intel_connector *connector = bl_get_data(bd);
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	intel_wakeref_t wakeref;
-	int ret = 0;
-
-	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
-		u32 hw_level;
-
-		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
-
-		hw_level = intel_panel_get_backlight(connector);
-		ret = scale_hw_to_user(connector,
-				       hw_level, bd->props.max_brightness);
-
-		drm_modeset_unlock(&dev->mode_config.connection_mutex);
-	}
-
-	return ret;
-}
-
-static const struct backlight_ops intel_backlight_device_ops = {
-	.update_status = intel_backlight_device_update_status,
-	.get_brightness = intel_backlight_device_get_brightness,
-};
-
-int intel_backlight_device_register(struct intel_connector *connector)
-{
-	struct drm_i915_private *i915 = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	struct backlight_properties props;
-	struct backlight_device *bd;
-	const char *name;
-	int ret = 0;
-
-	if (WARN_ON(panel->backlight.device))
-		return -ENODEV;
-
-	if (!panel->backlight.present)
-		return 0;
-
-	WARN_ON(panel->backlight.max == 0);
-
-	memset(&props, 0, sizeof(props));
-	props.type = BACKLIGHT_RAW;
-
-	/*
-	 * Note: Everything should work even if the backlight device max
-	 * presented to the userspace is arbitrarily chosen.
-	 */
-	props.max_brightness = panel->backlight.max;
-	props.brightness = scale_hw_to_user(connector,
-					    panel->backlight.level,
-					    props.max_brightness);
-
-	if (panel->backlight.enabled)
-		props.power = FB_BLANK_UNBLANK;
-	else
-		props.power = FB_BLANK_POWERDOWN;
-
-	name = kstrdup("intel_backlight", GFP_KERNEL);
-	if (!name)
-		return -ENOMEM;
-
-	bd = backlight_device_register(name, connector->base.kdev, connector,
-				       &intel_backlight_device_ops, &props);
-
-	/*
-	 * Using the same name independent of the drm device or connector
-	 * prevents registration of multiple backlight devices in the
-	 * driver. However, we need to use the default name for backward
-	 * compatibility. Use unique names for subsequent backlight devices as a
-	 * fallback when the default name already exists.
-	 */
-	if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) {
-		kfree(name);
-		name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
-				 i915->drm.primary->index, connector->base.name);
-		if (!name)
-			return -ENOMEM;
-
-		bd = backlight_device_register(name, connector->base.kdev, connector,
-					       &intel_backlight_device_ops, &props);
-	}
-
-	if (IS_ERR(bd)) {
-		drm_err(&i915->drm,
-			"[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n",
-			connector->base.base.id, connector->base.name, name, PTR_ERR(bd));
-		ret = PTR_ERR(bd);
-		goto out;
-	}
-
-	panel->backlight.device = bd;
-
-	drm_dbg_kms(&i915->drm,
-		    "[CONNECTOR:%d:%s] backlight device %s registered\n",
-		    connector->base.base.id, connector->base.name, name);
-
-out:
-	kfree(name);
-
-	return ret;
-}
-
-void intel_backlight_device_unregister(struct intel_connector *connector)
-{
-	struct intel_panel *panel = &connector->panel;
-
-	if (panel->backlight.device) {
-		backlight_device_unregister(panel->backlight.device);
-		panel->backlight.device = NULL;
-	}
-}
-#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
-
-/*
- * CNP: PWM clock frequency is 19.2 MHz or 24 MHz.
- *      PWM increment = 1
- */
-static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
-				 pwm_freq_hz);
-}
-
-/*
- * BXT: PWM clock frequency = 19.2 MHz.
- */
-static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
-}
-
-/*
- * SPT: This value represents the period of the PWM stream in clock periods
- * multiplied by 16 (default increment) or 128 (alternate increment selected in
- * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
- */
-static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct intel_panel *panel = &connector->panel;
-	u32 mul;
-
-	if (panel->backlight.alternate_pwm_increment)
-		mul = 128;
-	else
-		mul = 16;
-
-	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
-}
-
-/*
- * LPT: This value represents the period of the PWM stream in clock periods
- * multiplied by 128 (default increment) or 16 (alternate increment, selected in
- * LPT SOUTH_CHICKEN2 register bit 5).
- */
-static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 mul, clock;
-
-	if (panel->backlight.alternate_pwm_increment)
-		mul = 16;
-	else
-		mul = 128;
-
-	if (HAS_PCH_LPT_H(dev_priv))
-		clock = MHz(135); /* LPT:H */
-	else
-		clock = MHz(24); /* LPT:LP */
-
-	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
-}
-
-/*
- * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
- * display raw clocks multiplied by 128.
- */
-static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
-				 pwm_freq_hz * 128);
-}
-
-/*
- * Gen2: This field determines the number of time base events (display core
- * clock frequency/32) in total for a complete cycle of modulated backlight
- * control.
- *
- * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
- * divided by 32.
- */
-static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	int clock;
-
-	if (IS_PINEVIEW(dev_priv))
-		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
-	else
-		clock = KHz(dev_priv->cdclk.hw.cdclk);
-
-	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
-}
-
-/*
- * Gen4: This value represents the period of the PWM stream in display core
- * clocks ([DevCTG] HRAW clocks) multiplied by 128.
- *
- */
-static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	int clock;
-
-	if (IS_G4X(dev_priv))
-		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
-	else
-		clock = KHz(dev_priv->cdclk.hw.cdclk);
-
-	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
-}
-
-/*
- * VLV: This value represents the period of the PWM stream in display core
- * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
- * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
- */
-static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	int mul, clock;
-
-	if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
-		if (IS_CHERRYVIEW(dev_priv))
-			clock = KHz(19200);
-		else
-			clock = MHz(25);
-		mul = 16;
-	} else {
-		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
-		mul = 128;
-	}
-
-	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
-}
-
-static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv)
-{
-	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
-
-	if (pwm_freq_hz) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "VBT defined backlight frequency %u Hz\n",
-			    pwm_freq_hz);
-	} else {
-		pwm_freq_hz = 200;
-		drm_dbg_kms(&dev_priv->drm,
-			    "default backlight frequency %u Hz\n",
-			    pwm_freq_hz);
-	}
-
-	return pwm_freq_hz;
-}
-
-static u32 get_backlight_max_vbt(struct intel_connector *connector)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
-	u32 pwm;
-
-	if (!panel->backlight.pwm_funcs->hz_to_pwm) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "backlight frequency conversion not supported\n");
-		return 0;
-	}
-
-	pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz);
-	if (!pwm) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "backlight frequency conversion failed\n");
-		return 0;
-	}
-
-	return pwm;
-}
-
-/*
- * Note: The setup hooks can't assume pipe is set!
- */
-static u32 get_backlight_min_vbt(struct intel_connector *connector)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	int min;
-
-	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
-
-	/*
-	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
-	 * to problems. There are such machines out there. Either our
-	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
-	 * against this by letting the minimum be at most (arbitrarily chosen)
-	 * 25% of the max.
-	 */
-	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
-	if (min != dev_priv->vbt.backlight.min_brightness) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "clamping VBT min backlight %d/255 to %d/255\n",
-			    dev_priv->vbt.backlight.min_brightness, min);
-	}
-
-	/* vbt value is a coefficient in range [0..255] */
-	return scale(min, 0, 255, 0, panel->backlight.pwm_level_max);
-}
-
-static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
-	bool alt, cpu_mode;
-
-	if (HAS_PCH_LPT(dev_priv))
-		alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
-	else
-		alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
-	panel->backlight.alternate_pwm_increment = alt;
-
-	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
-	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
-
-	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
-	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
-
-	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
-
-	if (!panel->backlight.pwm_level_max)
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
-
-	cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) &&
-		   !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) &&
-		   (cpu_ctl2 & BLM_PWM_ENABLE);
-
-	if (cpu_mode) {
-		val = pch_get_backlight(connector, unused);
-
-		drm_dbg_kms(&dev_priv->drm,
-			    "CPU backlight register was enabled, switching to PCH override\n");
-
-		/* Write converted CPU PWM value to PCH override register */
-		lpt_set_backlight(connector->base.state, val);
-		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
-			       pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE);
-
-		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
-			       cpu_ctl2 & ~BLM_PWM_ENABLE);
-	}
-
-	return 0;
-}
-
-static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
-
-	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
-	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
-
-	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
-	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
-
-	if (!panel->backlight.pwm_level_max)
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
-	panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
-		(pch_ctl1 & BLM_PCH_PWM_ENABLE);
-
-	return 0;
-}
-
-static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 ctl, val;
-
-	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
-
-	if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
-		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
-
-	if (IS_PINEVIEW(dev_priv))
-		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
-
-	panel->backlight.pwm_level_max = ctl >> 17;
-
-	if (!panel->backlight.pwm_level_max) {
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-		panel->backlight.pwm_level_max >>= 1;
-	}
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	if (panel->backlight.combination_mode)
-		panel->backlight.pwm_level_max *= 0xff;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	val = i9xx_get_backlight(connector, unused);
-	val = intel_panel_invert_pwm_level(connector, val);
-	val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
-
-	panel->backlight.pwm_enabled = val != 0;
-
-	return 0;
-}
-
-static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 ctl, ctl2;
-
-	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
-	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
-	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
-
-	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
-	panel->backlight.pwm_level_max = ctl >> 16;
-
-	if (!panel->backlight.pwm_level_max)
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	if (panel->backlight.combination_mode)
-		panel->backlight.pwm_level_max *= 0xff;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
-
-	return 0;
-}
-
-static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 ctl, ctl2;
-
-	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
-		return -ENODEV;
-
-	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
-	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
-
-	ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe));
-	panel->backlight.pwm_level_max = ctl >> 16;
-
-	if (!panel->backlight.pwm_level_max)
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
-
-	return 0;
-}
-
-static int
-bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 pwm_ctl, val;
-
-	panel->backlight.controller = dev_priv->vbt.backlight.controller;
-
-	pwm_ctl = intel_de_read(dev_priv,
-				BXT_BLC_PWM_CTL(panel->backlight.controller));
-
-	/* Controller 1 uses the utility pin. */
-	if (panel->backlight.controller == 1) {
-		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
-		panel->backlight.util_pin_active_low =
-					val & UTIL_PIN_POLARITY;
-	}
-
-	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
-	panel->backlight.pwm_level_max =
-		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
-
-	if (!panel->backlight.pwm_level_max)
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
-
-	return 0;
-}
-
-static int
-cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-	u32 pwm_ctl;
-
-	/*
-	 * CNP has the BXT implementation of backlight, but with only one
-	 * controller. TODO: ICP has multiple controllers but we only use
-	 * controller 0 for now.
-	 */
-	panel->backlight.controller = 0;
-
-	pwm_ctl = intel_de_read(dev_priv,
-				BXT_BLC_PWM_CTL(panel->backlight.controller));
-
-	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
-	panel->backlight.pwm_level_max =
-		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
-
-	if (!panel->backlight.pwm_level_max)
-		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
-
-	if (!panel->backlight.pwm_level_max)
-		return -ENODEV;
-
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
-
-	return 0;
-}
-
-static int ext_pwm_setup_backlight(struct intel_connector *connector,
-				   enum pipe pipe)
-{
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_panel *panel = &connector->panel;
-	const char *desc;
-	u32 level;
-
-	/* Get the right PWM chip for DSI backlight according to VBT */
-	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
-		panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
-		desc = "PMIC";
-	} else {
-		panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight");
-		desc = "SoC";
-	}
-
-	if (IS_ERR(panel->backlight.pwm)) {
-		drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n",
-			desc);
-		panel->backlight.pwm = NULL;
-		return -ENODEV;
-	}
-
-	panel->backlight.pwm_level_max = 100; /* 100% */
-	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
-
-	if (pwm_is_enabled(panel->backlight.pwm)) {
-		/* PWM is already enabled, use existing settings */
-		pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state);
-
-		level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state,
-						    100);
-		level = intel_panel_invert_pwm_level(connector, level);
-		panel->backlight.pwm_enabled = true;
-
-		drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",
-			    NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,
-			    get_vbt_pwm_freq(dev_priv), level);
-	} else {
-		/* Set period from VBT frequency, leave other settings at 0. */
-		panel->backlight.pwm_state.period =
-			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
-	}
-
-	drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
-		 desc);
-	return 0;
-}
-
-static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct intel_panel *panel = &connector->panel;
-
-	panel->backlight.pwm_funcs->set(conn_state,
-				       intel_panel_invert_pwm_level(connector, level));
-}
-
-static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe)
-{
-	struct intel_panel *panel = &connector->panel;
-
-	return intel_panel_invert_pwm_level(connector,
-					    panel->backlight.pwm_funcs->get(connector, pipe));
-}
-
-static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
-				       const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct intel_panel *panel = &connector->panel;
-
-	panel->backlight.pwm_funcs->enable(crtc_state, conn_state,
-					   intel_panel_invert_pwm_level(connector, level));
-}
-
-static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct intel_panel *panel = &connector->panel;
-
-	panel->backlight.pwm_funcs->disable(conn_state,
-					    intel_panel_invert_pwm_level(connector, level));
-}
-
-static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe)
-{
-	struct intel_panel *panel = &connector->panel;
-	int ret = panel->backlight.pwm_funcs->setup(connector, pipe);
-
-	if (ret < 0)
-		return ret;
-
-	panel->backlight.min = panel->backlight.pwm_level_min;
-	panel->backlight.max = panel->backlight.pwm_level_max;
-	panel->backlight.level = intel_pwm_get_backlight(connector, pipe);
-	panel->backlight.enabled = panel->backlight.pwm_enabled;
-
-	return 0;
-}
-
-void intel_panel_update_backlight(struct intel_atomic_state *state,
-				  struct intel_encoder *encoder,
-				  const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state)
-{
-	struct intel_connector *connector = to_intel_connector(conn_state->connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct intel_panel *panel = &connector->panel;
-
-	if (!panel->backlight.present)
-		return;
-
-	mutex_lock(&dev_priv->backlight_lock);
-	if (!panel->backlight.enabled)
-		__intel_panel_enable_backlight(crtc_state, conn_state);
-
-	mutex_unlock(&dev_priv->backlight_lock);
-}
-
-int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct intel_panel *panel = &intel_connector->panel;
-	int ret;
-
-	if (!dev_priv->vbt.backlight.present) {
-		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
-			drm_dbg_kms(&dev_priv->drm,
-				    "no backlight present per VBT, but present per quirk\n");
-		} else {
-			drm_dbg_kms(&dev_priv->drm,
-				    "no backlight present per VBT\n");
-			return 0;
-		}
-	}
-
-	/* ensure intel_panel has been initialized first */
-	if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs))
-		return -ENODEV;
-
-	/* set level and max in panel struct */
-	mutex_lock(&dev_priv->backlight_lock);
-	ret = panel->backlight.funcs->setup(intel_connector, pipe);
-	mutex_unlock(&dev_priv->backlight_lock);
-
-	if (ret) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "failed to setup backlight for connector %s\n",
-			    connector->name);
-		return ret;
-	}
-
-	panel->backlight.present = true;
-
-	drm_dbg_kms(&dev_priv->drm,
-		    "Connector %s backlight initialized, %s, brightness %u/%u\n",
-		    connector->name,
-		    enableddisabled(panel->backlight.enabled),
-		    panel->backlight.level, panel->backlight.max);
-
-	return 0;
-}
-
-static void intel_panel_destroy_backlight(struct intel_panel *panel)
-{
-	/* dispose of the pwm */
-	if (panel->backlight.pwm)
-		pwm_put(panel->backlight.pwm);
-
-	panel->backlight.present = false;
-}
-
-static const struct intel_panel_bl_funcs bxt_pwm_funcs = {
-	.setup = bxt_setup_backlight,
-	.enable = bxt_enable_backlight,
-	.disable = bxt_disable_backlight,
-	.set = bxt_set_backlight,
-	.get = bxt_get_backlight,
-	.hz_to_pwm = bxt_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs cnp_pwm_funcs = {
-	.setup = cnp_setup_backlight,
-	.enable = cnp_enable_backlight,
-	.disable = cnp_disable_backlight,
-	.set = bxt_set_backlight,
-	.get = bxt_get_backlight,
-	.hz_to_pwm = cnp_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs lpt_pwm_funcs = {
-	.setup = lpt_setup_backlight,
-	.enable = lpt_enable_backlight,
-	.disable = lpt_disable_backlight,
-	.set = lpt_set_backlight,
-	.get = lpt_get_backlight,
-	.hz_to_pwm = lpt_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs spt_pwm_funcs = {
-	.setup = lpt_setup_backlight,
-	.enable = lpt_enable_backlight,
-	.disable = lpt_disable_backlight,
-	.set = lpt_set_backlight,
-	.get = lpt_get_backlight,
-	.hz_to_pwm = spt_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs pch_pwm_funcs = {
-	.setup = pch_setup_backlight,
-	.enable = pch_enable_backlight,
-	.disable = pch_disable_backlight,
-	.set = pch_set_backlight,
-	.get = pch_get_backlight,
-	.hz_to_pwm = pch_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs ext_pwm_funcs = {
-	.setup = ext_pwm_setup_backlight,
-	.enable = ext_pwm_enable_backlight,
-	.disable = ext_pwm_disable_backlight,
-	.set = ext_pwm_set_backlight,
-	.get = ext_pwm_get_backlight,
-};
-
-static const struct intel_panel_bl_funcs vlv_pwm_funcs = {
-	.setup = vlv_setup_backlight,
-	.enable = vlv_enable_backlight,
-	.disable = vlv_disable_backlight,
-	.set = vlv_set_backlight,
-	.get = vlv_get_backlight,
-	.hz_to_pwm = vlv_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs i965_pwm_funcs = {
-	.setup = i965_setup_backlight,
-	.enable = i965_enable_backlight,
-	.disable = i965_disable_backlight,
-	.set = i9xx_set_backlight,
-	.get = i9xx_get_backlight,
-	.hz_to_pwm = i965_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs i9xx_pwm_funcs = {
-	.setup = i9xx_setup_backlight,
-	.enable = i9xx_enable_backlight,
-	.disable = i9xx_disable_backlight,
-	.set = i9xx_set_backlight,
-	.get = i9xx_get_backlight,
-	.hz_to_pwm = i9xx_hz_to_pwm,
-};
-
-static const struct intel_panel_bl_funcs pwm_bl_funcs = {
-	.setup = intel_pwm_setup_backlight,
-	.enable = intel_pwm_enable_backlight,
-	.disable = intel_pwm_disable_backlight,
-	.set = intel_pwm_set_backlight,
-	.get = intel_pwm_get_backlight,
-};
-
-/* Set up chip specific backlight functions */
-static void
-intel_panel_init_backlight_funcs(struct intel_panel *panel)
-{
-	struct intel_connector *connector =
-		container_of(panel, struct intel_connector, panel);
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
-	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
-	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
-		return;
-
-	if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
-		panel->backlight.pwm_funcs = &bxt_pwm_funcs;
-	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
-		panel->backlight.pwm_funcs = &cnp_pwm_funcs;
-	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) {
-		if (HAS_PCH_LPT(dev_priv))
-			panel->backlight.pwm_funcs = &lpt_pwm_funcs;
-		else
-			panel->backlight.pwm_funcs = &spt_pwm_funcs;
-	} else if (HAS_PCH_SPLIT(dev_priv)) {
-		panel->backlight.pwm_funcs = &pch_pwm_funcs;
-	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
-			panel->backlight.pwm_funcs = &ext_pwm_funcs;
-		} else {
-			panel->backlight.pwm_funcs = &vlv_pwm_funcs;
-		}
-	} else if (DISPLAY_VER(dev_priv) == 4) {
-		panel->backlight.pwm_funcs = &i965_pwm_funcs;
-	} else {
-		panel->backlight.pwm_funcs = &i9xx_pwm_funcs;
-	}
-
-	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
-	    intel_dp_aux_init_backlight_funcs(connector) == 0)
-		return;
-
-	/* We're using a standard PWM backlight interface */
-	panel->backlight.funcs = &pwm_bl_funcs;
-}
-
 enum drm_connector_status
 intel_panel_detect(struct drm_connector *connector, bool force)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h
index 1d340f77bffc7..67dbb15026bf1 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.h
+++ b/drivers/gpu/drm/i915/display/intel_panel.h
@@ -8,15 +8,13 @@
 
 #include <linux/types.h>
 
-#include "intel_display.h"
-
+enum drm_connector_status;
 struct drm_connector;
 struct drm_connector_state;
 struct drm_display_mode;
+struct drm_i915_private;
 struct intel_connector;
-struct intel_crtc;
 struct intel_crtc_state;
-struct intel_encoder;
 struct intel_panel;
 
 int intel_panel_init(struct intel_panel *panel,
@@ -31,17 +29,6 @@ int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state);
 int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state);
-void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
-				    u32 level, u32 max);
-int intel_panel_setup_backlight(struct drm_connector *connector,
-				enum pipe pipe);
-void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state);
-void intel_panel_update_backlight(struct intel_atomic_state *state,
-				  struct intel_encoder *encoder,
-				  const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state);
-void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state);
 struct drm_display_mode *
 intel_panel_edid_downclock_mode(struct intel_connector *connector,
 				const struct drm_display_mode *fixed_mode);
@@ -49,22 +36,5 @@ struct drm_display_mode *
 intel_panel_edid_fixed_mode(struct intel_connector *connector);
 struct drm_display_mode *
 intel_panel_vbt_fixed_mode(struct intel_connector *connector);
-void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level);
-u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level);
-u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level);
-u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val);
-
-#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
-int intel_backlight_device_register(struct intel_connector *connector);
-void intel_backlight_device_unregister(struct intel_connector *connector);
-#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
-static inline int intel_backlight_device_register(struct intel_connector *connector)
-{
-	return 0;
-}
-static inline void intel_backlight_device_unregister(struct intel_connector *connector)
-{
-}
-#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
 
 #endif /* __INTEL_PANEL_H__ */
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 0ee4ff341e25d..b27738df447d0 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -32,6 +32,7 @@
 
 #include "i915_drv.h"
 #include "intel_atomic.h"
+#include "intel_backlight.h"
 #include "intel_connector.h"
 #include "intel_crtc.h"
 #include "intel_de.h"
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 012/107] drm/i915/display: avoid warnings when registering dual panel backlight
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (10 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 013/107] ALSA: hda: intel-nhlt: remove use of __func__ in dev_dbg Greg Kroah-Hartman
                   ` (103 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Arun R Murthy, Jani Nikula,
	Rodrigo Vivi, Sasha Levin

From: Arun R Murthy <arun.r.murthy@intel.com>

[ Upstream commit 868e8e5156a1f8d92ca83fdbac6fd52798650792 ]

Commit 20f85ef89d94 ("drm/i915/backlight: use unique backlight device
names") added support for multiple backlight devices on dual panel
systems, but did so with error handling on -EEXIST from
backlight_device_register(). Unfortunately, that triggered a warning in
dmesg all the way down from sysfs_add_file_mode_ns() and
sysfs_warn_dup().

Instead of optimistically always attempting to register with the default
name ("intel_backlight", which we have to retain for backward
compatibility), check if a backlight device with the name exists first,
and, if so, use the card and connector based name.

v2: reworked on top of the patch commit 20f85ef89d94
("drm/i915/backlight: use unique backlight device names")
v3: fixed the ref count leak(Jani N)

Fixes: 20f85ef89d94 ("drm/i915/backlight: use unique backlight device names")
Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220808035750.3111046-1-arun.r.murthy@intel.com
(cherry picked from commit 4234ea30051200fc6016de10e4d58369e60b38f1)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../gpu/drm/i915/display/intel_backlight.c    | 26 +++++++++----------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c
index 4b0086ee48519..60f91ac7d1427 100644
--- a/drivers/gpu/drm/i915/display/intel_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_backlight.c
@@ -966,26 +966,24 @@ int intel_backlight_device_register(struct intel_connector *connector)
 	if (!name)
 		return -ENOMEM;
 
-	bd = backlight_device_register(name, connector->base.kdev, connector,
-				       &intel_backlight_device_ops, &props);
-
-	/*
-	 * Using the same name independent of the drm device or connector
-	 * prevents registration of multiple backlight devices in the
-	 * driver. However, we need to use the default name for backward
-	 * compatibility. Use unique names for subsequent backlight devices as a
-	 * fallback when the default name already exists.
-	 */
-	if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) {
+	bd = backlight_device_get_by_name(name);
+	if (bd) {
+		put_device(&bd->dev);
+		/*
+		 * Using the same name independent of the drm device or connector
+		 * prevents registration of multiple backlight devices in the
+		 * driver. However, we need to use the default name for backward
+		 * compatibility. Use unique names for subsequent backlight devices as a
+		 * fallback when the default name already exists.
+		 */
 		kfree(name);
 		name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
 				 i915->drm.primary->index, connector->base.name);
 		if (!name)
 			return -ENOMEM;
-
-		bd = backlight_device_register(name, connector->base.kdev, connector,
-					       &intel_backlight_device_ops, &props);
 	}
+	bd = backlight_device_register(name, connector->base.kdev, connector,
+				       &intel_backlight_device_ops, &props);
 
 	if (IS_ERR(bd)) {
 		drm_err(&i915->drm,
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 013/107] ALSA: hda: intel-nhlt: remove use of __func__ in dev_dbg
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (11 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 012/107] drm/i915/display: avoid warnings when registering dual panel backlight Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 014/107] ALSA: hda: intel-nhlt: Correct the handling of fmt_config flexible array Greg Kroah-Hartman
                   ` (102 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Pierre-Louis Bossart,
	Ranjani Sridharan, Péter Ujfalusi, Bard Liao, Takashi Iwai,
	Sasha Levin

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

[ Upstream commit 6376ab02374822e1e8758a848ee736a182786a2e ]

The module and function information can be added with
'modprobe foo dyndbg=+pmf'

Suggested-by: Greg KH <gregkh@linuxfoundation.org>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220616220559.136160-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/hda/intel-nhlt.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c
index e2237239d922a..5e04fedaec49e 100644
--- a/sound/hda/intel-nhlt.c
+++ b/sound/hda/intel-nhlt.c
@@ -55,8 +55,8 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
 
 		/* find max number of channels based on format_configuration */
 		if (fmt_configs->fmt_count) {
-			dev_dbg(dev, "%s: found %d format definitions\n",
-				__func__, fmt_configs->fmt_count);
+			dev_dbg(dev, "found %d format definitions\n",
+				fmt_configs->fmt_count);
 
 			for (i = 0; i < fmt_configs->fmt_count; i++) {
 				struct wav_fmt_ext *fmt_ext;
@@ -66,9 +66,9 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
 				if (fmt_ext->fmt.channels > max_ch)
 					max_ch = fmt_ext->fmt.channels;
 			}
-			dev_dbg(dev, "%s: max channels found %d\n", __func__, max_ch);
+			dev_dbg(dev, "max channels found %d\n", max_ch);
 		} else {
-			dev_dbg(dev, "%s: No format information found\n", __func__);
+			dev_dbg(dev, "No format information found\n");
 		}
 
 		if (cfg->device_config.config_type != NHLT_CONFIG_TYPE_MIC_ARRAY) {
@@ -95,17 +95,16 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
 			}
 
 			if (dmic_geo > 0) {
-				dev_dbg(dev, "%s: Array with %d dmics\n", __func__, dmic_geo);
+				dev_dbg(dev, "Array with %d dmics\n", dmic_geo);
 			}
 			if (max_ch > dmic_geo) {
-				dev_dbg(dev, "%s: max channels %d exceed dmic number %d\n",
-					__func__, max_ch, dmic_geo);
+				dev_dbg(dev, "max channels %d exceed dmic number %d\n",
+					max_ch, dmic_geo);
 			}
 		}
 	}
 
-	dev_dbg(dev, "%s: dmic number %d max_ch %d\n",
-		__func__, dmic_geo, max_ch);
+	dev_dbg(dev, "dmic number %d max_ch %d\n", dmic_geo, max_ch);
 
 	return dmic_geo;
 }
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 014/107] ALSA: hda: intel-nhlt: Correct the handling of fmt_config flexible array
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (12 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 013/107] ALSA: hda: intel-nhlt: remove use of __func__ in dev_dbg Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 015/107] wifi: cfg80211: debugfs: fix return type in ht40allow_map_read() Greg Kroah-Hartman
                   ` (101 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Peter Ujfalusi, Pierre-Louis Bossart,
	Jaska Uimonen, Takashi Iwai, Sasha Levin

From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>

[ Upstream commit 2e6481a3f3ee6234ce577454e1d88aca55f51d47 ]

The struct nhlt_format's fmt_config is a flexible array, it must not be
used as normal array.
When moving to the next nhlt_fmt_cfg we need to take into account the data
behind the ->config.caps (indicated by ->config.size).

Fixes: a864e8f159b13 ("ALSA: hda: intel-nhlt: verify config type")
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Jaska Uimonen <jaska.uimonen@linux.intel.com>
Link: https://lore.kernel.org/r/20220823122405.18464-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/hda/intel-nhlt.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c
index 5e04fedaec49e..8714891f50b0a 100644
--- a/sound/hda/intel-nhlt.c
+++ b/sound/hda/intel-nhlt.c
@@ -55,16 +55,22 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
 
 		/* find max number of channels based on format_configuration */
 		if (fmt_configs->fmt_count) {
+			struct nhlt_fmt_cfg *fmt_cfg = fmt_configs->fmt_config;
+
 			dev_dbg(dev, "found %d format definitions\n",
 				fmt_configs->fmt_count);
 
 			for (i = 0; i < fmt_configs->fmt_count; i++) {
 				struct wav_fmt_ext *fmt_ext;
 
-				fmt_ext = &fmt_configs->fmt_config[i].fmt_ext;
+				fmt_ext = &fmt_cfg->fmt_ext;
 
 				if (fmt_ext->fmt.channels > max_ch)
 					max_ch = fmt_ext->fmt.channels;
+
+				/* Move to the next nhlt_fmt_cfg */
+				fmt_cfg = (struct nhlt_fmt_cfg *)(fmt_cfg->config.caps +
+								  fmt_cfg->config.size);
 			}
 			dev_dbg(dev, "max channels found %d\n", max_ch);
 		} else {
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 015/107] wifi: cfg80211: debugfs: fix return type in ht40allow_map_read()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (13 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 014/107] ALSA: hda: intel-nhlt: Correct the handling of fmt_config flexible array Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 016/107] Revert "xhci: turn off port power in shutdown" Greg Kroah-Hartman
                   ` (100 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Dan Carpenter, Johannes Berg, Sasha Levin

From: Dan Carpenter <dan.carpenter@oracle.com>

[ Upstream commit d776763f48084926b5d9e25507a3ddb7c9243d5e ]

The return type is supposed to be ssize_t, which is signed long,
but "r" was declared as unsigned int.  This means that on 64 bit systems
we return positive values instead of negative error codes.

Fixes: 80a3511d70e8 ("cfg80211: add debugfs HT40 allow map")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: https://lore.kernel.org/r/YutvOQeJm0UjLhwU@kili
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/debugfs.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index aab43469a2f04..0878b162890af 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -65,9 +65,10 @@ static ssize_t ht40allow_map_read(struct file *file,
 {
 	struct wiphy *wiphy = file->private_data;
 	char *buf;
-	unsigned int offset = 0, buf_size = PAGE_SIZE, i, r;
+	unsigned int offset = 0, buf_size = PAGE_SIZE, i;
 	enum nl80211_band band;
 	struct ieee80211_supported_band *sband;
+	ssize_t r;
 
 	buf = kzalloc(buf_size, GFP_KERNEL);
 	if (!buf)
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 016/107] Revert "xhci: turn off port power in shutdown"
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (14 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 015/107] wifi: cfg80211: debugfs: fix return type in ht40allow_map_read() Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 017/107] net: sparx5: fix handling uneven length packets in manual extraction Greg Kroah-Hartman
                   ` (99 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Mathias Nyman, Sasha Levin

From: Mathias Nyman <mathias.nyman@linux.intel.com>

[ Upstream commit 8531aa1659f7278d4f2ec7408cc000eaa8d85217 ]

This reverts commit 83810f84ecf11dfc5a9414a8b762c3501b328185.

Turning off port power in shutdown did cause issues such as a laptop not
proprly powering off, and some specific usb devies failing to enumerate the
subsequent boot after a warm reset.

So revert this.

Fixes: 83810f84ecf1 ("xhci: turn off port power in shutdown")
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20220825150840.132216-4-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/usb/host/xhci-hub.c |  2 +-
 drivers/usb/host/xhci.c     | 15 ++-------------
 drivers/usb/host/xhci.h     |  2 --
 3 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index fc322a9526c8c..f65f1ba2b5929 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -652,7 +652,7 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd)
  * It will release and re-aquire the lock while calling ACPI
  * method.
  */
-void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd,
+static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd,
 				u16 index, bool on, unsigned long *flags)
 	__must_hold(&xhci->lock)
 {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d76c10f9ad807..e3767651c9a9e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -776,8 +776,6 @@ static void xhci_stop(struct usb_hcd *hcd)
 void xhci_shutdown(struct usb_hcd *hcd)
 {
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	unsigned long flags;
-	int i;
 
 	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
 		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
@@ -793,21 +791,12 @@ void xhci_shutdown(struct usb_hcd *hcd)
 		del_timer_sync(&xhci->shared_hcd->rh_timer);
 	}
 
-	spin_lock_irqsave(&xhci->lock, flags);
+	spin_lock_irq(&xhci->lock);
 	xhci_halt(xhci);
-
-	/* Power off USB2 ports*/
-	for (i = 0; i < xhci->usb2_rhub.num_ports; i++)
-		xhci_set_port_power(xhci, xhci->main_hcd, i, false, &flags);
-
-	/* Power off USB3 ports*/
-	for (i = 0; i < xhci->usb3_rhub.num_ports; i++)
-		xhci_set_port_power(xhci, xhci->shared_hcd, i, false, &flags);
-
 	/* Workaround for spurious wakeups at shutdown with HSW */
 	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
 		xhci_reset(xhci, XHCI_RESET_SHORT_USEC);
-	spin_unlock_irqrestore(&xhci->lock, flags);
+	spin_unlock_irq(&xhci->lock);
 
 	xhci_cleanup_msix(xhci);
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 101f1956a96ca..81e1bfdf83988 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2174,8 +2174,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
 int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
 int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
 struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd);
-void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index,
-			 bool on, unsigned long *flags);
 
 void xhci_hc_died(struct xhci_hcd *xhci);
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 017/107] net: sparx5: fix handling uneven length packets in manual extraction
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (15 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 016/107] Revert "xhci: turn off port power in shutdown" Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 018/107] net: smsc911x: Stop and start PHY during suspend and resume Greg Kroah-Hartman
                   ` (98 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Casper Andersson, Steen Hegelund,
	Jakub Kicinski, Sasha Levin

From: Casper Andersson <casper.casan@gmail.com>

[ Upstream commit 7498a457ecf7ff2c4d379360aa8f24566bb1543e ]

Packets that are not of length divisible by 4 (e.g. 77, 78, 79) would
have the checksum included up to next multiple of 4 (a 77 bytes packet
would have 3 bytes of ethernet checksum included). The check for the
value expects it in host (Little) endian.

Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
Signed-off-by: Casper Andersson <casper.casan@gmail.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Link: https://lore.kernel.org/r/20220825084955.684637-1-casper.casan@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 148d431fcde42..c460168131c26 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -107,6 +107,8 @@ static void sparx5_xtr_grp(struct sparx5 *sparx5, u8 grp, bool byte_swap)
 			/* This assumes STATUS_WORD_POS == 1, Status
 			 * just after last data
 			 */
+			if (!byte_swap)
+				val = ntohl((__force __be32)val);
 			byte_cnt -= (4 - XTR_VALID_BYTES(val));
 			eof_flag = true;
 			break;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 018/107] net: smsc911x: Stop and start PHY during suspend and resume
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (16 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 017/107] net: sparx5: fix handling uneven length packets in manual extraction Greg Kroah-Hartman
@ 2022-09-06 13:29 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 019/107] openvswitch: fix memory leak at failed datapath creation Greg Kroah-Hartman
                   ` (97 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Geert Uytterhoeven, Marek Szyprowski,
	Florian Fainelli, Jakub Kicinski, Sasha Levin

From: Florian Fainelli <f.fainelli@gmail.com>

[ Upstream commit 3ce9f2bef75528936c78a7053301f5725f622f3a ]

Commit 744d23c71af3 ("net: phy: Warn about incorrect
mdio_bus_phy_resume() state") unveiled that the smsc911x driver was not
properly stopping and restarting the PHY during suspend/resume. Correct
that by indicating that the MAC is in charge of PHY PM operations and
ensure that all MDIO bus activity is quiescent during suspend.

Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Fixes: fba863b81604 ("net: phy: make PHY PM ops a no-op if MAC driver manages PHY PM")
Fixes: 2aa70f864955 ("net: smsc911x: Quieten netif during suspend")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20220825023951.3220-1-f.fainelli@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/smsc/smsc911x.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 592e191adbf7d..63b99dd8ca51c 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1037,6 +1037,8 @@ static int smsc911x_mii_probe(struct net_device *dev)
 		return ret;
 	}
 
+	/* Indicate that the MAC is responsible for managing PHY PM */
+	phydev->mac_managed_pm = true;
 	phy_attached_info(phydev);
 
 	phy_set_max_speed(phydev, SPEED_100);
@@ -2584,6 +2586,8 @@ static int smsc911x_suspend(struct device *dev)
 	if (netif_running(ndev)) {
 		netif_stop_queue(ndev);
 		netif_device_detach(ndev);
+		if (!device_may_wakeup(dev))
+			phy_stop(ndev->phydev);
 	}
 
 	/* enable wake on LAN, energy detection and the external PME
@@ -2625,6 +2629,8 @@ static int smsc911x_resume(struct device *dev)
 	if (netif_running(ndev)) {
 		netif_device_attach(ndev);
 		netif_start_queue(ndev);
+		if (!device_may_wakeup(dev))
+			phy_start(ndev->phydev);
 	}
 
 	return 0;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 019/107] openvswitch: fix memory leak at failed datapath creation
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (17 preceding siblings ...)
  2022-09-06 13:29 ` [PATCH 5.15 018/107] net: smsc911x: Stop and start PHY during suspend and resume Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 020/107] net: dsa: xrs700x: Use irqsave variant for u64 stats update Greg Kroah-Hartman
                   ` (96 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Aaron Conole, Andrey Zhadchenko,
	Jakub Kicinski, Sasha Levin

From: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>

[ Upstream commit a87406f4adee9c53b311d8a1ba2849c69e29a6d0 ]

ovs_dp_cmd_new()->ovs_dp_change()->ovs_dp_set_upcall_portids()
allocates array via kmalloc.
If for some reason new_vport() fails during ovs_dp_cmd_new()
dp->upcall_portids must be freed.
Add missing kfree.

Kmemleak example:
unreferenced object 0xffff88800c382500 (size 64):
  comm "dump_state", pid 323, jiffies 4294955418 (age 104.347s)
  hex dump (first 32 bytes):
    5e c2 79 e4 1f 7a 38 c7 09 21 38 0c 80 88 ff ff  ^.y..z8..!8.....
    03 00 00 00 0a 00 00 00 14 00 00 00 28 00 00 00  ............(...
  backtrace:
    [<0000000071bebc9f>] ovs_dp_set_upcall_portids+0x38/0xa0
    [<000000000187d8bd>] ovs_dp_change+0x63/0xe0
    [<000000002397e446>] ovs_dp_cmd_new+0x1f0/0x380
    [<00000000aa06f36e>] genl_family_rcv_msg_doit+0xea/0x150
    [<000000008f583bc4>] genl_rcv_msg+0xdc/0x1e0
    [<00000000fa10e377>] netlink_rcv_skb+0x50/0x100
    [<000000004959cece>] genl_rcv+0x24/0x40
    [<000000004699ac7f>] netlink_unicast+0x23e/0x360
    [<00000000c153573e>] netlink_sendmsg+0x24e/0x4b0
    [<000000006f4aa380>] sock_sendmsg+0x62/0x70
    [<00000000d0068654>] ____sys_sendmsg+0x230/0x270
    [<0000000012dacf7d>] ___sys_sendmsg+0x88/0xd0
    [<0000000011776020>] __sys_sendmsg+0x59/0xa0
    [<000000002e8f2dc1>] do_syscall_64+0x3b/0x90
    [<000000003243e7cb>] entry_SYSCALL_64_after_hwframe+0x63/0xcd

Fixes: b83d23a2a38b ("openvswitch: Introduce per-cpu upcall dispatch")
Acked-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
Link: https://lore.kernel.org/r/20220825020326.664073-1-andrey.zhadchenko@virtuozzo.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/openvswitch/datapath.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 67ad08320886b..5e2c83cb7b129 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1801,7 +1801,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 				ovs_dp_reset_user_features(skb, info);
 		}
 
-		goto err_unlock_and_destroy_meters;
+		goto err_destroy_portids;
 	}
 
 	err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
@@ -1816,6 +1816,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	ovs_notify(&dp_datapath_genl_family, reply, info);
 	return 0;
 
+err_destroy_portids:
+	kfree(rcu_dereference_raw(dp->upcall_portids));
 err_unlock_and_destroy_meters:
 	ovs_unlock();
 	ovs_meters_exit(dp);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 020/107] net: dsa: xrs700x: Use irqsave variant for u64 stats update
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (18 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 019/107] openvswitch: fix memory leak at failed datapath creation Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 021/107] net: sched: tbf: dont call qdisc_put() while holding tree lock Greg Kroah-Hartman
                   ` (95 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Andrew Lunn, Florian Fainelli,
	George McCollister, Vivien Didelot, Vladimir Oltean,
	Sebastian Andrzej Siewior, David S. Miller, Sasha Levin

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

[ Upstream commit 3f8ae9fe0409698799e173f698b714f34570b64b ]

xrs700x_read_port_counters() updates the stats from a worker using the
u64_stats_update_begin() version. This is okay on 32-UP since on the
reader side preemption is disabled.
On 32bit-SMP the writer can be preempted by the reader at which point
the reader will spin on the seqcount until writer continues and
completes the update.

Assigning the mib_mutex mutex to the underlying seqcount would ensure
proper synchronisation. The API for that on the u64_stats_init() side
isn't available. Since it is the only user, just use disable interrupts
during the update.

Use u64_stats_update_begin_irqsave() on the writer side to ensure an
uninterrupted update.

Fixes: ee00b24f32eb8 ("net: dsa: add Arrow SpeedChips XRS700x driver")
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: George McCollister <george.mccollister@gmail.com>
Cc: Vivien Didelot <vivien.didelot@gmail.com>
Cc: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: George McCollister <george.mccollister@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/dsa/xrs700x/xrs700x.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index 469420941054e..cf363d5a30020 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -108,6 +108,7 @@ static void xrs700x_read_port_counters(struct xrs700x *priv, int port)
 {
 	struct xrs700x_port *p = &priv->ports[port];
 	struct rtnl_link_stats64 stats;
+	unsigned long flags;
 	int i;
 
 	memset(&stats, 0, sizeof(stats));
@@ -137,9 +138,9 @@ static void xrs700x_read_port_counters(struct xrs700x *priv, int port)
 	 */
 	stats.rx_packets += stats.multicast;
 
-	u64_stats_update_begin(&p->syncp);
+	flags = u64_stats_update_begin_irqsave(&p->syncp);
 	p->stats64 = stats;
-	u64_stats_update_end(&p->syncp);
+	u64_stats_update_end_irqrestore(&p->syncp, flags);
 
 	mutex_unlock(&p->mib_mutex);
 }
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 021/107] net: sched: tbf: dont call qdisc_put() while holding tree lock
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (19 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 020/107] net: dsa: xrs700x: Use irqsave variant for u64 stats update Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 022/107] net/sched: fix netdevice reference leaks in attach_default_qdiscs() Greg Kroah-Hartman
                   ` (94 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Zhengchao Shao, Paolo Abeni, Sasha Levin

From: Zhengchao Shao <shaozhengchao@huawei.com>

[ Upstream commit b05972f01e7d30419987a1f221b5593668fd6448 ]

The issue is the same to commit c2999f7fb05b ("net: sched: multiq: don't
call qdisc_put() while holding tree lock"). Qdiscs call qdisc_put() while
holding sch tree spinlock, which results sleeping-while-atomic BUG.

Fixes: c266f64dbfa2 ("net: sched: protect block state with mutex")
Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
Link: https://lore.kernel.org/r/20220826013930.340121-1-shaozhengchao@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_tbf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 78e79029dc631..6eb17004a9e44 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -342,6 +342,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 	struct nlattr *tb[TCA_TBF_MAX + 1];
 	struct tc_tbf_qopt *qopt;
 	struct Qdisc *child = NULL;
+	struct Qdisc *old = NULL;
 	struct psched_ratecfg rate;
 	struct psched_ratecfg peak;
 	u64 max_size;
@@ -433,7 +434,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 	sch_tree_lock(sch);
 	if (child) {
 		qdisc_tree_flush_backlog(q->qdisc);
-		qdisc_put(q->qdisc);
+		old = q->qdisc;
 		q->qdisc = child;
 	}
 	q->limit = qopt->limit;
@@ -453,6 +454,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 	memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
 
 	sch_tree_unlock(sch);
+	qdisc_put(old);
 	err = 0;
 
 	tbf_offload_change(sch);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 022/107] net/sched: fix netdevice reference leaks in attach_default_qdiscs()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (20 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 021/107] net: sched: tbf: dont call qdisc_put() while holding tree lock Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 023/107] ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler Greg Kroah-Hartman
                   ` (93 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Wang Hai, Paolo Abeni, Sasha Levin

From: Wang Hai <wanghai38@huawei.com>

[ Upstream commit f612466ebecb12a00d9152344ddda6f6345f04dc ]

In attach_default_qdiscs(), if a dev has multiple queues and queue 0 fails
to attach qdisc because there is no memory in attach_one_default_qdisc().
Then dev->qdisc will be noop_qdisc by default. But the other queues may be
able to successfully attach to default qdisc.

In this case, the fallback to noqueue process will be triggered. If the
original attached qdisc is not released and a new one is directly
attached, this will cause netdevice reference leaks.

The following is the bug log:

veth0: default qdisc (fq_codel) fail, fallback to noqueue
unregister_netdevice: waiting for veth0 to become free. Usage count = 32
leaked reference.
 qdisc_alloc+0x12e/0x210
 qdisc_create_dflt+0x62/0x140
 attach_one_default_qdisc.constprop.41+0x44/0x70
 dev_activate+0x128/0x290
 __dev_open+0x12a/0x190
 __dev_change_flags+0x1a2/0x1f0
 dev_change_flags+0x23/0x60
 do_setlink+0x332/0x1150
 __rtnl_newlink+0x52f/0x8e0
 rtnl_newlink+0x43/0x70
 rtnetlink_rcv_msg+0x140/0x3b0
 netlink_rcv_skb+0x50/0x100
 netlink_unicast+0x1bb/0x290
 netlink_sendmsg+0x37c/0x4e0
 sock_sendmsg+0x5f/0x70
 ____sys_sendmsg+0x208/0x280

Fix this bug by clearing any non-noop qdiscs that may have been assigned
before trying to re-attach.

Fixes: bf6dba76d278 ("net: sched: fallback to qdisc noqueue if default qdisc setup fail")
Signed-off-by: Wang Hai <wanghai38@huawei.com>
Link: https://lore.kernel.org/r/20220826090055.24424-1-wanghai38@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_generic.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 250d87d993cb7..02299785209c1 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -1083,6 +1083,21 @@ struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
 }
 EXPORT_SYMBOL(dev_graft_qdisc);
 
+static void shutdown_scheduler_queue(struct net_device *dev,
+				     struct netdev_queue *dev_queue,
+				     void *_qdisc_default)
+{
+	struct Qdisc *qdisc = dev_queue->qdisc_sleeping;
+	struct Qdisc *qdisc_default = _qdisc_default;
+
+	if (qdisc) {
+		rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
+		dev_queue->qdisc_sleeping = qdisc_default;
+
+		qdisc_put(qdisc);
+	}
+}
+
 static void attach_one_default_qdisc(struct net_device *dev,
 				     struct netdev_queue *dev_queue,
 				     void *_unused)
@@ -1130,6 +1145,7 @@ static void attach_default_qdiscs(struct net_device *dev)
 	if (qdisc == &noop_qdisc) {
 		netdev_warn(dev, "default qdisc (%s) fail, fallback to %s\n",
 			    default_qdisc_ops->id, noqueue_qdisc_ops.id);
+		netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
 		dev->priv_flags |= IFF_NO_QUEUE;
 		netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
 		qdisc = txq->qdisc_sleeping;
@@ -1384,21 +1400,6 @@ void dev_init_scheduler(struct net_device *dev)
 	timer_setup(&dev->watchdog_timer, dev_watchdog, 0);
 }
 
-static void shutdown_scheduler_queue(struct net_device *dev,
-				     struct netdev_queue *dev_queue,
-				     void *_qdisc_default)
-{
-	struct Qdisc *qdisc = dev_queue->qdisc_sleeping;
-	struct Qdisc *qdisc_default = _qdisc_default;
-
-	if (qdisc) {
-		rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
-		dev_queue->qdisc_sleeping = qdisc_default;
-
-		qdisc_put(qdisc);
-	}
-}
-
 void dev_shutdown(struct net_device *dev)
 {
 	netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 023/107] ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (21 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 022/107] net/sched: fix netdevice reference leaks in attach_default_qdiscs() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 024/107] mlxbf_gige: compute MDIO period based on i1clk Greg Kroah-Hartman
                   ` (92 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Duoming Zhou, David S. Miller, Sasha Levin

From: Duoming Zhou <duoming@zju.edu.cn>

[ Upstream commit c0955bf957be4bead01fae1d791476260da7325d ]

The function neigh_timer_handler() is a timer handler that runs in an
atomic context. When used by rocker, neigh_timer_handler() calls
"kzalloc(.., GFP_KERNEL)" that may sleep. As a result, the sleep in
atomic context bug will happen. One of the processes is shown below:

ofdpa_fib4_add()
 ...
 neigh_add_timer()

(wait a timer)

neigh_timer_handler()
 neigh_release()
  neigh_destroy()
   rocker_port_neigh_destroy()
    rocker_world_port_neigh_destroy()
     ofdpa_port_neigh_destroy()
      ofdpa_port_ipv4_neigh()
       kzalloc(sizeof(.., GFP_KERNEL) //may sleep

This patch changes the gfp_t parameter of kzalloc() from GFP_KERNEL to
GFP_ATOMIC in order to mitigate the bug.

Fixes: 00fc0c51e35b ("rocker: Change world_ops API and implementation to be switchdev independant")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/rocker/rocker_ofdpa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
index bc70c6abd6a5b..58cf7cc54f408 100644
--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
+++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
@@ -1273,7 +1273,7 @@ static int ofdpa_port_ipv4_neigh(struct ofdpa_port *ofdpa_port,
 	bool removing;
 	int err = 0;
 
-	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 	if (!entry)
 		return -ENOMEM;
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 024/107] mlxbf_gige: compute MDIO period based on i1clk
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (22 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 023/107] ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 025/107] kcm: fix strp_init() order and cleanup Greg Kroah-Hartman
                   ` (91 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Asmaa Mnebhi, David Thompson,
	Jakub Kicinski, Sasha Levin

From: David Thompson <davthompson@nvidia.com>

[ Upstream commit 3a1a274e933fca73fdc960cb1f60636cd285a265 ]

This patch adds logic to compute the MDIO period based on
the i1clk, and thereafter write the MDIO period into the YU
MDIO config register. The i1clk resource from the ACPI table
is used to provide addressing to YU bootrecord PLL registers.
The values in these registers are used to compute MDIO period.
If the i1clk resource is not present in the ACPI table, then
the current default hardcorded value of 430Mhz is used.
The i1clk clock value of 430MHz is only accurate for boards
with BF2 mid bin and main bin SoCs. The BF2 high bin SoCs
have i1clk = 500MHz, but can support a slower MDIO period.

Fixes: f92e1869d74e ("Add Mellanox BlueField Gigabit Ethernet driver")
Reviewed-by: Asmaa Mnebhi <asmaa@nvidia.com>
Signed-off-by: David Thompson <davthompson@nvidia.com>
Link: https://lore.kernel.org/r/20220826155916.12491-1-davthompson@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../ethernet/mellanox/mlxbf_gige/mlxbf_gige.h |   4 +-
 .../mellanox/mlxbf_gige/mlxbf_gige_mdio.c     | 122 +++++++++++++++---
 .../mellanox/mlxbf_gige/mlxbf_gige_regs.h     |   2 +
 3 files changed, 110 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
index e3509e69ed1c6..3e8725b7f0b70 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
@@ -80,6 +80,7 @@ struct mlxbf_gige {
 	struct net_device *netdev;
 	struct platform_device *pdev;
 	void __iomem *mdio_io;
+	void __iomem *clk_io;
 	struct mii_bus *mdiobus;
 	void __iomem *gpio_io;
 	struct irq_domain *irqdomain;
@@ -149,7 +150,8 @@ enum mlxbf_gige_res {
 	MLXBF_GIGE_RES_MDIO9,
 	MLXBF_GIGE_RES_GPIO0,
 	MLXBF_GIGE_RES_LLU,
-	MLXBF_GIGE_RES_PLU
+	MLXBF_GIGE_RES_PLU,
+	MLXBF_GIGE_RES_CLK
 };
 
 /* Version of register data returned by mlxbf_gige_get_regs() */
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
index 7905179a95753..f979ba7e5effc 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
@@ -22,10 +22,23 @@
 #include <linux/property.h>
 
 #include "mlxbf_gige.h"
+#include "mlxbf_gige_regs.h"
 
 #define MLXBF_GIGE_MDIO_GW_OFFSET	0x0
 #define MLXBF_GIGE_MDIO_CFG_OFFSET	0x4
 
+#define MLXBF_GIGE_MDIO_FREQ_REFERENCE 156250000ULL
+#define MLXBF_GIGE_MDIO_COREPLL_CONST  16384ULL
+#define MLXBF_GIGE_MDC_CLK_NS          400
+#define MLXBF_GIGE_MDIO_PLL_I1CLK_REG1 0x4
+#define MLXBF_GIGE_MDIO_PLL_I1CLK_REG2 0x8
+#define MLXBF_GIGE_MDIO_CORE_F_SHIFT   0
+#define MLXBF_GIGE_MDIO_CORE_F_MASK    GENMASK(25, 0)
+#define MLXBF_GIGE_MDIO_CORE_R_SHIFT   26
+#define MLXBF_GIGE_MDIO_CORE_R_MASK    GENMASK(31, 26)
+#define MLXBF_GIGE_MDIO_CORE_OD_SHIFT  0
+#define MLXBF_GIGE_MDIO_CORE_OD_MASK   GENMASK(3, 0)
+
 /* Support clause 22 */
 #define MLXBF_GIGE_MDIO_CL22_ST1	0x1
 #define MLXBF_GIGE_MDIO_CL22_WRITE	0x1
@@ -50,27 +63,76 @@
 #define MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK		GENMASK(23, 16)
 #define MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK		GENMASK(31, 24)
 
+#define MLXBF_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \
+				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \
+				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \
+				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \
+				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13))
+
+#define MLXBF_GIGE_BF2_COREPLL_ADDR 0x02800c30
+#define MLXBF_GIGE_BF2_COREPLL_SIZE 0x0000000c
+
+static struct resource corepll_params[] = {
+	[MLXBF_GIGE_VERSION_BF2] = {
+		.start = MLXBF_GIGE_BF2_COREPLL_ADDR,
+		.end = MLXBF_GIGE_BF2_COREPLL_ADDR + MLXBF_GIGE_BF2_COREPLL_SIZE - 1,
+		.name = "COREPLL_RES"
+	},
+};
+
+/* Returns core clock i1clk in Hz */
+static u64 calculate_i1clk(struct mlxbf_gige *priv)
+{
+	u8 core_od, core_r;
+	u64 freq_output;
+	u32 reg1, reg2;
+	u32 core_f;
+
+	reg1 = readl(priv->clk_io + MLXBF_GIGE_MDIO_PLL_I1CLK_REG1);
+	reg2 = readl(priv->clk_io + MLXBF_GIGE_MDIO_PLL_I1CLK_REG2);
+
+	core_f = (reg1 & MLXBF_GIGE_MDIO_CORE_F_MASK) >>
+		MLXBF_GIGE_MDIO_CORE_F_SHIFT;
+	core_r = (reg1 & MLXBF_GIGE_MDIO_CORE_R_MASK) >>
+		MLXBF_GIGE_MDIO_CORE_R_SHIFT;
+	core_od = (reg2 & MLXBF_GIGE_MDIO_CORE_OD_MASK) >>
+		MLXBF_GIGE_MDIO_CORE_OD_SHIFT;
+
+	/* Compute PLL output frequency as follow:
+	 *
+	 *                                     CORE_F / 16384
+	 * freq_output = freq_reference * ----------------------------
+	 *                              (CORE_R + 1) * (CORE_OD + 1)
+	 */
+	freq_output = div_u64((MLXBF_GIGE_MDIO_FREQ_REFERENCE * core_f),
+			      MLXBF_GIGE_MDIO_COREPLL_CONST);
+	freq_output = div_u64(freq_output, (core_r + 1) * (core_od + 1));
+
+	return freq_output;
+}
+
 /* Formula for encoding the MDIO period. The encoded value is
  * passed to the MDIO config register.
  *
- * mdc_clk = 2*(val + 1)*i1clk
+ * mdc_clk = 2*(val + 1)*(core clock in sec)
  *
- * 400 ns = 2*(val + 1)*(((1/430)*1000) ns)
+ * i1clk is in Hz:
+ * 400 ns = 2*(val + 1)*(1/i1clk)
  *
- * val = (((400 * 430 / 1000) / 2) - 1)
+ * val = (((400/10^9) / (1/i1clk) / 2) - 1)
+ * val = (400/2 * i1clk)/10^9 - 1
  */
-#define MLXBF_GIGE_I1CLK_MHZ		430
-#define MLXBF_GIGE_MDC_CLK_NS		400
+static u8 mdio_period_map(struct mlxbf_gige *priv)
+{
+	u8 mdio_period;
+	u64 i1clk;
 
-#define MLXBF_GIGE_MDIO_PERIOD	(((MLXBF_GIGE_MDC_CLK_NS * MLXBF_GIGE_I1CLK_MHZ / 1000) / 2) - 1)
+	i1clk = calculate_i1clk(priv);
 
-#define MLXBF_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \
-				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \
-				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \
-				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK, \
-					    MLXBF_GIGE_MDIO_PERIOD) | \
-				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \
-				 FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13))
+	mdio_period = div_u64((MLXBF_GIGE_MDC_CLK_NS >> 1) * i1clk, 1000000000) - 1;
+
+	return mdio_period;
+}
 
 static u32 mlxbf_gige_mdio_create_cmd(u16 data, int phy_add,
 				      int phy_reg, u32 opcode)
@@ -123,9 +185,9 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
 				 int phy_reg, u16 val)
 {
 	struct mlxbf_gige *priv = bus->priv;
+	u32 temp;
 	u32 cmd;
 	int ret;
-	u32 temp;
 
 	if (phy_reg & MII_ADDR_C45)
 		return -EOPNOTSUPP;
@@ -142,18 +204,44 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
 	return ret;
 }
 
+static void mlxbf_gige_mdio_cfg(struct mlxbf_gige *priv)
+{
+	u8 mdio_period;
+	u32 val;
+
+	mdio_period = mdio_period_map(priv);
+
+	val = MLXBF_GIGE_MDIO_CFG_VAL;
+	val |= FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK, mdio_period);
+	writel(val, priv->mdio_io + MLXBF_GIGE_MDIO_CFG_OFFSET);
+}
+
 int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)
 {
 	struct device *dev = &pdev->dev;
+	struct resource *res;
 	int ret;
 
 	priv->mdio_io = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MDIO9);
 	if (IS_ERR(priv->mdio_io))
 		return PTR_ERR(priv->mdio_io);
 
-	/* Configure mdio parameters */
-	writel(MLXBF_GIGE_MDIO_CFG_VAL,
-	       priv->mdio_io + MLXBF_GIGE_MDIO_CFG_OFFSET);
+	/* clk resource shared with other drivers so cannot use
+	 * devm_platform_ioremap_resource
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, MLXBF_GIGE_RES_CLK);
+	if (!res) {
+		/* For backward compatibility with older ACPI tables, also keep
+		 * CLK resource internal to the driver.
+		 */
+		res = &corepll_params[MLXBF_GIGE_VERSION_BF2];
+	}
+
+	priv->clk_io = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(priv->clk_io))
+		return PTR_ERR(priv->clk_io);
+
+	mlxbf_gige_mdio_cfg(priv);
 
 	priv->mdiobus = devm_mdiobus_alloc(dev);
 	if (!priv->mdiobus) {
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
index 5fb33c9294bf9..7be3a793984d5 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
@@ -8,6 +8,8 @@
 #ifndef __MLXBF_GIGE_REGS_H__
 #define __MLXBF_GIGE_REGS_H__
 
+#define MLXBF_GIGE_VERSION                            0x0000
+#define MLXBF_GIGE_VERSION_BF2                        0x0
 #define MLXBF_GIGE_STATUS                             0x0010
 #define MLXBF_GIGE_STATUS_READY                       BIT(0)
 #define MLXBF_GIGE_INT_STATUS                         0x0028
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 025/107] kcm: fix strp_init() order and cleanup
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (23 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 024/107] mlxbf_gige: compute MDIO period based on i1clk Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 026/107] sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb Greg Kroah-Hartman
                   ` (90 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, syzbot+e696806ef96cdd2d87cd,
	Tom Herbert, Cong Wang, Jakub Kicinski, Sasha Levin,
	syzbot+9fc084a4348493ef65d2

From: Cong Wang <cong.wang@bytedance.com>

[ Upstream commit 8fc29ff3910f3af08a7c40a75d436b5720efe2bf ]

strp_init() is called just a few lines above this csk->sk_user_data
check, it also initializes strp->work etc., therefore, it is
unnecessary to call strp_done() to cancel the freshly initialized
work.

And if sk_user_data is already used by KCM, psock->strp should not be
touched, particularly strp->work state, so we need to move strp_init()
after the csk->sk_user_data check.

This also makes a lockdep warning reported by syzbot go away.

Reported-and-tested-by: syzbot+9fc084a4348493ef65d2@syzkaller.appspotmail.com
Reported-by: syzbot+e696806ef96cdd2d87cd@syzkaller.appspotmail.com
Fixes: e5571240236c ("kcm: Check if sk_user_data already set in kcm_attach")
Fixes: dff8baa26117 ("kcm: Call strp_stop before strp_done in kcm_attach")
Cc: Tom Herbert <tom@herbertland.com>
Signed-off-by: Cong Wang <cong.wang@bytedance.com>
Link: https://lore.kernel.org/r/20220827181314.193710-1-xiyou.wangcong@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/kcm/kcmsock.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index 11a715d76a4f1..f780fbe82e7dc 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -1411,12 +1411,6 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
 	psock->sk = csk;
 	psock->bpf_prog = prog;
 
-	err = strp_init(&psock->strp, csk, &cb);
-	if (err) {
-		kmem_cache_free(kcm_psockp, psock);
-		goto out;
-	}
-
 	write_lock_bh(&csk->sk_callback_lock);
 
 	/* Check if sk_user_data is already by KCM or someone else.
@@ -1424,13 +1418,18 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
 	 */
 	if (csk->sk_user_data) {
 		write_unlock_bh(&csk->sk_callback_lock);
-		strp_stop(&psock->strp);
-		strp_done(&psock->strp);
 		kmem_cache_free(kcm_psockp, psock);
 		err = -EALREADY;
 		goto out;
 	}
 
+	err = strp_init(&psock->strp, csk, &cb);
+	if (err) {
+		write_unlock_bh(&csk->sk_callback_lock);
+		kmem_cache_free(kcm_psockp, psock);
+		goto out;
+	}
+
 	psock->save_data_ready = csk->sk_data_ready;
 	psock->save_write_space = csk->sk_write_space;
 	psock->save_state_change = csk->sk_state_change;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 026/107] sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (24 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 025/107] kcm: fix strp_init() order and cleanup Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 027/107] tcp: annotate data-race around challenge_timestamp Greg Kroah-Hartman
                   ` (89 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Toke Høiland-Jørgensen,
	Jakub Kicinski, Sasha Levin, zdi-disclosures

From: Toke Høiland-Jørgensen <toke@toke.dk>

[ Upstream commit 90fabae8a2c225c4e4936723c38857887edde5cc ]

When the GSO splitting feature of sch_cake is enabled, GSO superpackets
will be broken up and the resulting segments enqueued in place of the
original skb. In this case, CAKE calls consume_skb() on the original skb,
but still returns NET_XMIT_SUCCESS. This can confuse parent qdiscs into
assuming the original skb still exists, when it really has been freed. Fix
this by adding the __NET_XMIT_STOLEN flag to the return value in this case.

Fixes: 0c850344d388 ("sch_cake: Conditionally split GSO segments")
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-18231
Link: https://lore.kernel.org/r/20220831092103.442868-1-toke@toke.dk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_cake.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index 857aaebd49f43..6944c669731c4 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1713,6 +1713,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 	}
 	idx--;
 	flow = &b->flows[idx];
+	ret = NET_XMIT_SUCCESS;
 
 	/* ensure shaper state isn't stale */
 	if (!b->tin_backlog) {
@@ -1771,6 +1772,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 
 		qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen);
 		consume_skb(skb);
+		ret |= __NET_XMIT_STOLEN;
 	} else {
 		/* not splitting */
 		cobalt_set_enqueue_time(skb, now);
@@ -1904,7 +1906,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 		}
 		b->drop_overlimit += dropped;
 	}
-	return NET_XMIT_SUCCESS;
+	return ret;
 }
 
 static struct sk_buff *cake_dequeue_one(struct Qdisc *sch)
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 027/107] tcp: annotate data-race around challenge_timestamp
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (25 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 026/107] sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 028/107] Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb" Greg Kroah-Hartman
                   ` (88 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, syzbot, Eric Dumazet, Neal Cardwell,
	Jakub Kicinski, Sasha Levin

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 8c70521238b7863c2af607e20bcba20f974c969b ]

challenge_timestamp can be read an written by concurrent threads.

This was expected, but we need to annotate the race to avoid potential issues.

Following patch moves challenge_timestamp and challenge_count
to per-netns storage to provide better isolation.

Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/tcp_input.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a33e6aa42a4c5..7fd7e7cba0c92 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3623,11 +3623,11 @@ static void tcp_send_challenge_ack(struct sock *sk, const struct sk_buff *skb)
 
 	/* Then check host-wide RFC 5961 rate limit. */
 	now = jiffies / HZ;
-	if (now != challenge_timestamp) {
+	if (now != READ_ONCE(challenge_timestamp)) {
 		u32 ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
 		u32 half = (ack_limit + 1) >> 1;
 
-		challenge_timestamp = now;
+		WRITE_ONCE(challenge_timestamp, now);
 		WRITE_ONCE(challenge_count, half + prandom_u32_max(ack_limit));
 	}
 	count = READ_ONCE(challenge_count);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 028/107] Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb"
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (26 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 027/107] tcp: annotate data-race around challenge_timestamp Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 029/107] net/smc: Remove redundant refcount increase Greg Kroah-Hartman
                   ` (87 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Jakub Kicinski, Sasha Levin

From: Jakub Kicinski <kuba@kernel.org>

[ Upstream commit 0b4f688d53fdc2a731b9d9cdf0c96255bc024ea6 ]

This reverts commit 90fabae8a2c225c4e4936723c38857887edde5cc.

Patch was applied hastily, revert and let the v2 be reviewed.

Fixes: 90fabae8a2c2 ("sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb")
Link: https://lore.kernel.org/all/87wnao2ha3.fsf@toke.dk/
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_cake.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index 6944c669731c4..857aaebd49f43 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1713,7 +1713,6 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 	}
 	idx--;
 	flow = &b->flows[idx];
-	ret = NET_XMIT_SUCCESS;
 
 	/* ensure shaper state isn't stale */
 	if (!b->tin_backlog) {
@@ -1772,7 +1771,6 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 
 		qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen);
 		consume_skb(skb);
-		ret |= __NET_XMIT_STOLEN;
 	} else {
 		/* not splitting */
 		cobalt_set_enqueue_time(skb, now);
@@ -1906,7 +1904,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 		}
 		b->drop_overlimit += dropped;
 	}
-	return ret;
+	return NET_XMIT_SUCCESS;
 }
 
 static struct sk_buff *cake_dequeue_one(struct Qdisc *sch)
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 029/107] net/smc: Remove redundant refcount increase
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (27 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 028/107] Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb" Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 030/107] soundwire: qcom: fix device status array range Greg Kroah-Hartman
                   ` (86 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Yacan Liu, Tony Lu, Paolo Abeni, Sasha Levin

From: Yacan Liu <liuyacan@corp.netease.com>

[ Upstream commit a8424a9b4522a3ab9f32175ad6d848739079071f ]

For passive connections, the refcount increment has been done in
smc_clcsock_accept()-->smc_sock_alloc().

Fixes: 3b2dec2603d5 ("net/smc: restructure client and server code in af_smc")
Signed-off-by: Yacan Liu <liuyacan@corp.netease.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220830152314.838736-1-liuyacan@corp.netease.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/smc/af_smc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 2ddd7b34b4ce5..26f81e2e1dfba 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1490,7 +1490,6 @@ static void smc_listen_out_connected(struct smc_sock *new_smc)
 {
 	struct sock *newsmcsk = &new_smc->sk;
 
-	sk_refcnt_debug_inc(newsmcsk);
 	if (newsmcsk->sk_state == SMC_INIT)
 		newsmcsk->sk_state = SMC_ACTIVE;
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 030/107] soundwire: qcom: fix device status array range
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (28 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 029/107] net/smc: Remove redundant refcount increase Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 031/107] serial: fsl_lpuart: RS485 RTS polariy is inverse Greg Kroah-Hartman
                   ` (85 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Dan Carpenter, Srinivas Kandagatla,
	Vinod Koul, Sasha Levin

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

[ Upstream commit 4ef3f2aff1267bfa6d5a90c42a30b927b8aa239b ]

This patch updates device status array range from 11 to 12 as we will
be reading status from device number 0 to device number 11 inclusive.

Without this patch we can potentially access status array out of range
during auto-enumeration.

Fixes: aa1262ca6695 ("soundwire: qcom: Check device status before reading devid")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20220708104747.8722-1-srinivas.kandagatla@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/soundwire/qcom.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index 2adc0a75c0515..1ce6f948e9a42 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -148,7 +148,7 @@ struct qcom_swrm_ctrl {
 	u8 wcmd_id;
 	struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS];
 	struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS];
-	enum sdw_slave_status status[SDW_MAX_DEVICES];
+	enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
 	int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val);
 	int (*reg_write)(struct qcom_swrm_ctrl *ctrl, int reg, int val);
 	u32 slave_status;
@@ -391,7 +391,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl)
 
 	ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
 
-	for (dev_num = 0; dev_num < SDW_MAX_DEVICES; dev_num++) {
+	for (dev_num = 0; dev_num <= SDW_MAX_DEVICES; dev_num++) {
 		status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ));
 
 		if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) {
@@ -411,7 +411,7 @@ static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl)
 	ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
 	ctrl->slave_status = val;
 
-	for (i = 0; i < SDW_MAX_DEVICES; i++) {
+	for (i = 0; i <= SDW_MAX_DEVICES; i++) {
 		u32 s;
 
 		s = (val >> (i * 2));
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 031/107] serial: fsl_lpuart: RS485 RTS polariy is inverse
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (29 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 030/107] soundwire: qcom: fix device status array range Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 032/107] staging: rtl8712: fix use after free bugs Greg Kroah-Hartman
                   ` (84 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, stable, Nicolas Diaz, Shenwei Wang

From: Shenwei Wang <shenwei.wang@nxp.com>

commit 846651eca073e2e02e37490a4a52752415d84781 upstream.

The setting of RS485 RTS polarity is inverse in the current driver.

When the property of 'rs485-rts-active-low' is enabled in the dts node,
the RTS signal should be LOW during sending. Otherwise, if there is no
such a property, the RTS should be HIGH during sending.

Fixes: 03895cf41d18 ("tty: serial: fsl_lpuart: Add support for RS-485")
Cc: stable <stable@kernel.org>
Signed-off-by: Nicolas Diaz <nicolas.diaz@nxp.com>
Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
Link: https://lore.kernel.org/r/20220805144529.604856-1-shenwei.wang@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/tty/serial/fsl_lpuart.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1381,9 +1381,9 @@ static int lpuart_config_rs485(struct ua
 		 * Note: UART is assumed to be active high.
 		 */
 		if (rs485->flags & SER_RS485_RTS_ON_SEND)
-			modem &= ~UARTMODEM_TXRTSPOL;
-		else if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
 			modem |= UARTMODEM_TXRTSPOL;
+		else if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
+			modem &= ~UARTMODEM_TXRTSPOL;
 	}
 
 	/* Store the new configuration */



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 032/107] staging: rtl8712: fix use after free bugs
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (30 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 031/107] serial: fsl_lpuart: RS485 RTS polariy is inverse Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 033/107] staging: r8188eu: add firmware dependency Greg Kroah-Hartman
                   ` (83 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, stable, Zheng Wang, Dan Carpenter

From: Dan Carpenter <dan.carpenter@oracle.com>

commit e230a4455ac3e9b112f0367d1b8e255e141afae0 upstream.

_Read/Write_MACREG callbacks are NULL so the read/write_macreg_hdl()
functions don't do anything except free the "pcmd" pointer.  It
results in a use after free.  Delete them.

Fixes: 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel")
Cc: stable <stable@kernel.org>
Reported-by: Zheng Wang <hackerzheng666@gmail.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: https://lore.kernel.org/r/Yw4ASqkYcUhUfoY2@kili
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/rtl8712/rtl8712_cmd.c |   36 ----------------------------------
 1 file changed, 36 deletions(-)

--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -117,34 +117,6 @@ static void r871x_internal_cmd_hdl(struc
 	kfree(pdrvcmd->pbuf);
 }
 
-static u8 read_macreg_hdl(struct _adapter *padapter, u8 *pbuf)
-{
-	void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj	*pcmd);
-	struct cmd_obj *pcmd  = (struct cmd_obj *)pbuf;
-
-	/*  invoke cmd->callback function */
-	pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
-	if (!pcmd_callback)
-		r8712_free_cmd_obj(pcmd);
-	else
-		pcmd_callback(padapter, pcmd);
-	return H2C_SUCCESS;
-}
-
-static u8 write_macreg_hdl(struct _adapter *padapter, u8 *pbuf)
-{
-	void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj	*pcmd);
-	struct cmd_obj *pcmd  = (struct cmd_obj *)pbuf;
-
-	/*  invoke cmd->callback function */
-	pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
-	if (!pcmd_callback)
-		r8712_free_cmd_obj(pcmd);
-	else
-		pcmd_callback(padapter, pcmd);
-	return H2C_SUCCESS;
-}
-
 static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf)
 {
 	struct cmd_obj *pcmd  = (struct cmd_obj *)pbuf;
@@ -213,14 +185,6 @@ static struct cmd_obj *cmd_hdl_filter(st
 	pcmd_r = NULL;
 
 	switch (pcmd->cmdcode) {
-	case GEN_CMD_CODE(_Read_MACREG):
-		read_macreg_hdl(padapter, (u8 *)pcmd);
-		pcmd_r = pcmd;
-		break;
-	case GEN_CMD_CODE(_Write_MACREG):
-		write_macreg_hdl(padapter, (u8 *)pcmd);
-		pcmd_r = pcmd;
-		break;
 	case GEN_CMD_CODE(_Read_BBREG):
 		read_bbreg_hdl(padapter, (u8 *)pcmd);
 		break;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 033/107] staging: r8188eu: add firmware dependency
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (31 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 032/107] staging: rtl8712: fix use after free bugs Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 034/107] powerpc: align syscall table for ppc32 Greg Kroah-Hartman
                   ` (82 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, stable, Grzegorz Szymaszek,
	Phillip Potter, Larry Finger

From: Grzegorz Szymaszek <gszymaszek@short.pl>

commit b2fa9e13bbf101c662c4cd974608242a0db98cfc upstream.

The old rtl8188eu module, removed in commit 55dfa29b43d2 ("staging:
rtl8188eu: remove rtl8188eu driver from staging dir") (Linux kernel
v5.15-rc1), required (through a MODULE_FIRMWARE call()) the
rtlwifi/rtl8188eufw.bin firmware file, which the new r8188eu driver no
longer requires.

I have tested a few RTL8188EUS-based Wi-Fi cards and, while supported by
both drivers, they do not work when using the new one and the firmware
wasn't manually loaded. According to Larry Finger, the module
maintainer, all such cards need the firmware and the driver should
depend on it (see the linked mails).

Add a proper MODULE_FIRMWARE() call, like it was done in the old driver.

Thanks to Greg Kroah-Hartman and Larry Finger for quick responses to my
questions.

Cc: stable <stable@kernel.org>
Link: https://answers.launchpad.net/ubuntu/+source/linux-meta-hwe-5.15/+question/702611
Link: https://lore.kernel.org/lkml/YukkBu3TNODO3or9@nx64de-df6d00/
Signed-off-by: Grzegorz Szymaszek <gszymaszek@short.pl>
Link: https://lore.kernel.org/r/YulcdKfhA8dPQ78s@nx64de-df6d00
Acked-by: Phillip Potter <phil@philpotter.co.uk>
Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/r8188eu/os_dep/os_intfs.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/staging/r8188eu/os_dep/os_intfs.c
+++ b/drivers/staging/r8188eu/os_dep/os_intfs.c
@@ -17,6 +17,7 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
 MODULE_AUTHOR("Realtek Semiconductor Corp.");
 MODULE_VERSION(DRIVERVERSION);
+MODULE_FIRMWARE("rtlwifi/rtl8188eufw.bin");
 
 #define CONFIG_BR_EXT_BRNAME "br0"
 #define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 034/107] powerpc: align syscall table for ppc32
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (32 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 033/107] staging: r8188eu: add firmware dependency Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 035/107] vt: Clear selection before changing the font Greg Kroah-Hartman
                   ` (81 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Christophe Leroy, Masahiro Yamada,
	Michael Ellerman

From: Masahiro Yamada <masahiroy@kernel.org>

commit c7acee3d2f128a38b68fb7af85dbbd91bfd0b4ad upstream.

Christophe Leroy reported that commit 7b4537199a4a ("kbuild: link
symbol CRCs at final link,  removing CONFIG_MODULE_REL_CRCS") broke
mpc85xx_defconfig + CONFIG_RELOCATABLE=y.

    LD      vmlinux
    SYSMAP  System.map
    SORTTAB vmlinux
    CHKREL  vmlinux
  WARNING: 451 bad relocations
  c0b312a9 R_PPC_UADDR32     .head.text-0x3ff9ed54
  c0b312ad R_PPC_UADDR32     .head.text-0x3ffac224
  c0b312b1 R_PPC_UADDR32     .head.text-0x3ffb09f4
  c0b312b5 R_PPC_UADDR32     .head.text-0x3fe184dc
  c0b312b9 R_PPC_UADDR32     .head.text-0x3fe183a8
      ...

The compiler emits a bunch of R_PPC_UADDR32, which is not supported by
arch/powerpc/kernel/reloc_32.S.

The reason is there exists an unaligned symbol.

  $ powerpc-linux-gnu-nm -n vmlinux
    ...
  c0b31258 d spe_aligninfo
  c0b31298 d __func__.0
  c0b312a9 D sys_call_table
  c0b319b8 d __func__.0

Commit 7b4537199a4a is not the root cause. Even before that, I can
reproduce the same issue for mpc85xx_defconfig + CONFIG_RELOCATABLE=y
+ CONFIG_MODVERSIONS=n.

It is just that nobody noticed because when CONFIG_MODVERSIONS is
enabled, a __crc_* symbol inserted before sys_call_table was hiding the
unalignment issue.

Adding alignment to the syscall table for ppc32 fixes the issue.

Cc: stable@vger.kernel.org
Reported-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
[mpe: Trim change log discussion, add Cc stable]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/lkml/38605f6a-a568-f884-f06f-ea4da5b214f0@csgroup.eu/
Link: https://lore.kernel.org/r/20220820165129.1147589-1-masahiroy@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/powerpc/kernel/systbl.S |    1 +
 1 file changed, 1 insertion(+)

--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -18,6 +18,7 @@
 	.p2align	3
 #define __SYSCALL(nr, entry)	.8byte entry
 #else
+	.p2align	2
 #define __SYSCALL(nr, entry)	.long entry
 #endif
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 035/107] vt: Clear selection before changing the font
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (33 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 034/107] powerpc: align syscall table for ppc32 Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 036/107] musb: fix USB_MUSB_TUSB6010 dependency Greg Kroah-Hartman
                   ` (80 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, syzbot+14b0e8f3fd1612e35350, stable,
	Khalid Masum, Helge Deller

From: Helge Deller <deller@gmx.de>

commit 566f9c9f89337792070b5a6062dff448b3e7977f upstream.

When changing the console font with ioctl(KDFONTOP) the new font size
can be bigger than the previous font. A previous selection may thus now
be outside of the new screen size and thus trigger out-of-bounds
accesses to graphics memory if the selection is removed in
vc_do_resize().

Prevent such out-of-memory accesses by dropping the selection before the
various con_font_set() console handlers are called.

Reported-by: syzbot+14b0e8f3fd1612e35350@syzkaller.appspotmail.com
Cc: stable <stable@kernel.org>
Tested-by: Khalid Masum <khalid.masum.92@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Link: https://lore.kernel.org/r/YuV9apZGNmGfjcor@p100
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/tty/vt/vt.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4662,9 +4662,11 @@ static int con_font_set(struct vc_data *
 	console_lock();
 	if (vc->vc_mode != KD_TEXT)
 		rc = -EINVAL;
-	else if (vc->vc_sw->con_font_set)
+	else if (vc->vc_sw->con_font_set) {
+		if (vc_is_sel(vc))
+			clear_selection();
 		rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
-	else
+	} else
 		rc = -ENOSYS;
 	console_unlock();
 	kfree(font.data);
@@ -4691,9 +4693,11 @@ static int con_font_default(struct vc_da
 		console_unlock();
 		return -EINVAL;
 	}
-	if (vc->vc_sw->con_font_default)
+	if (vc->vc_sw->con_font_default) {
+		if (vc_is_sel(vc))
+			clear_selection();
 		rc = vc->vc_sw->con_font_default(vc, &font, s);
-	else
+	} else
 		rc = -ENOSYS;
 	console_unlock();
 	if (!rc) {



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 036/107] musb: fix USB_MUSB_TUSB6010 dependency
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (34 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 035/107] vt: Clear selection before changing the font Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 037/107] tty: serial: lpuart: disable flow control while waiting for the transmit engine to complete Greg Kroah-Hartman
                   ` (79 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, stable, Arnd Bergmann

From: Arnd Bergmann <arnd@arndb.de>

commit a3f2fd22743fc56dd5e3896a3fbddd276df1577f upstream.

Turning on NOP_USB_XCEIV as builtin broke the TUSB6010 driver because
of an older issue with the depencency.

It is not necessary to forbid NOP_USB_XCEIV=y in combination with
USB_MUSB_HDRC=m, but only the reverse, which causes the link failure
from the original Kconfig change.

Use the correct dependency to still allow NOP_USB_XCEIV=n or
NOP_USB_XCEIV=y but forbid NOP_USB_XCEIV=m when USB_MUSB_HDRC=m
to fix the multi_v7_defconfig for tusb.

Fixes: ab37a7a890c1 ("ARM: multi_v7_defconfig: Make NOP_USB_XCEIV driver built-in")
Fixes: c0442479652b ("usb: musb: Fix randconfig build issues for Kconfig options")
Cc: stable <stable@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20220818135737.3143895-10-arnd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/musb/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -86,7 +86,7 @@ config USB_MUSB_TUSB6010
 	tristate "TUSB6010"
 	depends on HAS_IOMEM
 	depends on ARCH_OMAP2PLUS || COMPILE_TEST
-	depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules
+	depends on NOP_USB_XCEIV!=m || USB_MUSB_HDRC=m
 
 config USB_MUSB_OMAP2PLUS
 	tristate "OMAP2430 and onwards"



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 037/107] tty: serial: lpuart: disable flow control while waiting for the transmit engine to complete
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (35 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 036/107] musb: fix USB_MUSB_TUSB6010 dependency Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 038/107] Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag Greg Kroah-Hartman
                   ` (78 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, stable, Sherry Sun

From: Sherry Sun <sherry.sun@nxp.com>

commit d5a2e0834364377a5d5a2fff1890a0b3f0bafd1f upstream.

When the user initializes the uart port, and waits for the transmit
engine to complete in lpuart32_set_termios(), if the UART TX fifo has
dirty data and the UARTMODIR enable the flow control, the TX fifo may
never be empty. So here we should disable the flow control first to make
sure the transmit engin can complete.

Fixes: 380c966c093e ("tty: serial: fsl_lpuart: add 32-bit register interface support")
Cc: stable <stable@kernel.org>
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20220821101527.10066-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/tty/serial/fsl_lpuart.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -2203,6 +2203,7 @@ lpuart32_set_termios(struct uart_port *p
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 	/* wait transmit engin complete */
+	lpuart32_write(&sport->port, 0, UARTMODIR);
 	lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
 
 	/* disable transmit and receive */



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 038/107] Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (36 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 037/107] tty: serial: lpuart: disable flow control while waiting for the transmit engine to complete Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 039/107] iio: ad7292: Prevent regulator double disable Greg Kroah-Hartman
                   ` (77 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, syzbot, Fabio M. De Francesco,
	Hillf Danton, Tetsuo Handa, Dmitry Torokhov

From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>

commit 98e01215708b6d416345465c09dce2bd4868c67a upstream.

syzbot is reporting hung task at __input_unregister_device() [1], for
iforce_close() waiting at wait_event_interruptible() with dev->mutex held
is blocking input_disconnect_device() from __input_unregister_device().

It seems that the cause is simply that commit c2b27ef672992a20 ("Input:
iforce - wait for command completion when closing the device") forgot to
call wake_up() after clear_bit().

Fix this problem by introducing a helper that calls clear_bit() followed
by wake_up_all().

Reported-by: syzbot <syzbot+deb6abc36aad4008f407@syzkaller.appspotmail.com>
Fixes: c2b27ef672992a20 ("Input: iforce - wait for command completion when closing the device")
Tested-by: syzbot <syzbot+deb6abc36aad4008f407@syzkaller.appspotmail.com>
Suggested-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
Co-developed-by: Hillf Danton <hdanton@sina.com>
Signed-off-by: Hillf Danton <hdanton@sina.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Link: https://lore.kernel.org/r/887021c3-4f13-40ce-c8b9-aa6e09faa3a7@I-love.SAKURA.ne.jp
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/joystick/iforce/iforce-serio.c |    6 +++---
 drivers/input/joystick/iforce/iforce-usb.c   |    8 ++++----
 drivers/input/joystick/iforce/iforce.h       |    6 ++++++
 3 files changed, 13 insertions(+), 7 deletions(-)

--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -39,7 +39,7 @@ static void iforce_serio_xmit(struct ifo
 
 again:
 	if (iforce->xmit.head == iforce->xmit.tail) {
-		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
+		iforce_clear_xmit_and_wake(iforce);
 		spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 		return;
 	}
@@ -64,7 +64,7 @@ again:
 	if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
 		goto again;
 
-	clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
+	iforce_clear_xmit_and_wake(iforce);
 
 	spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 }
@@ -169,7 +169,7 @@ static irqreturn_t iforce_serio_irq(stru
 			iforce_serio->cmd_response_len = iforce_serio->len;
 
 			/* Signal that command is done */
-			wake_up(&iforce->wait);
+			wake_up_all(&iforce->wait);
 		} else if (likely(iforce->type)) {
 			iforce_process_packet(iforce, iforce_serio->id,
 					      iforce_serio->data_in,
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -30,7 +30,7 @@ static void __iforce_usb_xmit(struct ifo
 	spin_lock_irqsave(&iforce->xmit_lock, flags);
 
 	if (iforce->xmit.head == iforce->xmit.tail) {
-		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
+		iforce_clear_xmit_and_wake(iforce);
 		spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 		return;
 	}
@@ -58,9 +58,9 @@ static void __iforce_usb_xmit(struct ifo
 	XMIT_INC(iforce->xmit.tail, n);
 
 	if ( (n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC)) ) {
-		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
 		dev_warn(&iforce_usb->intf->dev,
 			 "usb_submit_urb failed %d\n", n);
+		iforce_clear_xmit_and_wake(iforce);
 	}
 
 	/* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
@@ -175,15 +175,15 @@ static void iforce_usb_out(struct urb *u
 	struct iforce *iforce = &iforce_usb->iforce;
 
 	if (urb->status) {
-		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
 		dev_dbg(&iforce_usb->intf->dev, "urb->status %d, exiting\n",
 			urb->status);
+		iforce_clear_xmit_and_wake(iforce);
 		return;
 	}
 
 	__iforce_usb_xmit(iforce);
 
-	wake_up(&iforce->wait);
+	wake_up_all(&iforce->wait);
 }
 
 static int iforce_usb_probe(struct usb_interface *intf,
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -119,6 +119,12 @@ static inline int iforce_get_id_packet(s
 					 response_data, response_len);
 }
 
+static inline void iforce_clear_xmit_and_wake(struct iforce *iforce)
+{
+	clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
+	wake_up_all(&iforce->wait);
+}
+
 /* Public functions */
 /* iforce-main.c */
 int iforce_init_device(struct device *parent, u16 bustype,



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 039/107] iio: ad7292: Prevent regulator double disable
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (37 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 038/107] Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 040/107] iio: adc: mcp3911: use correct formula for AD conversion Greg Kroah-Hartman
                   ` (76 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Matti Vaittinen, Marcelo Schmitt,
	Stable, Jonathan Cameron

From: Matti Vaittinen <mazziesaccount@gmail.com>

commit 22b4277641c6823ec03d5b1cd82628e5e53e75b7 upstream.

The ad7292 tries to add an devm_action for disabling a regulator at
device detach using devm_add_action_or_reset(). The
devm_add_action_or_reset() does call the release function should adding
action fail. The driver inspects the value returned by
devm_add_action_or_reset() and manually calls regulator_disable() if
adding the action has failed. This leads to double disable and messes
the enable count for regulator.

Do not manually call disable if devm_add_action_or_reset() fails.

Fixes: 506d2e317a0a ("iio: adc: Add driver support for AD7292")
Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Tested-by: Marcelo Schmitt <marcelo.schmitt1@gmail.com>
Link: https://lore.kernel.org/r/Yv9O+9sxU7gAv3vM@fedora
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/iio/adc/ad7292.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- a/drivers/iio/adc/ad7292.c
+++ b/drivers/iio/adc/ad7292.c
@@ -287,10 +287,8 @@ static int ad7292_probe(struct spi_devic
 
 		ret = devm_add_action_or_reset(&spi->dev,
 					       ad7292_regulator_disable, st);
-		if (ret) {
-			regulator_disable(st->reg);
+		if (ret)
 			return ret;
-		}
 
 		ret = regulator_get_voltage(st->reg);
 		if (ret < 0)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 040/107] iio: adc: mcp3911: use correct formula for AD conversion
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (38 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 039/107] iio: ad7292: Prevent regulator double disable Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 041/107] misc: fastrpc: fix memory corruption on probe Greg Kroah-Hartman
                   ` (75 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Marcus Folkesson, Andy Shevchenko,
	Stable, Jonathan Cameron

From: Marcus Folkesson <marcus.folkesson@gmail.com>

commit 9e2238e3ae40d371a1130226e0e740aa1601efa6 upstream.

The ADC conversion is actually not rail-to-rail but with a factor 1.5.
Make use of this factor when calculating actual voltage.

Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20220722130726.7627-4-marcus.folkesson@gmail.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/iio/adc/mcp3911.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -38,8 +38,8 @@
 #define MCP3911_CHANNEL(x)		(MCP3911_REG_CHANNEL0 + x * 3)
 #define MCP3911_OFFCAL(x)		(MCP3911_REG_OFFCAL_CH0 + x * 6)
 
-/* Internal voltage reference in uV */
-#define MCP3911_INT_VREF_UV		1200000
+/* Internal voltage reference in mV */
+#define MCP3911_INT_VREF_MV		1200
 
 #define MCP3911_REG_READ(reg, id)	((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff)
 #define MCP3911_REG_WRITE(reg, id)	((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
@@ -137,11 +137,18 @@ static int mcp3911_read_raw(struct iio_d
 
 			*val = ret / 1000;
 		} else {
-			*val = MCP3911_INT_VREF_UV;
+			*val = MCP3911_INT_VREF_MV;
 		}
 
-		*val2 = 24;
-		ret = IIO_VAL_FRACTIONAL_LOG2;
+		/*
+		 * For 24bit Conversion
+		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
+		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
+		 */
+
+		/* val2 = (2^23 * 1.5) */
+		*val2 = 12582912;
+		ret = IIO_VAL_FRACTIONAL;
 		break;
 	}
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 041/107] misc: fastrpc: fix memory corruption on probe
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (39 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 040/107] iio: adc: mcp3911: use correct formula for AD conversion Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 042/107] misc: fastrpc: fix memory corruption on open Greg Kroah-Hartman
                   ` (74 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Johan Hovold

From: Johan Hovold <johan+linaro@kernel.org>

commit 9baa1415d9abdd1e08362ea2dcfadfacee8690b5 upstream.

Add the missing sanity check on the probed-session count to avoid
corrupting memory beyond the fixed-size slab-allocated session array
when there are more than FASTRPC_MAX_SESSIONS sessions defined in the
devicetree.

Fixes: f6f9279f2bf0 ("misc: fastrpc: Add Qualcomm fastrpc basic driver model")
Cc: stable@vger.kernel.org      # 5.1
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20220829080531.29681-2-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/misc/fastrpc.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1550,6 +1550,11 @@ static int fastrpc_cb_probe(struct platf
 	of_property_read_u32(dev->of_node, "qcom,nsessions", &sessions);
 
 	spin_lock_irqsave(&cctx->lock, flags);
+	if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) {
+		dev_err(&pdev->dev, "too many sessions\n");
+		spin_unlock_irqrestore(&cctx->lock, flags);
+		return -ENOSPC;
+	}
 	sess = &cctx->session[cctx->sesscount];
 	sess->used = false;
 	sess->valid = true;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 042/107] misc: fastrpc: fix memory corruption on open
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (40 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 041/107] misc: fastrpc: fix memory corruption on probe Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 043/107] USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id Greg Kroah-Hartman
                   ` (73 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Johan Hovold

From: Johan Hovold <johan+linaro@kernel.org>

commit d245f43aab2b61195d8ebb64cef7b5a08c590ab4 upstream.

The probe session-duplication overflow check incremented the session
count also when there were no more available sessions so that memory
beyond the fixed-size slab-allocated session array could be corrupted in
fastrpc_session_alloc() on open().

Fixes: f6f9279f2bf0 ("misc: fastrpc: Add Qualcomm fastrpc basic driver model")
Cc: stable@vger.kernel.org      # 5.1
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20220829080531.29681-3-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/misc/fastrpc.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1555,7 +1555,7 @@ static int fastrpc_cb_probe(struct platf
 		spin_unlock_irqrestore(&cctx->lock, flags);
 		return -ENOSPC;
 	}
-	sess = &cctx->session[cctx->sesscount];
+	sess = &cctx->session[cctx->sesscount++];
 	sess->used = false;
 	sess->valid = true;
 	sess->dev = dev;
@@ -1568,13 +1568,12 @@ static int fastrpc_cb_probe(struct platf
 		struct fastrpc_session_ctx *dup_sess;
 
 		for (i = 1; i < sessions; i++) {
-			if (cctx->sesscount++ >= FASTRPC_MAX_SESSIONS)
+			if (cctx->sesscount >= FASTRPC_MAX_SESSIONS)
 				break;
-			dup_sess = &cctx->session[cctx->sesscount];
+			dup_sess = &cctx->session[cctx->sesscount++];
 			memcpy(dup_sess, sess, sizeof(*dup_sess));
 		}
 	}
-	cctx->sesscount++;
 	spin_unlock_irqrestore(&cctx->lock, flags);
 	rc = dma_set_mask(dev, DMA_BIT_MASK(32));
 	if (rc) {



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 043/107] USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (41 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 042/107] misc: fastrpc: fix memory corruption on open Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 044/107] mmc: core: Fix UHS-I SD 1.8V workaround branch Greg Kroah-Hartman
                   ` (72 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Niek Nooijens, Johan Hovold

From: Niek Nooijens <niek.nooijens@omron.com>

commit 001047ea241a9646010b2744451dfbc7289542f3 upstream.

works perfectly with:
modprobe ftdi_sio
echo "0590 00b2" | tee
/sys/module/ftdi_sio/drivers/usb-serial\:ftdi_sio/new_id > /dev/null

but doing this every reboot is a pain in the ass.

Signed-off-by: Niek Nooijens <niek.nooijens@omron.com>
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/ftdi_sio.c     |    2 ++
 drivers/usb/serial/ftdi_sio_ids.h |    6 ++++++
 2 files changed, 8 insertions(+)

--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1045,6 +1045,8 @@ static const struct usb_device_id id_tab
 	/* IDS GmbH devices */
 	{ USB_DEVICE(IDS_VID, IDS_SI31A_PID) },
 	{ USB_DEVICE(IDS_VID, IDS_CM31A_PID) },
+	/* Omron devices */
+	{ USB_DEVICE(OMRON_VID, OMRON_CS1W_CIF31_PID) },
 	/* U-Blox devices */
 	{ USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) },
 	{ USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) },
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -662,6 +662,12 @@
 #define INFINEON_TRIBOARD_TC2X7_PID	0x0043 /* DAS JTAG TriBoard TC2X7 V1.0 */
 
 /*
+ * Omron corporation (https://www.omron.com)
+ */
+ #define OMRON_VID			0x0590
+ #define OMRON_CS1W_CIF31_PID		0x00b2
+
+/*
  * Acton Research Corp.
  */
 #define ACTON_VID		0x0647	/* Vendor ID */



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 044/107] mmc: core: Fix UHS-I SD 1.8V workaround branch
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (42 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 043/107] USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 045/107] mmc: core: Fix inconsistent sd3_bus_mode at UHS-I SD voltage switch failure Greg Kroah-Hartman
                   ` (71 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Adrian Hunter, Seunghui Lee, Ulf Hansson

From: Adrian Hunter <adrian.hunter@intel.com>

commit 15c56208c79c340686869c31595c209d1431c5e8 upstream.

When introduced, upon success, the 1.8V fixup workaround in
mmc_sd_init_card() would branch to practically the end of the function, to
a label named "done". Unfortunately, perhaps due to the label name, over
time new code has been added that really should have come after "done" not
before it. Let's fix the problem by moving the label to the correct place
and rename it "cont".

Fixes: 045d705dc1fb ("mmc: core: Enable the MMC host software queue for the SD card")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Seunghui Lee <sh043.lee@samsung.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220815073321.63382-2-adrian.hunter@intel.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/core/sd.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1491,7 +1491,7 @@ retry:
 					mmc_remove_card(card);
 				goto retry;
 			}
-			goto done;
+			goto cont;
 		}
 	}
 
@@ -1527,7 +1527,7 @@ retry:
 			mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
 		}
 	}
-
+cont:
 	if (!oldcard) {
 		/* Read/parse the extension registers. */
 		err = sd_read_ext_regs(card);
@@ -1559,7 +1559,7 @@ retry:
 		err = -EINVAL;
 		goto free_card;
 	}
-done:
+
 	host->card = card;
 	return 0;
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 045/107] mmc: core: Fix inconsistent sd3_bus_mode at UHS-I SD voltage switch failure
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (43 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 044/107] mmc: core: Fix UHS-I SD 1.8V workaround branch Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 046/107] binder: fix UAF of ref->proc caused by race condition Greg Kroah-Hartman
                   ` (70 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Seunghui Lee, Adrian Hunter, Ulf Hansson

From: Adrian Hunter <adrian.hunter@intel.com>

commit 63f1560930e4e1c4f6279b8ae715c9841fe1a6d3 upstream.

If re-initialization results is a different signal voltage, because the
voltage switch failed previously, but not this time (or vice versa), then
sd3_bus_mode will be inconsistent with the card because the SD_SWITCH
command is done only upon first initialization.

Fix by always reading SD_SWITCH information during re-initialization, which
also means it does not need to be re-read later for the 1.8V fixup
workaround.

Note, brief testing showed SD_SWITCH took about 1.8ms to 2ms which added
about 1% to 1.5% to the re-initialization time, so it's not particularly
significant.

Reported-by: Seunghui Lee <sh043.lee@samsung.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Seunghui Lee <sh043.lee@samsung.com>
Tested-by: Seunghui Lee <sh043.lee@samsung.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220815073321.63382-3-adrian.hunter@intel.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/core/sd.c |   42 ++++++++++++++++--------------------------
 1 file changed, 16 insertions(+), 26 deletions(-)

--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -942,16 +942,17 @@ int mmc_sd_setup_card(struct mmc_host *h
 
 		/* Erase init depends on CSD and SSR */
 		mmc_init_erase(card);
-
-		/*
-		 * Fetch switch information from card.
-		 */
-		err = mmc_read_switch(card);
-		if (err)
-			return err;
 	}
 
 	/*
+	 * Fetch switch information from card. Note, sd3_bus_mode can change if
+	 * voltage switch outcome changes, so do this always.
+	 */
+	err = mmc_read_switch(card);
+	if (err)
+		return err;
+
+	/*
 	 * For SPI, enable CRC as appropriate.
 	 * This CRC enable is located AFTER the reading of the
 	 * card registers because some SDHC cards are not able
@@ -1473,26 +1474,15 @@ retry:
 	if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_uhs(host) &&
 	    mmc_sd_card_using_v18(card) &&
 	    host->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_180) {
-		/*
-		 * Re-read switch information in case it has changed since
-		 * oldcard was initialized.
-		 */
-		if (oldcard) {
-			err = mmc_read_switch(card);
-			if (err)
-				goto free_card;
-		}
-		if (mmc_sd_card_using_v18(card)) {
-			if (mmc_host_set_uhs_voltage(host) ||
-			    mmc_sd_init_uhs_card(card)) {
-				v18_fixup_failed = true;
-				mmc_power_cycle(host, ocr);
-				if (!oldcard)
-					mmc_remove_card(card);
-				goto retry;
-			}
-			goto cont;
+		if (mmc_host_set_uhs_voltage(host) ||
+		    mmc_sd_init_uhs_card(card)) {
+			v18_fixup_failed = true;
+			mmc_power_cycle(host, ocr);
+			if (!oldcard)
+				mmc_remove_card(card);
+			goto retry;
 		}
+		goto cont;
 	}
 
 	/* Initialization sequence for UHS-I cards */



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 046/107] binder: fix UAF of ref->proc caused by race condition
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (44 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 045/107] mmc: core: Fix inconsistent sd3_bus_mode at UHS-I SD voltage switch failure Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 047/107] binder: fix alloc->vma_vm_mm null-ptr dereference Greg Kroah-Hartman
                   ` (69 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Christian Brauner (Microsoft),
	Carlos Llamas, stable

From: Carlos Llamas <cmllamas@google.com>

commit a0e44c64b6061dda7e00b7c458e4523e2331b739 upstream.

A transaction of type BINDER_TYPE_WEAK_HANDLE can fail to increment the
reference for a node. In this case, the target proc normally releases
the failed reference upon close as expected. However, if the target is
dying in parallel the call will race with binder_deferred_release(), so
the target could have released all of its references by now leaving the
cleanup of the new failed reference unhandled.

The transaction then ends and the target proc gets released making the
ref->proc now a dangling pointer. Later on, ref->node is closed and we
attempt to take spin_lock(&ref->proc->inner_lock), which leads to the
use-after-free bug reported below. Let's fix this by cleaning up the
failed reference on the spot instead of relying on the target to do so.

  ==================================================================
  BUG: KASAN: use-after-free in _raw_spin_lock+0xa8/0x150
  Write of size 4 at addr ffff5ca207094238 by task kworker/1:0/590

  CPU: 1 PID: 590 Comm: kworker/1:0 Not tainted 5.19.0-rc8 #10
  Hardware name: linux,dummy-virt (DT)
  Workqueue: events binder_deferred_func
  Call trace:
   dump_backtrace.part.0+0x1d0/0x1e0
   show_stack+0x18/0x70
   dump_stack_lvl+0x68/0x84
   print_report+0x2e4/0x61c
   kasan_report+0xa4/0x110
   kasan_check_range+0xfc/0x1a4
   __kasan_check_write+0x3c/0x50
   _raw_spin_lock+0xa8/0x150
   binder_deferred_func+0x5e0/0x9b0
   process_one_work+0x38c/0x5f0
   worker_thread+0x9c/0x694
   kthread+0x188/0x190
   ret_from_fork+0x10/0x20

Acked-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Cc: stable <stable@kernel.org> # 4.14+
Link: https://lore.kernel.org/r/20220801182511.3371447-1-cmllamas@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/android/binder.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -1358,6 +1358,18 @@ static int binder_inc_ref_for_node(struc
 	}
 	ret = binder_inc_ref_olocked(ref, strong, target_list);
 	*rdata = ref->data;
+	if (ret && ref == new_ref) {
+		/*
+		 * Cleanup the failed reference here as the target
+		 * could now be dead and have already released its
+		 * references by now. Calling on the new reference
+		 * with strong=0 and a tmp_refs will not decrement
+		 * the node. The new_ref gets kfree'd below.
+		 */
+		binder_cleanup_ref_olocked(new_ref);
+		ref = NULL;
+	}
+
 	binder_proc_unlock(proc);
 	if (new_ref && ref != new_ref)
 		/*



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 047/107] binder: fix alloc->vma_vm_mm null-ptr dereference
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (45 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 046/107] binder: fix UAF of ref->proc caused by race condition Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 048/107] cifs: fix small mempool leak in SMB2_negotiate() Greg Kroah-Hartman
                   ` (68 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Liam R. Howlett,
	syzbot+f7dc54e5be28950ac459, syzbot+a75ebe0452711c9e56d9,
	Todd Kjos, Carlos Llamas

From: Carlos Llamas <cmllamas@google.com>

commit 1da52815d5f1b654c89044db0cdc6adce43da1f1 upstream.

Syzbot reported a couple issues introduced by commit 44e602b4e52f
("binder_alloc: add missing mmap_lock calls when using the VMA"), in
which we attempt to acquire the mmap_lock when alloc->vma_vm_mm has not
been initialized yet.

This can happen if a binder_proc receives a transaction without having
previously called mmap() to setup the binder_proc->alloc space in [1].
Also, a similar issue occurs via binder_alloc_print_pages() when we try
to dump the debugfs binder stats file in [2].

Sample of syzbot's crash report:
  ==================================================================
  KASAN: null-ptr-deref in range [0x0000000000000128-0x000000000000012f]
  CPU: 0 PID: 3755 Comm: syz-executor229 Not tainted 6.0.0-rc1-next-20220819-syzkaller #0
  syz-executor229[3755] cmdline: ./syz-executor2294415195
  Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022
  RIP: 0010:__lock_acquire+0xd83/0x56d0 kernel/locking/lockdep.c:4923
  [...]
  Call Trace:
   <TASK>
   lock_acquire kernel/locking/lockdep.c:5666 [inline]
   lock_acquire+0x1ab/0x570 kernel/locking/lockdep.c:5631
   down_read+0x98/0x450 kernel/locking/rwsem.c:1499
   mmap_read_lock include/linux/mmap_lock.h:117 [inline]
   binder_alloc_new_buf_locked drivers/android/binder_alloc.c:405 [inline]
   binder_alloc_new_buf+0xa5/0x19e0 drivers/android/binder_alloc.c:593
   binder_transaction+0x242e/0x9a80 drivers/android/binder.c:3199
   binder_thread_write+0x664/0x3220 drivers/android/binder.c:3986
   binder_ioctl_write_read drivers/android/binder.c:5036 [inline]
   binder_ioctl+0x3470/0x6d00 drivers/android/binder.c:5323
   vfs_ioctl fs/ioctl.c:51 [inline]
   __do_sys_ioctl fs/ioctl.c:870 [inline]
   __se_sys_ioctl fs/ioctl.c:856 [inline]
   __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:856
   do_syscall_x64 arch/x86/entry/common.c:50 [inline]
   do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
   entry_SYSCALL_64_after_hwframe+0x63/0xcd
   [...]
  ==================================================================

Fix these issues by setting up alloc->vma_vm_mm pointer during open()
and caching directly from current->mm. This guarantees we have a valid
reference to take the mmap_lock during scenarios described above.

[1] https://syzkaller.appspot.com/bug?extid=f7dc54e5be28950ac459
[2] https://syzkaller.appspot.com/bug?extid=a75ebe0452711c9e56d9

Fixes: 44e602b4e52f ("binder_alloc: add missing mmap_lock calls when using the VMA")
Cc: <stable@vger.kernel.org> # v5.15+
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Reported-by: syzbot+f7dc54e5be28950ac459@syzkaller.appspotmail.com
Reported-by: syzbot+a75ebe0452711c9e56d9@syzkaller.appspotmail.com
Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Acked-by: Todd Kjos <tkjos@google.com>
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Link: https://lore.kernel.org/r/20220829201254.1814484-2-cmllamas@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/android/binder_alloc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -322,7 +322,6 @@ static inline void binder_alloc_set_vma(
 	 */
 	if (vma) {
 		vm_start = vma->vm_start;
-		alloc->vma_vm_mm = vma->vm_mm;
 		mmap_assert_write_locked(alloc->vma_vm_mm);
 	} else {
 		mmap_assert_locked(alloc->vma_vm_mm);
@@ -795,7 +794,6 @@ int binder_alloc_mmap_handler(struct bin
 	binder_insert_free_buffer(alloc, buffer);
 	alloc->free_async_space = alloc->buffer_size / 2;
 	binder_alloc_set_vma(alloc, vma);
-	mmgrab(alloc->vma_vm_mm);
 
 	return 0;
 
@@ -1095,6 +1093,8 @@ static struct shrinker binder_shrinker =
 void binder_alloc_init(struct binder_alloc *alloc)
 {
 	alloc->pid = current->group_leader->pid;
+	alloc->vma_vm_mm = current->mm;
+	mmgrab(alloc->vma_vm_mm);
 	mutex_init(&alloc->mutex);
 	INIT_LIST_HEAD(&alloc->buffers);
 }



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 048/107] cifs: fix small mempool leak in SMB2_negotiate()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (46 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 047/107] binder: fix alloc->vma_vm_mm null-ptr dereference Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 049/107] KVM: VMX: Heed the msr argument in msr_write_intercepted() Greg Kroah-Hartman
                   ` (67 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Enzo Matsumiya, Ronnie Sahlberg,
	Steve French

From: Enzo Matsumiya <ematsumiya@suse.de>

commit 27893dfc1285f80f80f46b3b8c95f5d15d2e66d0 upstream.

In some cases of failure (dialect mismatches) in SMB2_negotiate(), after
the request is sent, the checks would return -EIO when they should be
rather setting rc = -EIO and jumping to neg_exit to free the response
buffer from mempool.

Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
Cc: stable@vger.kernel.org
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/cifs/smb2pdu.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -933,16 +933,17 @@ SMB2_negotiate(const unsigned int xid, s
 	} else if (rc != 0)
 		goto neg_exit;
 
+	rc = -EIO;
 	if (strcmp(server->vals->version_string,
 		   SMB3ANY_VERSION_STRING) == 0) {
 		if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
 			cifs_server_dbg(VFS,
 				"SMB2 dialect returned but not requested\n");
-			return -EIO;
+			goto neg_exit;
 		} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
 			cifs_server_dbg(VFS,
 				"SMB2.1 dialect returned but not requested\n");
-			return -EIO;
+			goto neg_exit;
 		} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
 			/* ops set to 3.0 by default for default so update */
 			server->ops = &smb311_operations;
@@ -953,7 +954,7 @@ SMB2_negotiate(const unsigned int xid, s
 		if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
 			cifs_server_dbg(VFS,
 				"SMB2 dialect returned but not requested\n");
-			return -EIO;
+			goto neg_exit;
 		} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
 			/* ops set to 3.0 by default for default so update */
 			server->ops = &smb21_operations;
@@ -967,7 +968,7 @@ SMB2_negotiate(const unsigned int xid, s
 		/* if requested single dialect ensure returned dialect matched */
 		cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n",
 				le16_to_cpu(rsp->DialectRevision));
-		return -EIO;
+		goto neg_exit;
 	}
 
 	cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
@@ -985,9 +986,10 @@ SMB2_negotiate(const unsigned int xid, s
 	else {
 		cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n",
 				le16_to_cpu(rsp->DialectRevision));
-		rc = -EIO;
 		goto neg_exit;
 	}
+
+	rc = 0;
 	server->dialect = le16_to_cpu(rsp->DialectRevision);
 
 	/*



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 049/107] KVM: VMX: Heed the msr argument in msr_write_intercepted()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (47 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 048/107] cifs: fix small mempool leak in SMB2_negotiate() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 050/107] drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" Greg Kroah-Hartman
                   ` (66 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Sean Christopherson, Jim Mattson,
	Paolo Bonzini, Sasha Levin

From: Jim Mattson <jmattson@google.com>

[ Upstream commit 020dac4187968535f089f83f376a72beb3451311 ]

Regardless of the 'msr' argument passed to the VMX version of
msr_write_intercepted(), the function always checks to see if a
specific MSR (IA32_SPEC_CTRL) is intercepted for write.  This behavior
seems unintentional and unexpected.

Modify the function so that it checks to see if the provided 'msr'
index is intercepted for write.

Fixes: 67f4b9969c30 ("KVM: nVMX: Handle dynamic MSR intercept toggling")
Cc: Sean Christopherson <seanjc@google.com>
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20220810213050.2655000-1-jmattson@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/kvm/vmx/vmx.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index cfb3a5c809f2e..e5584e974c774 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -831,8 +831,7 @@ static bool msr_write_intercepted(struct vcpu_vmx *vmx, u32 msr)
 	if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS))
 		return true;
 
-	return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap,
-					 MSR_IA32_SPEC_CTRL);
+	return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap, msr);
 }
 
 unsigned int __vmx_vcpu_run_flags(struct vcpu_vmx *vmx)
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 050/107] drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported"
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (48 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 049/107] KVM: VMX: Heed the msr argument in msr_write_intercepted() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 051/107] clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops Greg Kroah-Hartman
                   ` (65 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Colin Ian King, Zhi Wang,
	Zhenyu Wang, Sasha Levin

From: Colin Ian King <colin.i.king@gmail.com>

[ Upstream commit 233f56745be446b289edac2ba8184c09365c005e ]

There is a spelling mistake in a gvt_vgpu_err error message. Fix it.

Fixes: 695fbc08d80f ("drm/i915/gvt: replace the gvt_err with gvt_vgpu_err")
Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20220315202449.2952845-1-colin.i.king@gmail.com
Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/i915/gvt/handlers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index cde0a477fb497..7ed7dba42c834 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -909,7 +909,7 @@ static int update_fdi_rx_iir_status(struct intel_vgpu *vgpu,
 	else if (FDI_RX_IMR_TO_PIPE(offset) != INVALID_INDEX)
 		index = FDI_RX_IMR_TO_PIPE(offset);
 	else {
-		gvt_vgpu_err("Unsupport registers %x\n", offset);
+		gvt_vgpu_err("Unsupported registers %x\n", offset);
 		return -EINVAL;
 	}
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 051/107] clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (49 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 050/107] drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 052/107] Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops" Greg Kroah-Hartman
                   ` (64 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Chen-Yu Tsai,
	Nícolas F .  R .  A .  Prado, Stephen Boyd, Sasha Levin

From: Chen-Yu Tsai <wenst@chromium.org>

[ Upstream commit 35b0fac808b95eea1212f8860baf6ad25b88b087 ]

In the previous commits that added CLK_OPS_PARENT_ENABLE, support for
this flag was only added to rate change operations (rate setting and
reparent) and disabling unused subtree. It was not added to the
clock gate related operations. Any hardware driver that needs it for
these operations will either see bogus results, or worse, hang.

This has been seen on MT8192 and MT8195, where the imp_ii2_* clk
drivers set this, but dumping debugfs clk_summary would cause it
to hang.

Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)")
Fixes: a4b3518d146f ("clk: core: support clocks which requires parents enable (part 1)")
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Link: https://lore.kernel.org/r/20220822081424.1310926-2-wenst@chromium.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d6dc58bd07b33..973649db3decb 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -203,6 +203,9 @@ static bool clk_core_rate_is_protected(struct clk_core *core)
 	return core->protect_count;
 }
 
+static int clk_core_prepare_enable(struct clk_core *core);
+static void clk_core_disable_unprepare(struct clk_core *core);
+
 static bool clk_core_is_prepared(struct clk_core *core)
 {
 	bool ret = false;
@@ -215,7 +218,11 @@ static bool clk_core_is_prepared(struct clk_core *core)
 		return core->prepare_count;
 
 	if (!clk_pm_runtime_get(core)) {
+		if (core->flags & CLK_OPS_PARENT_ENABLE)
+			clk_core_prepare_enable(core->parent);
 		ret = core->ops->is_prepared(core->hw);
+		if (core->flags & CLK_OPS_PARENT_ENABLE)
+			clk_core_disable_unprepare(core->parent);
 		clk_pm_runtime_put(core);
 	}
 
@@ -251,7 +258,13 @@ static bool clk_core_is_enabled(struct clk_core *core)
 		}
 	}
 
+	if (core->flags & CLK_OPS_PARENT_ENABLE)
+		clk_core_prepare_enable(core->parent);
+
 	ret = core->ops->is_enabled(core->hw);
+
+	if (core->flags & CLK_OPS_PARENT_ENABLE)
+		clk_core_disable_unprepare(core->parent);
 done:
 	if (core->rpm_enabled)
 		pm_runtime_put(core->dev);
@@ -818,6 +831,9 @@ int clk_rate_exclusive_get(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_rate_exclusive_get);
 
+static int clk_core_enable_lock(struct clk_core *core);
+static void clk_core_disable_lock(struct clk_core *core);
+
 static void clk_core_unprepare(struct clk_core *core)
 {
 	lockdep_assert_held(&prepare_lock);
@@ -841,6 +857,9 @@ static void clk_core_unprepare(struct clk_core *core)
 
 	WARN(core->enable_count > 0, "Unpreparing enabled %s\n", core->name);
 
+	if (core->flags & CLK_OPS_PARENT_ENABLE)
+		clk_core_enable_lock(core->parent);
+
 	trace_clk_unprepare(core);
 
 	if (core->ops->unprepare)
@@ -849,6 +868,9 @@ static void clk_core_unprepare(struct clk_core *core)
 	clk_pm_runtime_put(core);
 
 	trace_clk_unprepare_complete(core);
+
+	if (core->flags & CLK_OPS_PARENT_ENABLE)
+		clk_core_disable_lock(core->parent);
 	clk_core_unprepare(core->parent);
 }
 
@@ -897,6 +919,9 @@ static int clk_core_prepare(struct clk_core *core)
 		if (ret)
 			goto runtime_put;
 
+		if (core->flags & CLK_OPS_PARENT_ENABLE)
+			clk_core_enable_lock(core->parent);
+
 		trace_clk_prepare(core);
 
 		if (core->ops->prepare)
@@ -904,6 +929,9 @@ static int clk_core_prepare(struct clk_core *core)
 
 		trace_clk_prepare_complete(core);
 
+		if (core->flags & CLK_OPS_PARENT_ENABLE)
+			clk_core_disable_lock(core->parent);
+
 		if (ret)
 			goto unprepare;
 	}
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 052/107] Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops"
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (50 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 051/107] clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 053/107] clk: core: Fix runtime PM sequence in clk_core_unprepare() Greg Kroah-Hartman
                   ` (63 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Alexander Stein, Chen-Yu Tsai,
	Stephen Boyd, Sasha Levin

From: Stephen Boyd <sboyd@kernel.org>

[ Upstream commit abb5f3f4b1f5f0ad50eb067a00051d3587dec9fb ]

This reverts commit 35b0fac808b95eea1212f8860baf6ad25b88b087. Alexander
reports that it causes boot failures on i.MX8M Plus based boards
(specifically imx8mp-tqma8mpql-mba8mpxl.dts).

Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Cc: Chen-Yu Tsai <wenst@chromium.org>
Fixes: 35b0fac808b9 ("clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops")
Link: https://lore.kernel.org/r/12115951.O9o76ZdvQC@steina-w
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20220831175326.2523912-1-sboyd@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/clk.c | 28 ----------------------------
 1 file changed, 28 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 973649db3decb..d6dc58bd07b33 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -203,9 +203,6 @@ static bool clk_core_rate_is_protected(struct clk_core *core)
 	return core->protect_count;
 }
 
-static int clk_core_prepare_enable(struct clk_core *core);
-static void clk_core_disable_unprepare(struct clk_core *core);
-
 static bool clk_core_is_prepared(struct clk_core *core)
 {
 	bool ret = false;
@@ -218,11 +215,7 @@ static bool clk_core_is_prepared(struct clk_core *core)
 		return core->prepare_count;
 
 	if (!clk_pm_runtime_get(core)) {
-		if (core->flags & CLK_OPS_PARENT_ENABLE)
-			clk_core_prepare_enable(core->parent);
 		ret = core->ops->is_prepared(core->hw);
-		if (core->flags & CLK_OPS_PARENT_ENABLE)
-			clk_core_disable_unprepare(core->parent);
 		clk_pm_runtime_put(core);
 	}
 
@@ -258,13 +251,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
 		}
 	}
 
-	if (core->flags & CLK_OPS_PARENT_ENABLE)
-		clk_core_prepare_enable(core->parent);
-
 	ret = core->ops->is_enabled(core->hw);
-
-	if (core->flags & CLK_OPS_PARENT_ENABLE)
-		clk_core_disable_unprepare(core->parent);
 done:
 	if (core->rpm_enabled)
 		pm_runtime_put(core->dev);
@@ -831,9 +818,6 @@ int clk_rate_exclusive_get(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_rate_exclusive_get);
 
-static int clk_core_enable_lock(struct clk_core *core);
-static void clk_core_disable_lock(struct clk_core *core);
-
 static void clk_core_unprepare(struct clk_core *core)
 {
 	lockdep_assert_held(&prepare_lock);
@@ -857,9 +841,6 @@ static void clk_core_unprepare(struct clk_core *core)
 
 	WARN(core->enable_count > 0, "Unpreparing enabled %s\n", core->name);
 
-	if (core->flags & CLK_OPS_PARENT_ENABLE)
-		clk_core_enable_lock(core->parent);
-
 	trace_clk_unprepare(core);
 
 	if (core->ops->unprepare)
@@ -868,9 +849,6 @@ static void clk_core_unprepare(struct clk_core *core)
 	clk_pm_runtime_put(core);
 
 	trace_clk_unprepare_complete(core);
-
-	if (core->flags & CLK_OPS_PARENT_ENABLE)
-		clk_core_disable_lock(core->parent);
 	clk_core_unprepare(core->parent);
 }
 
@@ -919,9 +897,6 @@ static int clk_core_prepare(struct clk_core *core)
 		if (ret)
 			goto runtime_put;
 
-		if (core->flags & CLK_OPS_PARENT_ENABLE)
-			clk_core_enable_lock(core->parent);
-
 		trace_clk_prepare(core);
 
 		if (core->ops->prepare)
@@ -929,9 +904,6 @@ static int clk_core_prepare(struct clk_core *core)
 
 		trace_clk_prepare_complete(core);
 
-		if (core->flags & CLK_OPS_PARENT_ENABLE)
-			clk_core_disable_lock(core->parent);
-
 		if (ret)
 			goto unprepare;
 	}
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 053/107] clk: core: Fix runtime PM sequence in clk_core_unprepare()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (51 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 052/107] Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops" Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 054/107] Input: rk805-pwrkey - fix module autoloading Greg Kroah-Hartman
                   ` (62 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Chen-Yu Tsai,
	Nícolas F .  R .  A .  Prado, Stephen Boyd, Sasha Levin

From: Chen-Yu Tsai <wenst@chromium.org>

[ Upstream commit 4b592061f7b3971c70e8b72fc42aaead47c24701 ]

In the original commit 9a34b45397e5 ("clk: Add support for runtime PM"),
the commit message mentioned that pm_runtime_put_sync() would be done
at the end of clk_core_unprepare(). This mirrors the operations in
clk_core_prepare() in the opposite order.

However, the actual code that was added wasn't in the order the commit
message described. Move clk_pm_runtime_put() to the end of
clk_core_unprepare() so that it is in the correct order.

Fixes: 9a34b45397e5 ("clk: Add support for runtime PM")
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Link: https://lore.kernel.org/r/20220822081424.1310926-3-wenst@chromium.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/clk.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d6dc58bd07b33..0674dbc62eb55 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -846,10 +846,9 @@ static void clk_core_unprepare(struct clk_core *core)
 	if (core->ops->unprepare)
 		core->ops->unprepare(core->hw);
 
-	clk_pm_runtime_put(core);
-
 	trace_clk_unprepare_complete(core);
 	clk_core_unprepare(core->parent);
+	clk_pm_runtime_put(core);
 }
 
 static void clk_core_unprepare_lock(struct clk_core *core)
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 054/107] Input: rk805-pwrkey - fix module autoloading
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (52 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 053/107] clk: core: Fix runtime PM sequence in clk_core_unprepare() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 055/107] clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate Greg Kroah-Hartman
                   ` (61 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Peter Robinson,
	Javier Martinez Canillas, Dmitry Torokhov, Sasha Levin

From: Peter Robinson <pbrobinson@gmail.com>

[ Upstream commit 99077ad668ddd9b4823cc8ce3f3c7a3fc56f6fd9 ]

Add the module alias so the rk805-pwrkey driver will
autoload when built as a module.

Fixes: 5a35b85c2d92 ("Input: add power key driver for Rockchip RK805 PMIC")
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20220612225437.3628788-1-pbrobinson@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/input/misc/rk805-pwrkey.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/input/misc/rk805-pwrkey.c b/drivers/input/misc/rk805-pwrkey.c
index 3fb64dbda1a21..76873aa005b41 100644
--- a/drivers/input/misc/rk805-pwrkey.c
+++ b/drivers/input/misc/rk805-pwrkey.c
@@ -98,6 +98,7 @@ static struct platform_driver rk805_pwrkey_driver = {
 };
 module_platform_driver(rk805_pwrkey_driver);
 
+MODULE_ALIAS("platform:rk805-pwrkey");
 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
 MODULE_DESCRIPTION("RK805 PMIC Power Key driver");
 MODULE_LICENSE("GPL");
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 055/107] clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (53 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 054/107] Input: rk805-pwrkey - fix module autoloading Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 056/107] clk: bcm: rpi: Use correct order for the parameters of devm_kcalloc() Greg Kroah-Hartman
                   ` (60 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Stefan Wahren, Florian Fainelli,
	Stephen Boyd, Sasha Levin

From: Stefan Wahren <stefan.wahren@i2se.com>

[ Upstream commit 35f73cca1cecda0c1f8bb7d8be4ce5cd2d46ae8c ]

The function raspberrypi_fw_get_rate (e.g. used for the recalc_rate
hook) can fail to get the clock rate from the firmware. In this case
we cannot return a signed error value, which would be casted to
unsigned long. Fix this by returning 0 instead.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Link: https://lore.kernel.org/r/20220625083643.4012-1-stefan.wahren@i2se.com
Fixes: 4e85e535e6cc ("clk: bcm283x: add driver interfacing with Raspberry Pi's firmware")
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/bcm/clk-raspberrypi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index dd3b71eafabf3..fda78a2f9ac50 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -139,7 +139,7 @@ static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
 	ret = raspberrypi_clock_property(rpi->firmware, data,
 					 RPI_FIRMWARE_GET_CLOCK_RATE, &val);
 	if (ret)
-		return ret;
+		return 0;
 
 	return val;
 }
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 056/107] clk: bcm: rpi: Use correct order for the parameters of devm_kcalloc()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (54 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 055/107] clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 057/107] clk: bcm: rpi: Prevent out-of-bounds access Greg Kroah-Hartman
                   ` (59 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Christophe JAILLET, Stephen Boyd,
	Sasha Levin

From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>

[ Upstream commit b7fa6242f3e035308a76284560e4f918dad9b017 ]

We should have 'n', then 'size', not the opposite.
This is harmless because the 2 values are just multiplied, but having
the correct order silence a (unpublished yet) smatch warning.

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/49d726d11964ca0e3757bdb5659e3b3eaa1572b5.1653081643.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/bcm/clk-raspberrypi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index fda78a2f9ac50..97612860ce0e1 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -252,7 +252,7 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
 	int ret;
 
 	clks = devm_kcalloc(rpi->dev,
-			    sizeof(*clks), RPI_FIRMWARE_NUM_CLK_ID,
+			    RPI_FIRMWARE_NUM_CLK_ID, sizeof(*clks),
 			    GFP_KERNEL);
 	if (!clks)
 		return -ENOMEM;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 057/107] clk: bcm: rpi: Prevent out-of-bounds access
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (55 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 056/107] clk: bcm: rpi: Use correct order for the parameters of devm_kcalloc() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 058/107] clk: bcm: rpi: Add missing newline Greg Kroah-Hartman
                   ` (58 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Phil Elwell, Stefan Wahren,
	Florian Fainelli, Ivan T. Ivanov, Stephen Boyd, Sasha Levin

From: Stefan Wahren <stefan.wahren@i2se.com>

[ Upstream commit bc163555603e4ae9c817675ad80d618a4cdbfa2d ]

The while loop in raspberrypi_discover_clocks() relies on the assumption
that the id of the last clock element is zero. Because this data comes
from the Videocore firmware and it doesn't guarantuee such a behavior
this could lead to out-of-bounds access. So fix this by providing
a sentinel element.

Fixes: 93d2725affd6 ("clk: bcm: rpi: Discover the firmware clocks")
Link: https://github.com/raspberrypi/firmware/issues/1688
Suggested-by: Phil Elwell <phil@raspberrypi.com>
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Link: https://lore.kernel.org/r/20220713154953.3336-2-stefan.wahren@i2se.com
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Ivan T. Ivanov <iivanov@suse.de>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/bcm/clk-raspberrypi.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index 97612860ce0e1..834bcc256e921 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -251,8 +251,13 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
 	struct rpi_firmware_get_clocks_response *clks;
 	int ret;
 
+	/*
+	 * The firmware doesn't guarantee that the last element of
+	 * RPI_FIRMWARE_GET_CLOCKS is zeroed. So allocate an additional
+	 * zero element as sentinel.
+	 */
 	clks = devm_kcalloc(rpi->dev,
-			    RPI_FIRMWARE_NUM_CLK_ID, sizeof(*clks),
+			    RPI_FIRMWARE_NUM_CLK_ID + 1, sizeof(*clks),
 			    GFP_KERNEL);
 	if (!clks)
 		return -ENOMEM;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 058/107] clk: bcm: rpi: Add missing newline
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (56 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 057/107] clk: bcm: rpi: Prevent out-of-bounds access Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 059/107] hwmon: (gpio-fan) Fix array out of bounds access Greg Kroah-Hartman
                   ` (57 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Stefan Wahren, Florian Fainelli,
	Ivan T. Ivanov, Stephen Boyd, Sasha Levin

From: Stefan Wahren <stefan.wahren@i2se.com>

[ Upstream commit 13b5cf8d6a0d4a5d289e1ed046cadc63b416db85 ]

Some log messages lacks the final newline. So add them.

Fixes: 93d2725affd6 ("clk: bcm: rpi: Discover the firmware clocks")
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Link: https://lore.kernel.org/r/20220713154953.3336-3-stefan.wahren@i2se.com
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Ivan T. Ivanov <iivanov@suse.de>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/bcm/clk-raspberrypi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index 834bcc256e921..56c5166f841ae 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -156,7 +156,7 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
 	ret = raspberrypi_clock_property(rpi->firmware, data,
 					 RPI_FIRMWARE_SET_CLOCK_RATE, &_rate);
 	if (ret)
-		dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d",
+		dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d\n",
 				    clk_hw_get_name(hw), ret);
 
 	return ret;
@@ -208,7 +208,7 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
 					 RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
 					 &min_rate);
 	if (ret) {
-		dev_err(rpi->dev, "Failed to get clock %d min freq: %d",
+		dev_err(rpi->dev, "Failed to get clock %d min freq: %d\n",
 			id, ret);
 		return ERR_PTR(ret);
 	}
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 059/107] hwmon: (gpio-fan) Fix array out of bounds access
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (57 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 058/107] clk: bcm: rpi: Add missing newline Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 060/107] gpio: pca953x: Add mutex_lock for regcache sync in PM Greg Kroah-Hartman
                   ` (56 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Armin Wolf, Guenter Roeck, Sasha Levin

From: Armin Wolf <W_Armin@gmx.de>

[ Upstream commit f233d2be38dbbb22299192292983037f01ab363c ]

The driver does not check if the cooling state passed to
gpio_fan_set_cur_state() exceeds the maximum cooling state as
stored in fan_data->num_speeds. Since the cooling state is later
used as an array index in set_fan_speed(), an array out of bounds
access can occur.
This can be exploited by setting the state of the thermal cooling device
to arbitrary values, causing for example a kernel oops when unavailable
memory is accessed this way.

Example kernel oops:
[  807.987276] Unable to handle kernel paging request at virtual address ffffff80d0588064
[  807.987369] Mem abort info:
[  807.987398]   ESR = 0x96000005
[  807.987428]   EC = 0x25: DABT (current EL), IL = 32 bits
[  807.987477]   SET = 0, FnV = 0
[  807.987507]   EA = 0, S1PTW = 0
[  807.987536]   FSC = 0x05: level 1 translation fault
[  807.987570] Data abort info:
[  807.987763]   ISV = 0, ISS = 0x00000005
[  807.987801]   CM = 0, WnR = 0
[  807.987832] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001165000
[  807.987872] [ffffff80d0588064] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
[  807.987961] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[  807.987992] Modules linked in: cmac algif_hash aes_arm64 algif_skcipher af_alg bnep hci_uart btbcm bluetooth ecdh_generic ecc 8021q garp stp llc snd_soc_hdmi_codec brcmfmac vc4 brcmutil cec drm_kms_helper snd_soc_core cfg80211 snd_compress bcm2835_codec(C) snd_pcm_dmaengine syscopyarea bcm2835_isp(C) bcm2835_v4l2(C) sysfillrect v4l2_mem2mem bcm2835_mmal_vchiq(C) raspberrypi_hwmon sysimgblt videobuf2_dma_contig videobuf2_vmalloc fb_sys_fops videobuf2_memops rfkill videobuf2_v4l2 videobuf2_common i2c_bcm2835 snd_bcm2835(C) videodev snd_pcm snd_timer snd mc vc_sm_cma(C) gpio_fan uio_pdrv_genirq uio drm fuse drm_panel_orientation_quirks backlight ip_tables x_tables ipv6
[  807.988508] CPU: 0 PID: 1321 Comm: bash Tainted: G         C        5.15.56-v8+ #1575
[  807.988548] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT)
[  807.988574] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  807.988608] pc : set_fan_speed.part.5+0x34/0x80 [gpio_fan]
[  807.988654] lr : gpio_fan_set_cur_state+0x34/0x50 [gpio_fan]
[  807.988691] sp : ffffffc008cf3bd0
[  807.988710] x29: ffffffc008cf3bd0 x28: ffffff80019edac0 x27: 0000000000000000
[  807.988762] x26: 0000000000000000 x25: 0000000000000000 x24: ffffff800747c920
[  807.988787] x23: 000000000000000a x22: ffffff800369f000 x21: 000000001999997c
[  807.988854] x20: ffffff800369f2e8 x19: ffffff8002ae8080 x18: 0000000000000000
[  807.988877] x17: 0000000000000000 x16: 0000000000000000 x15: 000000559e271b70
[  807.988938] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[  807.988960] x11: 0000000000000000 x10: ffffffc008cf3c20 x9 : ffffffcfb60c741c
[  807.989018] x8 : 000000000000000a x7 : 00000000ffffffc9 x6 : 0000000000000009
[  807.989040] x5 : 000000000000002a x4 : 0000000000000000 x3 : ffffff800369f2e8
[  807.989062] x2 : 000000000000e780 x1 : 0000000000000001 x0 : ffffff80d0588060
[  807.989084] Call trace:
[  807.989091]  set_fan_speed.part.5+0x34/0x80 [gpio_fan]
[  807.989113]  gpio_fan_set_cur_state+0x34/0x50 [gpio_fan]
[  807.989199]  cur_state_store+0x84/0xd0
[  807.989221]  dev_attr_store+0x20/0x38
[  807.989262]  sysfs_kf_write+0x4c/0x60
[  807.989282]  kernfs_fop_write_iter+0x130/0x1c0
[  807.989298]  new_sync_write+0x10c/0x190
[  807.989315]  vfs_write+0x254/0x378
[  807.989362]  ksys_write+0x70/0xf8
[  807.989379]  __arm64_sys_write+0x24/0x30
[  807.989424]  invoke_syscall+0x4c/0x110
[  807.989442]  el0_svc_common.constprop.3+0xfc/0x120
[  807.989458]  do_el0_svc+0x2c/0x90
[  807.989473]  el0_svc+0x24/0x60
[  807.989544]  el0t_64_sync_handler+0x90/0xb8
[  807.989558]  el0t_64_sync+0x1a0/0x1a4
[  807.989579] Code: b9403801 f9402800 7100003f 8b35cc00 (b9400416)
[  807.989627] ---[ end trace 8ded4c918658445b ]---

Fix this by checking the cooling state and return an error if it
exceeds the maximum cooling state.

Tested on a Raspberry Pi 3.

Fixes: b5cf88e46bad ("(gpio-fan): Add thermal control hooks")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20220830011101.178843-1-W_Armin@gmx.de
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hwmon/gpio-fan.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index befe989ca7b94..fbf3f5a4ecb67 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -391,6 +391,9 @@ static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev,
 	if (!fan_data)
 		return -EINVAL;
 
+	if (state >= fan_data->num_speed)
+		return -EINVAL;
+
 	set_fan_speed(fan_data, state);
 	return 0;
 }
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 060/107] gpio: pca953x: Add mutex_lock for regcache sync in PM
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (58 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 059/107] hwmon: (gpio-fan) Fix array out of bounds access Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 061/107] KVM: x86: Mask off unsupported and unknown bits of IA32_ARCH_CAPABILITIES Greg Kroah-Hartman
                   ` (55 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Haibo Chen, Bartosz Golaszewski, Sasha Levin

From: Haibo Chen <haibo.chen@nxp.com>

[ Upstream commit 518e26f11af2fe4f5bebf9a0351595d508c7077f ]

The regcache sync will set the cache_bypass = true, at that
time, when there is regmap write operation, it will bypass
the regmap cache, then the regcache sync will write back the
value from cache to register, which is not as our expectation.

Though regmap already use its internal lock to avoid such issue,
but this driver force disable the regmap internal lock in its
regmap config: disable_locking = true

To avoid this issue, use the driver's own lock to do the protect
in system PM.

Fixes: b76574300504 ("gpio: pca953x: Restore registers after suspend/resume cycle")
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpio/gpio-pca953x.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 64befd6f702b2..4860bf3b7e002 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -1163,7 +1163,9 @@ static int pca953x_suspend(struct device *dev)
 {
 	struct pca953x_chip *chip = dev_get_drvdata(dev);
 
+	mutex_lock(&chip->i2c_lock);
 	regcache_cache_only(chip->regmap, true);
+	mutex_unlock(&chip->i2c_lock);
 
 	if (atomic_read(&chip->wakeup_path))
 		device_set_wakeup_path(dev);
@@ -1186,13 +1188,17 @@ static int pca953x_resume(struct device *dev)
 		}
 	}
 
+	mutex_lock(&chip->i2c_lock);
 	regcache_cache_only(chip->regmap, false);
 	regcache_mark_dirty(chip->regmap);
 	ret = pca953x_regcache_sync(dev);
-	if (ret)
+	if (ret) {
+		mutex_unlock(&chip->i2c_lock);
 		return ret;
+	}
 
 	ret = regcache_sync(chip->regmap);
+	mutex_unlock(&chip->i2c_lock);
 	if (ret) {
 		dev_err(dev, "Failed to restore register map: %d\n", ret);
 		return ret;
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 061/107] KVM: x86: Mask off unsupported and unknown bits of IA32_ARCH_CAPABILITIES
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (59 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 060/107] gpio: pca953x: Add mutex_lock for regcache sync in PM Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 062/107] xen/grants: prevent integer overflow in gnttab_dma_alloc_pages() Greg Kroah-Hartman
                   ` (54 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Paolo Bonzini, Jim Mattson,
	Vipin Sharma, Xiaoyao Li, Sasha Levin

From: Jim Mattson <jmattson@google.com>

[ Upstream commit 0204750bd4c6ccc2fb7417618477f10373b33f56 ]

KVM should not claim to virtualize unknown IA32_ARCH_CAPABILITIES
bits. When kvm_get_arch_capabilities() was originally written, there
were only a few bits defined in this MSR, and KVM could virtualize all
of them. However, over the years, several bits have been defined that
KVM cannot just blindly pass through to the guest without additional
work (such as virtualizing an MSR promised by the
IA32_ARCH_CAPABILITES feature bit).

Define a mask of supported IA32_ARCH_CAPABILITIES bits, and mask off
any other bits that are set in the hardware MSR.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Fixes: 5b76a3cff011 ("KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry")
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Vipin Sharma <vipinsh@google.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20220830174947.2182144-1-jmattson@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/kvm/x86.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f5b7a05530eb0..9109e5589b421 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1465,12 +1465,32 @@ static const u32 msr_based_features_all[] = {
 static u32 msr_based_features[ARRAY_SIZE(msr_based_features_all)];
 static unsigned int num_msr_based_features;
 
+/*
+ * Some IA32_ARCH_CAPABILITIES bits have dependencies on MSRs that KVM
+ * does not yet virtualize. These include:
+ *   10 - MISC_PACKAGE_CTRLS
+ *   11 - ENERGY_FILTERING_CTL
+ *   12 - DOITM
+ *   18 - FB_CLEAR_CTRL
+ *   21 - XAPIC_DISABLE_STATUS
+ *   23 - OVERCLOCKING_STATUS
+ */
+
+#define KVM_SUPPORTED_ARCH_CAP \
+	(ARCH_CAP_RDCL_NO | ARCH_CAP_IBRS_ALL | ARCH_CAP_RSBA | \
+	 ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \
+	 ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
+	 ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
+	 ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO)
+
 static u64 kvm_get_arch_capabilities(void)
 {
 	u64 data = 0;
 
-	if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
+	if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) {
 		rdmsrl(MSR_IA32_ARCH_CAPABILITIES, data);
+		data &= KVM_SUPPORTED_ARCH_CAP;
+	}
 
 	/*
 	 * If nx_huge_pages is enabled, KVM's shadow paging will ensure that
@@ -1518,9 +1538,6 @@ static u64 kvm_get_arch_capabilities(void)
 		 */
 	}
 
-	/* Guests don't need to know "Fill buffer clear control" exists */
-	data &= ~ARCH_CAP_FB_CLEAR_CTRL;
-
 	return data;
 }
 
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 062/107] xen/grants: prevent integer overflow in gnttab_dma_alloc_pages()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (60 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 061/107] KVM: x86: Mask off unsupported and unknown bits of IA32_ARCH_CAPABILITIES Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 063/107] mm: pagewalk: Fix race between unmap and page walker Greg Kroah-Hartman
                   ` (53 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Dan Carpenter, Juergen Gross, Sasha Levin

From: Dan Carpenter <dan.carpenter@oracle.com>

[ Upstream commit e9ea0b30ada008f4e65933f449db6894832cb242 ]

The change from kcalloc() to kvmalloc() means that arg->nr_pages
might now be large enough that the "args->nr_pages << PAGE_SHIFT" can
result in an integer overflow.

Fixes: b3f7931f5c61 ("xen/gntdev: switch from kcalloc() to kvcalloc()")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/YxDROJqu/RPvR0bi@kili
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/xen/grant-table.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 5c83d41766c85..0a2d24d6ac6f7 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -981,6 +981,9 @@ int gnttab_dma_alloc_pages(struct gnttab_dma_alloc_args *args)
 	size_t size;
 	int i, ret;
 
+	if (args->nr_pages < 0 || args->nr_pages > (INT_MAX >> PAGE_SHIFT))
+		return -ENOMEM;
+
 	size = args->nr_pages << PAGE_SHIFT;
 	if (args->coherent)
 		args->vaddr = dma_alloc_coherent(args->dev, size,
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 063/107] mm: pagewalk: Fix race between unmap and page walker
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (61 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 062/107] xen/grants: prevent integer overflow in gnttab_dma_alloc_pages() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 064/107] xen-blkback: Advertise feature-persistent as user requested Greg Kroah-Hartman
                   ` (52 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Jann Horn, Steven Price,
	Vlastimil Babka, Thomas Hellström, Konstantin Khlebnikov,
	Andrew Morton, Linus Torvalds, Sasha Levin

From: Steven Price <steven.price@arm.com>

[ Upstream commit 8782fb61cc848364e1e1599d76d3c9dd58a1cc06 ]

The mmap lock protects the page walker from changes to the page tables
during the walk.  However a read lock is insufficient to protect those
areas which don't have a VMA as munmap() detaches the VMAs before
downgrading to a read lock and actually tearing down PTEs/page tables.

For users of walk_page_range() the solution is to simply call pte_hole()
immediately without checking the actual page tables when a VMA is not
present. We now never call __walk_page_range() without a valid vma.

For walk_page_range_novma() the locking requirements are tightened to
require the mmap write lock to be taken, and then walking the pgd
directly with 'no_vma' set.

This in turn means that all page walkers either have a valid vma, or
it's that special 'novma' case for page table debugging.  As a result,
all the odd '(!walk->vma && !walk->no_vma)' tests can be removed.

Fixes: dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap")
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/riscv/mm/pageattr.c |  4 ++--
 mm/pagewalk.c            | 21 ++++++++++++---------
 mm/ptdump.c              |  4 ++--
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 5e49e4b4a4ccc..86c56616e5dea 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -118,10 +118,10 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,
 	if (!numpages)
 		return 0;
 
-	mmap_read_lock(&init_mm);
+	mmap_write_lock(&init_mm);
 	ret =  walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL,
 				     &masks);
-	mmap_read_unlock(&init_mm);
+	mmap_write_unlock(&init_mm);
 
 	flush_tlb_kernel_range(start, end);
 
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 9b3db11a4d1db..fa7a3d21a7518 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -110,7 +110,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
 	do {
 again:
 		next = pmd_addr_end(addr, end);
-		if (pmd_none(*pmd) || (!walk->vma && !walk->no_vma)) {
+		if (pmd_none(*pmd)) {
 			if (ops->pte_hole)
 				err = ops->pte_hole(addr, next, depth, walk);
 			if (err)
@@ -171,7 +171,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
 	do {
  again:
 		next = pud_addr_end(addr, end);
-		if (pud_none(*pud) || (!walk->vma && !walk->no_vma)) {
+		if (pud_none(*pud)) {
 			if (ops->pte_hole)
 				err = ops->pte_hole(addr, next, depth, walk);
 			if (err)
@@ -366,19 +366,19 @@ static int __walk_page_range(unsigned long start, unsigned long end,
 	struct vm_area_struct *vma = walk->vma;
 	const struct mm_walk_ops *ops = walk->ops;
 
-	if (vma && ops->pre_vma) {
+	if (ops->pre_vma) {
 		err = ops->pre_vma(start, end, walk);
 		if (err)
 			return err;
 	}
 
-	if (vma && is_vm_hugetlb_page(vma)) {
+	if (is_vm_hugetlb_page(vma)) {
 		if (ops->hugetlb_entry)
 			err = walk_hugetlb_range(start, end, walk);
 	} else
 		err = walk_pgd_range(start, end, walk);
 
-	if (vma && ops->post_vma)
+	if (ops->post_vma)
 		ops->post_vma(walk);
 
 	return err;
@@ -450,9 +450,13 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
 		if (!vma) { /* after the last vma */
 			walk.vma = NULL;
 			next = end;
+			if (ops->pte_hole)
+				err = ops->pte_hole(start, next, -1, &walk);
 		} else if (start < vma->vm_start) { /* outside vma */
 			walk.vma = NULL;
 			next = min(end, vma->vm_start);
+			if (ops->pte_hole)
+				err = ops->pte_hole(start, next, -1, &walk);
 		} else { /* inside vma */
 			walk.vma = vma;
 			next = min(end, vma->vm_end);
@@ -470,9 +474,8 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
 			}
 			if (err < 0)
 				break;
-		}
-		if (walk.vma || walk.ops->pte_hole)
 			err = __walk_page_range(start, next, &walk);
+		}
 		if (err)
 			break;
 	} while (start = next, start < end);
@@ -501,9 +504,9 @@ int walk_page_range_novma(struct mm_struct *mm, unsigned long start,
 	if (start >= end || !walk.mm)
 		return -EINVAL;
 
-	mmap_assert_locked(walk.mm);
+	mmap_assert_write_locked(walk.mm);
 
-	return __walk_page_range(start, end, &walk);
+	return walk_pgd_range(start, end, &walk);
 }
 
 int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops,
diff --git a/mm/ptdump.c b/mm/ptdump.c
index da751448d0e4e..f84ea700662fc 100644
--- a/mm/ptdump.c
+++ b/mm/ptdump.c
@@ -144,13 +144,13 @@ void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd)
 {
 	const struct ptdump_range *range = st->range;
 
-	mmap_read_lock(mm);
+	mmap_write_lock(mm);
 	while (range->start != range->end) {
 		walk_page_range_novma(mm, range->start, range->end,
 				      &ptdump_ops, pgd, st);
 		range++;
 	}
-	mmap_read_unlock(mm);
+	mmap_write_unlock(mm);
 
 	/* Flush out the last page */
 	st->note_page(st, 0, -1, 0);
-- 
2.35.1




^ permalink raw reply related	[flat|nested] 133+ messages in thread

* [PATCH 5.15 064/107] xen-blkback: Advertise feature-persistent as user requested
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (62 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 063/107] mm: pagewalk: Fix race between unmap and page walker Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 065/107] xen-blkfront: " Greg Kroah-Hartman
                   ` (51 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Juergen Gross, SeongJae Park,
	Marek Marczykowski-Górecki

From: SeongJae Park <sj@kernel.org>

commit 06ba5d2e943e97bb66e75c152e87f1d2c7027a67 upstream.

The advertisement of the persistent grants feature (writing
'feature-persistent' to xenbus) should mean not the decision for using
the feature but only the availability of the feature.  However, commit
aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent
grants") made a field of blkback, which was a place for saving only the
negotiation result, to be used for yet another purpose: caching of the
'feature_persistent' parameter value.  As a result, the advertisement,
which should follow only the parameter value, becomes inconsistent.

This commit fixes the misuse of the semantic by making blkback saves the
parameter value in a separate place and advertises the support based on
only the saved value.

Fixes: aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants")
Cc: <stable@vger.kernel.org> # 5.10.x
Suggested-by: Juergen Gross <jgross@suse.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20220831165824.94815-2-sj@kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/block/xen-blkback/common.h |    3 +++
 drivers/block/xen-blkback/xenbus.c |    6 ++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -226,6 +226,9 @@ struct xen_vbd {
 	sector_t		size;
 	unsigned int		flush_support:1;
 	unsigned int		discard_secure:1;
+	/* Connect-time cached feature_persistent parameter value */
+	unsigned int		feature_gnt_persistent_parm:1;
+	/* Persistent grants feature negotiation result */
 	unsigned int		feature_gnt_persistent:1;
 	unsigned int		overflow_max_grants:1;
 };
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -910,7 +910,7 @@ again:
 	xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
 
 	err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u",
-			be->blkif->vbd.feature_gnt_persistent);
+			be->blkif->vbd.feature_gnt_persistent_parm);
 	if (err) {
 		xenbus_dev_fatal(dev, err, "writing %s/feature-persistent",
 				 dev->nodename);
@@ -1088,7 +1088,9 @@ static int connect_ring(struct backend_i
 		return -ENOSYS;
 	}
 
-	blkif->vbd.feature_gnt_persistent = feature_persistent &&
+	blkif->vbd.feature_gnt_persistent_parm = feature_persistent;
+	blkif->vbd.feature_gnt_persistent =
+		blkif->vbd.feature_gnt_persistent_parm &&
 		xenbus_read_unsigned(dev->otherend, "feature-persistent", 0);
 
 	blkif->vbd.overflow_max_grants = 0;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 065/107] xen-blkfront: Advertise feature-persistent as user requested
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (63 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 064/107] xen-blkback: Advertise feature-persistent as user requested Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 066/107] xen-blkfront: Cache feature_persistent value before advertisement Greg Kroah-Hartman
                   ` (50 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Juergen Gross, SeongJae Park,
	Marek Marczykowski-Górecki

From: SeongJae Park <sj@kernel.org>

commit 9f5e0fe5d05f7e8de7f39b2b10089834eb0ff787 upstream.

The advertisement of the persistent grants feature (writing
'feature-persistent' to xenbus) should mean not the decision for using
the feature but only the availability of the feature.  However, commit
74a852479c68 ("xen-blkfront: add a parameter for disabling of persistent
grants") made a field of blkfront, which was a place for saving only the
negotiation result, to be used for yet another purpose: caching of the
'feature_persistent' parameter value.  As a result, the advertisement,
which should follow only the parameter value, becomes inconsistent.

This commit fixes the misuse of the semantic by making blkfront saves
the parameter value in a separate place and advertises the support based
on only the saved value.

Fixes: 74a852479c68 ("xen-blkfront: add a parameter for disabling of persistent grants")
Cc: <stable@vger.kernel.org> # 5.10.x
Suggested-by: Juergen Gross <jgross@suse.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20220831165824.94815-3-sj@kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/block/xen-blkfront.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -212,6 +212,9 @@ struct blkfront_info
 	unsigned int feature_fua:1;
 	unsigned int feature_discard:1;
 	unsigned int feature_secdiscard:1;
+	/* Connect-time cached feature_persistent parameter */
+	unsigned int feature_persistent_parm:1;
+	/* Persistent grants feature negotiation result */
 	unsigned int feature_persistent:1;
 	unsigned int bounce:1;
 	unsigned int discard_granularity;
@@ -1874,7 +1877,7 @@ again:
 		goto abort_transaction;
 	}
 	err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u",
-			info->feature_persistent);
+			info->feature_persistent_parm);
 	if (err)
 		dev_warn(&dev->dev,
 			 "writing persistent grants feature to xenbus");
@@ -2307,7 +2310,8 @@ static void blkfront_gather_backend_feat
 	if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0))
 		blkfront_setup_discard(info);
 
-	if (feature_persistent)
+	info->feature_persistent_parm = feature_persistent;
+	if (info->feature_persistent_parm)
 		info->feature_persistent =
 			!!xenbus_read_unsigned(info->xbdev->otherend,
 					       "feature-persistent", 0);



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 066/107] xen-blkfront: Cache feature_persistent value before advertisement
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (64 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 065/107] xen-blkfront: " Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 067/107] thunderbolt: Use the actual buffer in tb_async_error() Greg Kroah-Hartman
                   ` (49 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Marek Marczykowski-Górecki,
	SeongJae Park, Juergen Gross

From: SeongJae Park <sj@kernel.org>

commit fe8f65b018effbf473f53af3538d0c1878b8b329 upstream.

Xen blkfront advertises its support of the persistent grants feature
when it first setting up and when resuming in 'talk_to_blkback()'.
Then, blkback reads the advertised value when it connects with blkfront
and decides if it will use the persistent grants feature or not, and
advertises its decision to blkfront.  Blkfront reads the blkback's
decision and it also makes the decision for the use of the feature.

Commit 402c43ea6b34 ("xen-blkfront: Apply 'feature_persistent' parameter
when connect"), however, made the blkfront's read of the parameter for
disabling the advertisement, namely 'feature_persistent', to be done
when it negotiate, not when advertise.  Therefore blkfront advertises
without reading the parameter.  As the field for caching the parameter
value is zero-initialized, it always advertises as the feature is
disabled, so that the persistent grants feature becomes always disabled.

This commit fixes the issue by making the blkfront does parmeter caching
just before the advertisement.

Fixes: 402c43ea6b34 ("xen-blkfront: Apply 'feature_persistent' parameter when connect")
Cc: <stable@vger.kernel.org> # 5.10.x
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20220831165824.94815-4-sj@kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/block/xen-blkfront.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1785,6 +1785,12 @@ abort_transaction:
 	return err;
 }
 
+/* Enable the persistent grants feature. */
+static bool feature_persistent = true;
+module_param(feature_persistent, bool, 0644);
+MODULE_PARM_DESC(feature_persistent,
+		"Enables the persistent grants feature");
+
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_blkback(struct xenbus_device *dev,
 			   struct blkfront_info *info)
@@ -1876,6 +1882,7 @@ again:
 		message = "writing protocol";
 		goto abort_transaction;
 	}
+	info->feature_persistent_parm = feature_persistent;
 	err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u",
 			info->feature_persistent_parm);
 	if (err)
@@ -1945,12 +1952,6 @@ static int negotiate_mq(struct blkfront_
 	return 0;
 }
 
-/* Enable the persistent grants feature. */
-static bool feature_persistent = true;
-module_param(feature_persistent, bool, 0644);
-MODULE_PARM_DESC(feature_persistent,
-		"Enables the persistent grants feature");
-
 /*
  * Entry point to this code when a new device is created.  Allocate the basic
  * structures and the ring buffer for communication with the backend, and
@@ -2310,7 +2311,6 @@ static void blkfront_gather_backend_feat
 	if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0))
 		blkfront_setup_discard(info);
 
-	info->feature_persistent_parm = feature_persistent;
 	if (info->feature_persistent_parm)
 		info->feature_persistent =
 			!!xenbus_read_unsigned(info->xbdev->otherend,



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 067/107] thunderbolt: Use the actual buffer in tb_async_error()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (65 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 066/107] xen-blkfront: Cache feature_persistent value before advertisement Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 068/107] usb: dwc3: pci: Add support for Intel Raptor Lake Greg Kroah-Hartman
                   ` (48 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Mika Westerberg

From: Mika Westerberg <mika.westerberg@linux.intel.com>

commit eb100b8fa8e8b59eb3e5fc7a5fd4a1e3c5950f64 upstream.

The received notification packet is held in pkg->buffer and not in pkg
itself. Fix this by using the correct buffer.

Fixes: 81a54b5e1986 ("thunderbolt: Let the connection manager handle all notifications")
Cc: stable@vger.kernel.org
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/thunderbolt/ctl.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/thunderbolt/ctl.c
+++ b/drivers/thunderbolt/ctl.c
@@ -408,7 +408,7 @@ static void tb_ctl_rx_submit(struct ctl_
 
 static int tb_async_error(const struct ctl_pkg *pkg)
 {
-	const struct cfg_error_pkg *error = (const struct cfg_error_pkg *)pkg;
+	const struct cfg_error_pkg *error = pkg->buffer;
 
 	if (pkg->frame.eof != TB_CFG_PKG_ERROR)
 		return false;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 068/107] usb: dwc3: pci: Add support for Intel Raptor Lake
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (66 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 067/107] thunderbolt: Use the actual buffer in tb_async_error() Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 069/107] media: mceusb: Use new usb_control_msg_*() routines Greg Kroah-Hartman
                   ` (47 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Heikki Krogerus

From: Heikki Krogerus <heikki.krogerus@linux.intel.com>

commit bad0d1d726ace2db9e0f39c62b173bc7cc43dd6a upstream.

This adds the necessary PCI device ID for the controller
inside the Intel Raptor Lake CPU block. The controllers that
are part of the PCH (chipset) have separate device IDs.

Cc: stable@vger.kernel.org
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20220815123334.87526-1-heikki.krogerus@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/dwc3-pci.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -43,6 +43,7 @@
 #define PCI_DEVICE_ID_INTEL_ADLP		0x51ee
 #define PCI_DEVICE_ID_INTEL_ADLM		0x54ee
 #define PCI_DEVICE_ID_INTEL_ADLS		0x7ae1
+#define PCI_DEVICE_ID_INTEL_RPL			0x460e
 #define PCI_DEVICE_ID_INTEL_RPLS		0x7a61
 #define PCI_DEVICE_ID_INTEL_MTLP		0x7ec1
 #define PCI_DEVICE_ID_INTEL_MTL			0x7e7e
@@ -420,6 +421,9 @@ static const struct pci_device_id dwc3_p
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS),
 	  (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPL),
+	  (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS),
 	  (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 069/107] media: mceusb: Use new usb_control_msg_*() routines
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (67 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 068/107] usb: dwc3: pci: Add support for Intel Raptor Lake Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 070/107] xhci: Add grace period after xHC start to prevent premature runtime suspend Greg Kroah-Hartman
                   ` (46 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Mauro Carvalho Chehab, Alan Stern, Rondreis

From: Alan Stern <stern@rowland.harvard.edu>

commit 608e58a0f4617977178131f5f68a3fce1d3f5316 upstream.

Automatic kernel fuzzing led to a WARN about invalid pipe direction in
the mceusb driver:

------------[ cut here ]------------
usb 6-1: BOGUS control dir, pipe 80000380 doesn't match bRequestType 40
WARNING: CPU: 0 PID: 2465 at drivers/usb/core/urb.c:410
usb_submit_urb+0x1326/0x1820 drivers/usb/core/urb.c:410
Modules linked in:
CPU: 0 PID: 2465 Comm: kworker/0:2 Not tainted 5.19.0-rc4-00208-g69cb6c6556ad #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Workqueue: usb_hub_wq hub_event
RIP: 0010:usb_submit_urb+0x1326/0x1820 drivers/usb/core/urb.c:410
Code: 7c 24 40 e8 ac 23 91 fd 48 8b 7c 24 40 e8 b2 70 1b ff 45 89 e8
44 89 f1 4c 89 e2 48 89 c6 48 c7 c7 a0 30 a9 86 e8 48 07 11 02 <0f> 0b
e9 1c f0 ff ff e8 7e 23 91 fd 0f b6 1d 63 22 83 05 31 ff 41
RSP: 0018:ffffc900032becf0 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffff8881100f3058 RCX: 0000000000000000
RDX: ffffc90004961000 RSI: ffff888114c6d580 RDI: fffff52000657d90
RBP: ffff888105ad90f0 R08: ffffffff812c3638 R09: 0000000000000000
R10: 0000000000000005 R11: ffffed1023504ef1 R12: ffff888105ad9000
R13: 0000000000000040 R14: 0000000080000380 R15: ffff88810ba96500
FS: 0000000000000000(0000) GS:ffff88811a800000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffe810bda58 CR3: 000000010b720000 CR4: 0000000000350ef0
Call Trace:
<TASK>
usb_start_wait_urb+0x101/0x4c0 drivers/usb/core/message.c:58
usb_internal_control_msg drivers/usb/core/message.c:102 [inline]
usb_control_msg+0x31c/0x4a0 drivers/usb/core/message.c:153
mceusb_gen1_init drivers/media/rc/mceusb.c:1431 [inline]
mceusb_dev_probe+0x258e/0x33f0 drivers/media/rc/mceusb.c:1807

The reason for the warning is clear enough; the driver sends an
unusual read request on endpoint 0 but does not set the USB_DIR_IN bit
in the bRequestType field.

More importantly, the whole situation can be avoided and the driver
simplified by converting it over to the relatively new
usb_control_msg_recv() and usb_control_msg_send() routines.  That's
what this fix does.

Link: https://lore.kernel.org/all/CAB7eexLLApHJwZfMQ=X-PtRhw0BgO+5KcSMS05FNUYejJXqtSA@mail.gmail.com/
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: stable@vger.kernel.org
Reported-and-tested-by: Rondreis <linhaoguo86@gmail.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/YwkfnBFCSEVC6XZu@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/media/rc/mceusb.c |   35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1416,42 +1416,37 @@ static void mceusb_gen1_init(struct mceu
 {
 	int ret;
 	struct device *dev = ir->dev;
-	char *data;
-
-	data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL);
-	if (!data) {
-		dev_err(dev, "%s: memory allocation failed!", __func__);
-		return;
-	}
+	char data[USB_CTRL_MSG_SZ];
 
 	/*
 	 * This is a strange one. Windows issues a set address to the device
 	 * on the receive control pipe and expect a certain value pair back
 	 */
-	ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
-			      USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
-			      data, USB_CTRL_MSG_SZ, 3000);
+	ret = usb_control_msg_recv(ir->usbdev, 0, USB_REQ_SET_ADDRESS,
+				   USB_DIR_IN | USB_TYPE_VENDOR,
+				   0, 0, data, USB_CTRL_MSG_SZ, 3000,
+				   GFP_KERNEL);
 	dev_dbg(dev, "set address - ret = %d", ret);
 	dev_dbg(dev, "set address - data[0] = %d, data[1] = %d",
 						data[0], data[1]);
 
 	/* set feature: bit rate 38400 bps */
-	ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
-			      USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
-			      0xc04e, 0x0000, NULL, 0, 3000);
+	ret = usb_control_msg_send(ir->usbdev, 0,
+				   USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
+				   0xc04e, 0x0000, NULL, 0, 3000, GFP_KERNEL);
 
 	dev_dbg(dev, "set feature - ret = %d", ret);
 
 	/* bRequest 4: set char length to 8 bits */
-	ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
-			      4, USB_TYPE_VENDOR,
-			      0x0808, 0x0000, NULL, 0, 3000);
+	ret = usb_control_msg_send(ir->usbdev, 0,
+				   4, USB_TYPE_VENDOR,
+				   0x0808, 0x0000, NULL, 0, 3000, GFP_KERNEL);
 	dev_dbg(dev, "set char length - retB = %d", ret);
 
 	/* bRequest 2: set handshaking to use DTR/DSR */
-	ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
-			      2, USB_TYPE_VENDOR,
-			      0x0000, 0x0100, NULL, 0, 3000);
+	ret = usb_control_msg_send(ir->usbdev, 0,
+				   2, USB_TYPE_VENDOR,
+				   0x0000, 0x0100, NULL, 0, 3000, GFP_KERNEL);
 	dev_dbg(dev, "set handshake  - retC = %d", ret);
 
 	/* device resume */
@@ -1459,8 +1454,6 @@ static void mceusb_gen1_init(struct mceu
 
 	/* get hw/sw revision? */
 	mce_command_out(ir, GET_REVISION, sizeof(GET_REVISION));
-
-	kfree(data);
 }
 
 static void mceusb_gen2_init(struct mceusb_dev *ir)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 070/107] xhci: Add grace period after xHC start to prevent premature runtime suspend.
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (68 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 069/107] media: mceusb: Use new usb_control_msg_*() routines Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 071/107] USB: serial: cp210x: add Decagon UCA device id Greg Kroah-Hartman
                   ` (45 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Mathias Nyman

From: Mathias Nyman <mathias.nyman@linux.intel.com>

commit 33e321586e37b642ad10594b9ef25a613555cd08 upstream.

After xHC controller is started, either in probe or resume, it can take
a while before any of the connected usb devices are visible to the roothub
due to link training.

It's possible xhci driver loads, sees no acivity and suspends the host
before the USB device is visible.

In one testcase with a hotplugged xHC controller the host finally detected
the connected USB device and generated a wake 500ms after host initial
start.

If hosts didn't suspend the device duringe training it probablty wouldn't
take up to 500ms to detect it, but looking at specs reveal USB3 link
training has a couple long timeout values, such as 120ms
RxDetectQuietTimeout, and 360ms PollingLFPSTimeout.

So Add a 500ms grace period that keeps polling the roothub for 500ms after
start, preventing runtime suspend until USB devices are detected.

Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20220825150840.132216-3-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/xhci-hub.c |   11 +++++++++++
 drivers/usb/host/xhci.c     |    4 +++-
 drivers/usb/host/xhci.h     |    2 +-
 3 files changed, 15 insertions(+), 2 deletions(-)

--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1647,6 +1647,17 @@ int xhci_hub_status_data(struct usb_hcd
 
 	status = bus_state->resuming_ports;
 
+	/*
+	 * SS devices are only visible to roothub after link training completes.
+	 * Keep polling roothubs for a grace period after xHC start
+	 */
+	if (xhci->run_graceperiod) {
+		if (time_before(jiffies, xhci->run_graceperiod))
+			status = 1;
+		else
+			xhci->run_graceperiod = 0;
+	}
+
 	mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC;
 
 	/* For each port, did anything change?  If so, set that bit in buf. */
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -148,9 +148,11 @@ int xhci_start(struct xhci_hcd *xhci)
 		xhci_err(xhci, "Host took too long to start, "
 				"waited %u microseconds.\n",
 				XHCI_MAX_HALT_USEC);
-	if (!ret)
+	if (!ret) {
 		/* clear state flags. Including dying, halted or removing */
 		xhci->xhc_state = 0;
+		xhci->run_graceperiod = jiffies + msecs_to_jiffies(500);
+	}
 
 	return ret;
 }
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1830,7 +1830,7 @@ struct xhci_hcd {
 
 	/* Host controller watchdog timer structures */
 	unsigned int		xhc_state;
-
+	unsigned long		run_graceperiod;
 	u32			command;
 	struct s3_save		s3;
 /* Host controller is dying - not responding to commands. "I'm not dead yet!"



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 071/107] USB: serial: cp210x: add Decagon UCA device id
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (69 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 070/107] xhci: Add grace period after xHC start to prevent premature runtime suspend Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 072/107] USB: serial: option: add support for OPPO R11 diag port Greg Kroah-Hartman
                   ` (44 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Johan Hovold

From: Johan Hovold <johan@kernel.org>

commit ceb4038472a4803e7046ed488b03d11551991514 upstream.

Add the device id for Decagon Devices USB Cable Adapter.

Link: https://lore.kernel.org/r/trinity-819f9db2-d3e1-40e9-a669-9c245817c046-1661523546680@msvc-mesg-web108
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/cp210x.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -130,6 +130,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0x83AA) }, /* Mark-10 Digital Force Gauge */
 	{ USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */
 	{ USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
+	{ USB_DEVICE(0x10C4, 0x8414) }, /* Decagon USB Cable Adapter */
 	{ USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
 	{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
 	{ USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 072/107] USB: serial: option: add support for OPPO R11 diag port
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (70 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 071/107] USB: serial: cp210x: add Decagon UCA device id Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 073/107] USB: serial: option: add Quectel EM060K modem Greg Kroah-Hartman
                   ` (43 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Yan Xinyu, Johan Hovold

From: Yan Xinyu <sdlyyxy@bupt.edu.cn>

commit 8d5fc280392735e4441b35de14f2f4860fa8d83c upstream.

Add support for OPPO R11 USB diag serial port to option driver. This
phone uses Qualcomm Snapdragon 660 SoC.

usb-devices output:
T:  Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 10 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=22d9 ProdID=276c Rev=04.04
S:  Manufacturer=OPPO
S:  Product=SDM660-MTP _SN:09C6BCA7
S:  SerialNumber=beb2c403
C:  #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=500mA
I:  If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
I:  If#=0x1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs

Signed-off-by: Yan Xinyu <sdlyyxy@bupt.edu.cn>
Link: https://lore.kernel.org/r/20220714102037.4113889-1-sdlyyxy@bupt.edu.cn
Link: https://lore.kernel.org/r/Yt1WfSZk03Plpnan@hovoldconsulting.com
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/option.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -573,6 +573,10 @@ static void option_instat_callback(struc
 #define WETELECOM_PRODUCT_6802			0x6802
 #define WETELECOM_PRODUCT_WMD300		0x6803
 
+/* OPPO products */
+#define OPPO_VENDOR_ID				0x22d9
+#define OPPO_PRODUCT_R11			0x276c
+
 
 /* Device flags */
 
@@ -2155,6 +2159,7 @@ static const struct usb_device_id option
 	{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) },			/* GosunCn GM500 RNDIS */
 	{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) },			/* GosunCn GM500 MBIM */
 	{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) },			/* GosunCn GM500 ECM/NCM */
+	{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 073/107] USB: serial: option: add Quectel EM060K modem
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (71 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 072/107] USB: serial: option: add support for OPPO R11 diag port Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 074/107] USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode Greg Kroah-Hartman
                   ` (42 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Yonglin Tan, Johan Hovold

From: Yonglin Tan <yonglin.tan@outlook.com>

commit f766f3abe6dbc9bf8b56a5d53c87e5a17942c154 upstream.

Add usb product id entry for the Quectel EM060K module.

"MBIM mode": DIAG + NMEA + AT + MODEM + MBIM + QDSS

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  8 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=030b Rev= 5.04
S:  Manufacturer=Quectel
S:  Product=EM060K-GL
S:  SerialNumber=89fb57db
C:* #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA
A:  FirstIf#= 8 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option
E:  Ad=83(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=85(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=87(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 8 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim
E:  Ad=88(I) Atr=03(Int.) MxPS=  64 Ivl=32ms
I:  If#= 9 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
I:* If#= 9 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
E:  Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#=12 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Signed-off-by: Yonglin Tan <yonglin.tan@outlook.com>
[ johan: mention QDSS port and sort entries ]
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/option.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -253,6 +253,7 @@ static void option_instat_callback(struc
 #define QUECTEL_PRODUCT_BG96			0x0296
 #define QUECTEL_PRODUCT_EP06			0x0306
 #define QUECTEL_PRODUCT_EM05G			0x030a
+#define QUECTEL_PRODUCT_EM060K			0x030b
 #define QUECTEL_PRODUCT_EM12			0x0512
 #define QUECTEL_PRODUCT_RM500Q			0x0800
 #define QUECTEL_PRODUCT_EC200S_CN		0x6002
@@ -1142,6 +1143,9 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
 	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff),
 	  .driver_info = RSVD(6) | ZLP },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
 	  .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 074/107] USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (72 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 073/107] USB: serial: option: add Quectel EM060K modem Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 075/107] usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles Greg Kroah-Hartman
                   ` (41 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Slark Xiao, Johan Hovold

From: Slark Xiao <slark_xiao@163.com>

commit 8ffe20d08f2c95d702c453020d03a4c568a988f0 upstream.

We added PIDs for MV32-WA/WB MBIM mode before, now we need to add
support for RmNet mode.

Test evidence as below:
T:  Bus=03 Lev=01 Prnt=01 Port=02 Cnt=03 Dev#=  3 Spd=480 MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1e2d ProdID=00f3 Rev=05.04
S:  Manufacturer=Cinterion
S:  Product=Cinterion PID 0x00F3 USB Mobile Broadband
S:  SerialNumber=d7b4be8d
C:  #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=500mA
I:  If#=0x0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
I:  If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
I:  If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
I:  If#=0x3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option

T:  Bus=03 Lev=01 Prnt=01 Port=02 Cnt=03 Dev#= 10 Spd=480 MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1e2d ProdID=00f4 Rev=05.04
S:  Manufacturer=Cinterion
S:  Product=Cinterion PID 0x00F4 USB Mobile Broadband
S:  SerialNumber=d095087d
C:  #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=500mA
I:  If#=0x0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
I:  If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
I:  If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
I:  If#=0x3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option

Signed-off-by: Slark Xiao <slark_xiao@163.com>
[ johan: sort entries ]
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/option.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -439,6 +439,8 @@ static void option_instat_callback(struc
 #define CINTERION_PRODUCT_MV31_2_RMNET		0x00b9
 #define CINTERION_PRODUCT_MV32_WA		0x00f1
 #define CINTERION_PRODUCT_MV32_WB		0x00f2
+#define CINTERION_PRODUCT_MV32_WA_RMNET		0x00f3
+#define CINTERION_PRODUCT_MV32_WB_RMNET		0x00f4
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID			0x0b3c
@@ -2001,8 +2003,12 @@ static const struct usb_device_id option
 	  .driver_info = RSVD(0)},
 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff),
 	  .driver_info = RSVD(3)},
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA_RMNET, 0xff),
+	  .driver_info = RSVD(0) },
 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff),
 	  .driver_info = RSVD(3)},
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB_RMNET, 0xff),
+	  .driver_info = RSVD(0) },
 	{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
 	  .driver_info = RSVD(4) },
 	{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 075/107] usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (73 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 074/107] USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 076/107] usb: typec: intel_pmc_mux: Add new ACPI ID for Meteor Lake IOM device Greg Kroah-Hartman
                   ` (40 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Guillaume Ranquet, Heikki Krogerus,
	Pablo Sun, Macpaul Lin

From: Pablo Sun <pablo.sun@mediatek.com>

commit c1e5c2f0cb8a22ec2e14af92afc7006491bebabb upstream.

Fix incorrect pin assignment values when connecting to a monitor with
Type-C receptacle instead of a plug.

According to specification, an UFP_D receptacle's pin assignment
should came from the UFP_D pin assignments field (bit 23:16), while
an UFP_D plug's assignments are described in the DFP_D pin assignments
(bit 15:8) during Mode Discovery.

For example the LG 27 UL850-W is a monitor with Type-C receptacle.
The monitor responds to MODE DISCOVERY command with following
DisplayPort Capability flag:

        dp->alt->vdo=0x140045

The existing logic only take cares of UPF_D plug case,
and would take the bit 15:8 for this 0x140045 case.

This results in an non-existing pin assignment 0x0 in
dp_altmode_configure.

To fix this problem a new set of macros are introduced
to take plug/receptacle differences into consideration.

Fixes: 0e3bb7d6894d ("usb: typec: Add driver for DisplayPort alternate mode")
Cc: stable@vger.kernel.org
Co-developed-by: Pablo Sun <pablo.sun@mediatek.com>
Co-developed-by: Macpaul Lin <macpaul.lin@mediatek.com>
Reviewed-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Pablo Sun <pablo.sun@mediatek.com>
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
Link: https://lore.kernel.org/r/20220804034803.19486-1-macpaul.lin@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/typec/altmodes/displayport.c |    4 ++--
 include/linux/usb/typec_dp.h             |    5 +++++
 2 files changed, 7 insertions(+), 2 deletions(-)

--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -88,8 +88,8 @@ static int dp_altmode_configure(struct d
 	case DP_STATUS_CON_UFP_D:
 	case DP_STATUS_CON_BOTH: /* NOTE: First acting as DP source */
 		conf |= DP_CONF_UFP_U_AS_UFP_D;
-		pin_assign = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo) &
-			     DP_CAP_UFP_D_PIN_ASSIGN(dp->port->vdo);
+		pin_assign = DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo) &
+				 DP_CAP_PIN_ASSIGN_DFP_D(dp->port->vdo);
 		break;
 	default:
 		break;
--- a/include/linux/usb/typec_dp.h
+++ b/include/linux/usb/typec_dp.h
@@ -73,6 +73,11 @@ enum {
 #define DP_CAP_USB			BIT(7)
 #define DP_CAP_DFP_D_PIN_ASSIGN(_cap_)	(((_cap_) & GENMASK(15, 8)) >> 8)
 #define DP_CAP_UFP_D_PIN_ASSIGN(_cap_)	(((_cap_) & GENMASK(23, 16)) >> 16)
+/* Get pin assignment taking plug & receptacle into consideration */
+#define DP_CAP_PIN_ASSIGN_UFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \
+			DP_CAP_UFP_D_PIN_ASSIGN(_cap_) : DP_CAP_DFP_D_PIN_ASSIGN(_cap_))
+#define DP_CAP_PIN_ASSIGN_DFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \
+			DP_CAP_DFP_D_PIN_ASSIGN(_cap_) : DP_CAP_UFP_D_PIN_ASSIGN(_cap_))
 
 /* DisplayPort Status Update VDO bits */
 #define DP_STATUS_CONNECTION(_status_)	((_status_) & 3)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 076/107] usb: typec: intel_pmc_mux: Add new ACPI ID for Meteor Lake IOM device
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (74 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 075/107] usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 077/107] usb: typec: tcpm: Return ENOTSUPP for power supply prop writes Greg Kroah-Hartman
                   ` (39 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Utkarsh Patel, Heikki Krogerus

From: Utkarsh Patel <utkarsh.h.patel@intel.com>

commit 1b1b672cc1d4fb3065dac79efb8901bd6244ef69 upstream.

This adds the necessary ACPI ID for Intel Meteor Lake
IOM devices.

The callback function is_memory() is modified so that it
also checks if the resource descriptor passed to it is a
memory type "Address Space Resource Descriptor".

On Intel Meteor Lake the ACPI memory resource is not
described using the "32-bit Memory Range Descriptor" because
the memory is outside of the 32-bit address space. The
memory resource is described using the "Address Space
Resource Descriptor" instead.

Intel Meteor Lake is the first platform to describe the
memory resource for this device with Address Space Resource
Descriptor, but it most likely will not be the last.
Therefore the change to the is_memory() callback function
is made generic.

Signed-off-by: Utkarsh Patel <utkarsh.h.patel@intel.com>
Cc: stable@vger.kernel.org
[ heikki: Rewrote the commit message. ]
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20220816101629.69054-2-heikki.krogerus@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/typec/mux/intel_pmc_mux.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

--- a/drivers/usb/typec/mux/intel_pmc_mux.c
+++ b/drivers/usb/typec/mux/intel_pmc_mux.c
@@ -554,9 +554,11 @@ err_unregister_switch:
 
 static int is_memory(struct acpi_resource *res, void *data)
 {
-	struct resource r;
+	struct resource_win win = {};
+	struct resource *r = &win.res;
 
-	return !acpi_dev_resource_memory(res, &r);
+	return !(acpi_dev_resource_memory(res, r) ||
+		 acpi_dev_resource_address_space(res, &win));
 }
 
 /* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */
@@ -566,6 +568,9 @@ static const struct acpi_device_id iom_a
 
 	/* AlderLake */
 	{ "INTC1079", 0x160, },
+
+	/* Meteor Lake */
+	{ "INTC107A", 0x160, },
 	{}
 };
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 077/107] usb: typec: tcpm: Return ENOTSUPP for power supply prop writes
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (75 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 076/107] usb: typec: intel_pmc_mux: Add new ACPI ID for Meteor Lake IOM device Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:30 ` [PATCH 5.15 078/107] usb: dwc2: fix wrong order of phy_power_on and phy_init Greg Kroah-Hartman
                   ` (38 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Heikki Krogerus, Badhri Jagan Sridharan

From: Badhri Jagan Sridharan <badhri@google.com>

commit f2d38edc5e3375e56b4a30d5b66cefd385a2b38c upstream.

When the port does not support USB PD, prevent transition to PD
only states when power supply property is written. In this case,
TCPM transitions to SNK_NEGOTIATE_CAPABILITIES
which should not be the case given that the port is not pd_capable.

[   84.308251] state change SNK_READY -> SNK_NEGOTIATE_CAPABILITIES [rev3 NONE_AMS]
[   84.308335] Setting usb_comm capable false
[   84.323367] set_auto_vbus_discharge_threshold mode:3 pps_active:n vbus:5000 ret:0
[   84.323376] state change SNK_NEGOTIATE_CAPABILITIES -> SNK_WAIT_CAPABILITIES [rev3 NONE_AMS]

Fixes: e9e6e164ed8f6 ("usb: typec: tcpm: Support non-PD mode")
Cc: stable@vger.kernel.org
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
Link: https://lore.kernel.org/r/20220817215410.1807477-1-badhri@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/typec/tcpm/tcpm.c |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -6213,6 +6213,13 @@ static int tcpm_psy_set_prop(struct powe
 	struct tcpm_port *port = power_supply_get_drvdata(psy);
 	int ret;
 
+	/*
+	 * All the properties below are related to USB PD. The check needs to be
+	 * property specific when a non-pd related property is added.
+	 */
+	if (!port->pd_supported)
+		return -EOPNOTSUPP;
+
 	switch (psp) {
 	case POWER_SUPPLY_PROP_ONLINE:
 		ret = tcpm_psy_set_online(port, val);



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 078/107] usb: dwc2: fix wrong order of phy_power_on and phy_init
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (76 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 077/107] usb: typec: tcpm: Return ENOTSUPP for power supply prop writes Greg Kroah-Hartman
@ 2022-09-06 13:30 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 079/107] usb: cdns3: fix issue with rearming ISO OUT endpoint Greg Kroah-Hartman
                   ` (37 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Minas Harutyunyan, Marek Szyprowski,
	Heiner Kallweit

From: Heiner Kallweit <hkallweit1@gmail.com>

commit f9b995b49a07bd0d43b0e490f59be84415c745ae upstream.

Since 1599069a62c6 ("phy: core: Warn when phy_power_on is called before
phy_init") the driver complains. In my case (Amlogic SoC) the warning
is: phy phy-fe03e000.phy.2: phy_power_on was called before phy_init
So change the order of the two calls. The same change has to be done
to the order of phy_exit() and phy_power_off().

Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c")
Cc: stable@vger.kernel.org
Acked-by: Minas Harutyunyan <hminas@synopsys.com>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://lore.kernel.org/r/dfcc6b40-2274-4e86-e73c-5c5e6aa3e046@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc2/platform.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -154,9 +154,9 @@ static int __dwc2_lowlevel_hw_enable(str
 	} else if (hsotg->plat && hsotg->plat->phy_init) {
 		ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
 	} else {
-		ret = phy_power_on(hsotg->phy);
+		ret = phy_init(hsotg->phy);
 		if (ret == 0)
-			ret = phy_init(hsotg->phy);
+			ret = phy_power_on(hsotg->phy);
 	}
 
 	return ret;
@@ -188,9 +188,9 @@ static int __dwc2_lowlevel_hw_disable(st
 	} else if (hsotg->plat && hsotg->plat->phy_exit) {
 		ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
 	} else {
-		ret = phy_exit(hsotg->phy);
+		ret = phy_power_off(hsotg->phy);
 		if (ret == 0)
-			ret = phy_power_off(hsotg->phy);
+			ret = phy_exit(hsotg->phy);
 	}
 	if (ret)
 		return ret;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 079/107] usb: cdns3: fix issue with rearming ISO OUT endpoint
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (77 preceding siblings ...)
  2022-09-06 13:30 ` [PATCH 5.15 078/107] usb: dwc2: fix wrong order of phy_power_on and phy_init Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 080/107] usb: cdns3: fix incorrect handling TRB_SMM flag for ISOC transfer Greg Kroah-Hartman
                   ` (36 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Peter Chen, Pawel Laszczak

From: Pawel Laszczak <pawell@cadence.com>

commit b46a6b09fa056042a302b181a1941f0056944603 upstream.

ISO OUT endpoint is enabled during queuing first usb request
in transfer ring and disabled when TRBERR is reported by controller.
After TRBERR and before next transfer added to TR driver must again
reenable endpoint but does not.
To solve this issue during processing TRBERR event driver must
set the flag EP_UPDATE_EP_TRBADDR in priv_ep->flags field.

Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
cc: <stable@vger.kernel.org>
Acked-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Link: https://lore.kernel.org/r/20220825062137.5766-1-pawell@cadence.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/cdns3/cdns3-gadget.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/usb/cdns3/cdns3-gadget.c
+++ b/drivers/usb/cdns3/cdns3-gadget.c
@@ -1690,6 +1690,7 @@ static int cdns3_check_ep_interrupt_proc
 				ep_cfg &= ~EP_CFG_ENABLE;
 				writel(ep_cfg, &priv_dev->regs->ep_cfg);
 				priv_ep->flags &= ~EP_QUIRK_ISO_OUT_EN;
+				priv_ep->flags |= EP_UPDATE_EP_TRBADDR;
 			}
 			cdns3_transfer_completed(priv_dev, priv_ep);
 		} else if (!(priv_ep->flags & EP_STALLED) &&



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 080/107] usb: cdns3: fix incorrect handling TRB_SMM flag for ISOC transfer
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (78 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 079/107] usb: cdns3: fix issue with rearming ISO OUT endpoint Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 081/107] USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020) Greg Kroah-Hartman
                   ` (35 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Peter Chen, Pawel Laszczak

From: Pawel Laszczak <pawell@cadence.com>

commit d5dcc33677d7415c5f23b3c052f9e80cbab9ea4e upstream.

The TRB_SMM flag indicates that DMA has completed the TD service with
this TRB. Usually it’s a last TRB in TD. In case of ISOC transfer for
bInterval > 1 each ISOC transfer contains more than one TD associated
with usb request (one TD per ITP). In such case the TRB_SMM flag will
be set in every TD and driver will recognize the end of transfer after
processing the first TD with TRB_SMM. In result driver stops updating
request->actual and returns incorrect actual length.
To fix this issue driver additionally must check TRB_CHAIN which is not
used for isochronous transfers.

Fixes: 249f0a25e8be ("usb: cdns3: gadget: handle sg list use case at completion correctly")
cc: <stable@vger.kernel.org>
Acked-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Link: https://lore.kernel.org/r/20220825062207.5824-1-pawell@cadence.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/cdns3/cdns3-gadget.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/usb/cdns3/cdns3-gadget.c
+++ b/drivers/usb/cdns3/cdns3-gadget.c
@@ -1530,7 +1530,8 @@ static void cdns3_transfer_completed(str
 						TRB_LEN(le32_to_cpu(trb->length));
 
 				if (priv_req->num_of_trb > 1 &&
-					le32_to_cpu(trb->control) & TRB_SMM)
+					le32_to_cpu(trb->control) & TRB_SMM &&
+					le32_to_cpu(trb->control) & TRB_CHAIN)
 					transfer_end = true;
 
 				cdns3_ep_inc_deq(priv_ep);



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 081/107] USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020)
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (79 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 080/107] usb: cdns3: fix incorrect handling TRB_SMM flag for ISOC transfer Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 082/107] usb-storage: Add ignore-residue quirk for NXP PN7462AU Greg Kroah-Hartman
                   ` (34 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Thierry GUIBERT, stable

From: Thierry GUIBERT <thierry.guibert@croix-rouge.fr>

commit a10bc71729b236fe36de0d8e4d35c959fd8dec3a upstream.

Supports for ICOM F3400 and ICOM F4400 PMR radios in CDC-ACM driver
enabling the AT serial port.
The Vendor Id is 0x0C26
The Product ID is 0x0020

Output of lsusb :
Bus 001 Device 009: ID 0c26:0020 Prolific Technology Inc. ICOM Radio
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0c26 Prolific Technology Inc.
  idProduct          0x0020
  bcdDevice            0.00
  iManufacturer           1 ICOM Inc.
  iProduct                2 ICOM Radio
  iSerial                 3 *obfuscated*
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0030
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              12
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0

Signed-off-by: Thierry GUIBERT <thierry.guibert@croix-rouge.fr>
Cc: stable <stable@kernel.org>
Link: https://lore.kernel.org/r/20220819081702.84118-1-thierry.guibert@croix-rouge.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/class/cdc-acm.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1814,6 +1814,9 @@ static const struct usb_device_id acm_id
 	{ USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */
 	.driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */
 	},
+	{ USB_DEVICE(0x0c26, 0x0020), /* Icom ICF3400 Serie */
+	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+	},
 	{ USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 082/107] usb-storage: Add ignore-residue quirk for NXP PN7462AU
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (80 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 081/107] USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020) Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 083/107] s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages Greg Kroah-Hartman
                   ` (33 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Alan Stern, stable, Witold Lipieta

From: Witold Lipieta <witold.lipieta@thaumatec.com>

commit 2aa48857ad52236a9564c71183d6cc8893becd41 upstream.

This is USB mass storage primary boot loader for code download on
NXP PN7462AU.

Without the quirk it is impossible to write whole memory at once as
device restarts during the write due to bogus residue values reported.

Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@kernel.org>
Signed-off-by: Witold Lipieta <witold.lipieta@thaumatec.com>
Link: https://lore.kernel.org/r/20220809112911.462776-1-witold.lipieta@thaumatec.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/storage/unusual_devs.h |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -2294,6 +2294,13 @@ UNUSUAL_DEV( 0x1e74, 0x4621, 0x0000, 0x0
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ),
 
+/* Reported by Witold Lipieta <witold.lipieta@thaumatec.com> */
+UNUSUAL_DEV( 0x1fc9, 0x0117, 0x0100, 0x0100,
+		"NXP Semiconductors",
+		"PN7462AU",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Supplied with some Castlewood ORB removable drives */
 UNUSUAL_DEV(  0x2027, 0xa001, 0x0000, 0x9999,
 		"Double-H Technology",



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 083/107] s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (81 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 082/107] usb-storage: Add ignore-residue quirk for NXP PN7462AU Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 084/107] s390: fix nospec table alignments Greg Kroah-Hartman
                   ` (32 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Alexander Gordeev, Gerald Schaefer,
	Vasily Gorbik

From: Gerald Schaefer <gerald.schaefer@linux.ibm.com>

commit 7c8d42fdf1a84b1a0dd60d6528309c8ec127e87c upstream.

The alignment check in prepare_hugepage_range() is wrong for 2 GB
hugepages, it only checks for 1 MB hugepage alignment.

This can result in kernel crash in __unmap_hugepage_range() at the
BUG_ON(start & ~huge_page_mask(h)) alignment check, for mappings
created with MAP_FIXED at unaligned address.

Fix this by correctly handling multiple hugepage sizes, similar to the
generic version of prepare_hugepage_range().

Fixes: d08de8e2d867 ("s390/mm: add support for 2GB hugepages")
Cc: <stable@vger.kernel.org> # 4.8+
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/s390/include/asm/hugetlb.h |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -28,9 +28,11 @@ pte_t huge_ptep_get_and_clear(struct mm_
 static inline int prepare_hugepage_range(struct file *file,
 			unsigned long addr, unsigned long len)
 {
-	if (len & ~HPAGE_MASK)
+	struct hstate *h = hstate_file(file);
+
+	if (len & ~huge_page_mask(h))
 		return -EINVAL;
-	if (addr & ~HPAGE_MASK)
+	if (addr & ~huge_page_mask(h))
 		return -EINVAL;
 	return 0;
 }



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 084/107] s390: fix nospec table alignments
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (82 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 083/107] s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 085/107] USB: core: Prevent nested device-reset calls Greg Kroah-Hartman
                   ` (31 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Josh Poimboeuf, Heiko Carstens,
	Vasily Gorbik

From: Josh Poimboeuf <jpoimboe@kernel.org>

commit c9305b6c1f52060377c72aebe3a701389e9f3172 upstream.

Add proper alignment for .nospec_call_table and .nospec_return_table in
vmlinux.

[hca@linux.ibm.com]: The problem with the missing alignment of the nospec
tables exist since a long time, however only since commit e6ed91fd0768
("s390/alternatives: remove padding generation code") and with
CONFIG_RELOCATABLE=n the kernel may also crash at boot time.

The above named commit reduced the size of struct alt_instr by one byte,
so its new size is 11 bytes. Therefore depending on the number of cpu
alternatives the size of the __alt_instructions array maybe odd, which
again also causes that the addresses of the nospec tables will be odd.

If the address of __nospec_call_start is odd and the kernel is compiled
With CONFIG_RELOCATABLE=n the compiler may generate code that loads the
address of __nospec_call_start with a 'larl' instruction.

This will generate incorrect code since the 'larl' instruction only works
with even addresses. In result the members of the nospec tables will be
accessed with an off-by-one offset, which subsequently may lead to
addressing exceptions within __nospec_revert().

Fixes: f19fbd5ed642 ("s390: introduce execute-trampolines for branches")
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Link: https://lore.kernel.org/r/8719bf1ce4a72ebdeb575200290094e9ce047bcc.1661557333.git.jpoimboe@kernel.org
Cc: <stable@vger.kernel.org> # 4.16
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/s390/kernel/vmlinux.lds.S |    1 +
 1 file changed, 1 insertion(+)

--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -132,6 +132,7 @@ SECTIONS
 	/*
 	 * Table with the patch locations to undo expolines
 	*/
+	. = ALIGN(4);
 	.nospec_call_table : {
 		__nospec_call_start = . ;
 		*(.s390_indirect*)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 085/107] USB: core: Prevent nested device-reset calls
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (83 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 084/107] s390: fix nospec table alignments Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 086/107] usb: xhci-mtk: relax TT periodic bandwidth allocation Greg Kroah-Hartman
                   ` (30 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Alan Stern, Rondreis

From: Alan Stern <stern@rowland.harvard.edu>

commit 9c6d778800b921bde3bff3cff5003d1650f942d1 upstream.

Automatic kernel fuzzing revealed a recursive locking violation in
usb-storage:

============================================
WARNING: possible recursive locking detected
5.18.0 #3 Not tainted
--------------------------------------------
kworker/1:3/1205 is trying to acquire lock:
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230

but task is already holding lock:
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230

...

stack backtrace:
CPU: 1 PID: 1205 Comm: kworker/1:3 Not tainted 5.18.0 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Workqueue: usb_hub_wq hub_event
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_deadlock_bug kernel/locking/lockdep.c:2988 [inline]
check_deadlock kernel/locking/lockdep.c:3031 [inline]
validate_chain kernel/locking/lockdep.c:3816 [inline]
__lock_acquire.cold+0x152/0x3ca kernel/locking/lockdep.c:5053
lock_acquire kernel/locking/lockdep.c:5665 [inline]
lock_acquire+0x1ab/0x520 kernel/locking/lockdep.c:5630
__mutex_lock_common kernel/locking/mutex.c:603 [inline]
__mutex_lock+0x14f/0x1610 kernel/locking/mutex.c:747
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
usb_reset_device+0x37d/0x9a0 drivers/usb/core/hub.c:6109
r871xu_dev_remove+0x21a/0x270 drivers/staging/rtl8712/usb_intf.c:622
usb_unbind_interface+0x1bd/0x890 drivers/usb/core/driver.c:458
device_remove drivers/base/dd.c:545 [inline]
device_remove+0x11f/0x170 drivers/base/dd.c:537
__device_release_driver drivers/base/dd.c:1222 [inline]
device_release_driver_internal+0x1a7/0x2f0 drivers/base/dd.c:1248
usb_driver_release_interface+0x102/0x180 drivers/usb/core/driver.c:627
usb_forced_unbind_intf+0x4d/0xa0 drivers/usb/core/driver.c:1118
usb_reset_device+0x39b/0x9a0 drivers/usb/core/hub.c:6114

This turned out not to be an error in usb-storage but rather a nested
device reset attempt.  That is, as the rtl8712 driver was being
unbound from a composite device in preparation for an unrelated USB
reset (that driver does not have pre_reset or post_reset callbacks),
its ->remove routine called usb_reset_device() -- thus nesting one
reset call within another.

Performing a reset as part of disconnect processing is a questionable
practice at best.  However, the bug report points out that the USB
core does not have any protection against nested resets.  Adding a
reset_in_progress flag and testing it will prevent such errors in the
future.

Link: https://lore.kernel.org/all/CAB7eexKUpvX-JNiLzhXBDWgfg2T9e9_0Tw4HQ6keN==voRbP0g@mail.gmail.com/
Cc: stable@vger.kernel.org
Reported-and-tested-by: Rondreis <linhaoguo86@gmail.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/YwkflDxvg0KWqyZK@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/hub.c |   10 ++++++++++
 include/linux/usb.h    |    2 ++
 2 files changed, 12 insertions(+)

--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -6043,6 +6043,11 @@ re_enumerate_no_bos:
  * the reset is over (using their post_reset method).
  *
  * Return: The same as for usb_reset_and_verify_device().
+ * However, if a reset is already in progress (for instance, if a
+ * driver doesn't have pre_ or post_reset() callbacks, and while
+ * being unbound or re-bound during the ongoing reset its disconnect()
+ * or probe() routine tries to perform a second, nested reset), the
+ * routine returns -EINPROGRESS.
  *
  * Note:
  * The caller must own the device lock.  For example, it's safe to use
@@ -6076,6 +6081,10 @@ int usb_reset_device(struct usb_device *
 		return -EISDIR;
 	}
 
+	if (udev->reset_in_progress)
+		return -EINPROGRESS;
+	udev->reset_in_progress = 1;
+
 	port_dev = hub->ports[udev->portnum - 1];
 
 	/*
@@ -6140,6 +6149,7 @@ int usb_reset_device(struct usb_device *
 
 	usb_autosuspend_device(udev);
 	memalloc_noio_restore(noio_flag);
+	udev->reset_in_progress = 0;
 	return ret;
 }
 EXPORT_SYMBOL_GPL(usb_reset_device);
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -575,6 +575,7 @@ struct usb3_lpm_parameters {
  * @devaddr: device address, XHCI: assigned by HW, others: same as devnum
  * @can_submit: URBs may be submitted
  * @persist_enabled:  USB_PERSIST enabled for this device
+ * @reset_in_progress: the device is being reset
  * @have_langid: whether string_langid is valid
  * @authorized: policy has said we can use it;
  *	(user space) policy determines if we authorize this device to be
@@ -661,6 +662,7 @@ struct usb_device {
 
 	unsigned can_submit:1;
 	unsigned persist_enabled:1;
+	unsigned reset_in_progress:1;
 	unsigned have_langid:1;
 	unsigned authorized:1;
 	unsigned authenticated:1;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 086/107] usb: xhci-mtk: relax TT periodic bandwidth allocation
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (84 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 085/107] USB: core: Prevent nested device-reset calls Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 087/107] usb: xhci-mtk: fix bandwidth release issue Greg Kroah-Hartman
                   ` (29 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Chunfeng Yun, stable

From: Chunfeng Yun <chunfeng.yun@mediatek.com>

commit 8b13ea05117ffad4727b0971ed09122d5c91c4dc upstream.

Currently uses the worst case byte budgets on FS/LS bus bandwidth,
for example, for an isochronos IN endpoint with 192 bytes budget, it
will consume the whole 5 uframes(188 * 5) while the actual FS bus
budget should be just 192 bytes. It cause that many usb audio headsets
with 3 interfaces (audio input, audio output, and HID) cannot be
configured.
To improve it, changes to use "approximate" best case budget for FS/LS
bandwidth management. For the same endpoint from the above example,
the approximate best case budget is now reduced to (188 * 2) bytes.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Cc: stable <stable@kernel.org>
Link: https://lore.kernel.org/r/20220819080556.32215-1-chunfeng.yun@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/xhci-mtk-sch.c |   11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -476,7 +476,6 @@ static int check_fs_bus_bw(struct mu3h_s
 
 static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
 {
-	u32 extra_cs_count;
 	u32 start_ss, last_ss;
 	u32 start_cs, last_cs;
 
@@ -512,18 +511,12 @@ static int check_sch_tt(struct mu3h_sch_
 		if (last_cs > 7)
 			return -ESCH_CS_OVERFLOW;
 
-		if (sch_ep->ep_type == ISOC_IN_EP)
-			extra_cs_count = (last_cs == 7) ? 1 : 2;
-		else /*  ep_type : INTR IN / INTR OUT */
-			extra_cs_count = 1;
-
-		cs_count += extra_cs_count;
 		if (cs_count > 7)
 			cs_count = 7; /* HW limit */
 
 		sch_ep->cs_count = cs_count;
-		/* one for ss, the other for idle */
-		sch_ep->num_budget_microframes = cs_count + 2;
+		/* ss, idle are ignored */
+		sch_ep->num_budget_microframes = cs_count;
 
 		/*
 		 * if interval=1, maxp >752, num_budge_micoframe is larger



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 087/107] usb: xhci-mtk: fix bandwidth release issue
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (85 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 086/107] usb: xhci-mtk: relax TT periodic bandwidth allocation Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 088/107] usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS Greg Kroah-Hartman
                   ` (28 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, stable, Chunfeng Yun

From: Chunfeng Yun <chunfeng.yun@mediatek.com>

commit 6020f480004a80cdad4ae5ee180a231c4f65595b upstream.

This happens when @udev->reset_resume is set to true, when usb resume,
the flow as below:
  - hub_resume
    - usb_disable_interface
      - usb_disable_endpoint
        - usb_hcd_disable_endpoint
          - xhci_endpoint_disable  // it set @ep->hcpriv to NULL

Then when reset usb device, it will drop allocated endpoints,
the flow as below:
  - usb_reset_and_verify_device
    - usb_hcd_alloc_bandwidth
      - xhci_mtk_drop_ep

but @ep->hcpriv is already set to NULL, the bandwidth will be not
released anymore.

Due to the added endponts are stored in hash table, we can drop the check
of @ep->hcpriv.

Fixes: 4ce186665e7c ("usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint")
Cc: stable <stable@kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Link: https://lore.kernel.org/r/20220819080556.32215-2-chunfeng.yun@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/xhci-mtk-sch.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -815,8 +815,8 @@ int xhci_mtk_drop_ep(struct usb_hcd *hcd
 	if (ret)
 		return ret;
 
-	if (ep->hcpriv)
-		drop_ep_quirk(hcd, udev, ep);
+	/* needn't check @ep->hcpriv, xhci_endpoint_disable set it NULL */
+	drop_ep_quirk(hcd, udev, ep);
 
 	return 0;
 }



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 088/107] usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (86 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 087/107] usb: xhci-mtk: fix bandwidth release issue Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 089/107] driver core: Dont probe devices after bus_type.match() probe deferral Greg Kroah-Hartman
                   ` (27 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Alan Stern, Krishna Kurapati

From: Krishna Kurapati <quic_kriskura@quicinc.com>

commit 9d4dc16ec71bd6368548e9743223e449b4377fc7 upstream.

During cdrom emulation, the response to read_toc command must contain
the cdrom address as the number of sectors (2048 byte sized blocks)
represented either as an absolute value (when MSF bit is '0') or in
terms of PMin/PSec/PFrame (when MSF bit is set to '1'). Incase of
cdrom, the fsg_lun_open call sets the sector size to 2048 bytes.

When MAC OS sends a read_toc request with MSF set to '1', the
store_cdrom_address assumes that the address being provided is the
LUN size represented in 512 byte sized blocks instead of 2048. It
tries to modify the address further to convert it to 2048 byte sized
blocks and store it in MSF format. This results in data transfer
failures as the cdrom address being provided in the read_toc response
is incorrect.

Fixes: 3f565a363cee ("usb: gadget: storage: adapt logic block size to bound block devices")
Cc: stable@vger.kernel.org
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
Link: https://lore.kernel.org/r/1661570110-19127-1-git-send-email-quic_kriskura@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/gadget/function/storage_common.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/drivers/usb/gadget/function/storage_common.c
+++ b/drivers/usb/gadget/function/storage_common.c
@@ -294,8 +294,10 @@ EXPORT_SYMBOL_GPL(fsg_lun_fsync_sub);
 void store_cdrom_address(u8 *dest, int msf, u32 addr)
 {
 	if (msf) {
-		/* Convert to Minutes-Seconds-Frames */
-		addr >>= 2;		/* Convert to 2048-byte frames */
+		/*
+		 * Convert to Minutes-Seconds-Frames.
+		 * Sector size is already set to 2048 bytes.
+		 */
 		addr += 2*75;		/* Lead-in occupies 2 seconds */
 		dest[3] = addr % 75;	/* Frames */
 		addr /= 75;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 089/107] driver core: Dont probe devices after bus_type.match() probe deferral
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (87 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 088/107] usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 090/107] wifi: mac80211: Dont finalize CSA in IBSS mode if state is disconnected Greg Kroah-Hartman
                   ` (26 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Saravana Kannan, Guenter Roeck,
	Linus Walleij, Isaac J. Manjarres

From: Isaac J. Manjarres <isaacmanjarres@google.com>

commit 25e9fbf0fd38868a429feabc38abebfc6dbf6542 upstream.

Both __device_attach_driver() and __driver_attach() check the return
code of the bus_type.match() function to see if the device needs to be
added to the deferred probe list. After adding the device to the list,
the logic attempts to bind the device to the driver anyway, as if the
device had matched with the driver, which is not correct.

If __device_attach_driver() detects that the device in question is not
ready to match with a driver on the bus, then it doesn't make sense for
the device to attempt to bind with the current driver or continue
attempting to match with any of the other drivers on the bus. So, update
the logic in __device_attach_driver() to reflect this.

If __driver_attach() detects that a driver tried to match with a device
that is not ready to match yet, then the driver should not attempt to bind
with the device. However, the driver can still attempt to match and bind
with other devices on the bus, as drivers can be bound to multiple
devices. So, update the logic in __driver_attach() to reflect this.

Fixes: 656b8035b0ee ("ARM: 8524/1: driver cohandle -EPROBE_DEFER from bus_type.match()")
Cc: stable@vger.kernel.org
Cc: Saravana Kannan <saravanak@google.com>
Reported-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Isaac J. Manjarres <isaacmanjarres@google.com>
Link: https://lore.kernel.org/r/20220817184026.3468620-1-isaacmanjarres@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/dd.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -877,6 +877,11 @@ static int __device_attach_driver(struct
 		dev_dbg(dev, "Device match requests probe deferral\n");
 		dev->can_match = true;
 		driver_deferred_probe_add(dev);
+		/*
+		 * Device can't match with a driver right now, so don't attempt
+		 * to match or bind with other drivers on the bus.
+		 */
+		return ret;
 	} else if (ret < 0) {
 		dev_dbg(dev, "Bus failed to match device: %d\n", ret);
 		return ret;
@@ -1115,6 +1120,11 @@ static int __driver_attach(struct device
 		dev_dbg(dev, "Device match requests probe deferral\n");
 		dev->can_match = true;
 		driver_deferred_probe_add(dev);
+		/*
+		 * Driver could not match with device, but may match with
+		 * another device on the bus.
+		 */
+		return 0;
 	} else if (ret < 0) {
 		dev_dbg(dev, "Bus failed to match device: %d\n", ret);
 		return ret;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 090/107] wifi: mac80211: Dont finalize CSA in IBSS mode if state is disconnected
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (88 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 089/107] driver core: Dont probe devices after bus_type.match() probe deferral Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 091/107] wifi: mac80211: Fix UAF in ieee80211_scan_rx() Greg Kroah-Hartman
                   ` (25 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, syzbot+b6c9fe29aefe68e4ad34,
	Siddh Raman Pant, Johannes Berg

From: Siddh Raman Pant <code@siddh.me>

commit 15bc8966b6d3a5b9bfe4c9facfa02f2b69b1e5f0 upstream.

When we are not connected to a channel, sending channel "switch"
announcement doesn't make any sense.

The BSS list is empty in that case. This causes the for loop in
cfg80211_get_bss() to be bypassed, so the function returns NULL
(check line 1424 of net/wireless/scan.c), causing the WARN_ON()
in ieee80211_ibss_csa_beacon() to get triggered (check line 500
of net/mac80211/ibss.c), which was consequently reported on the
syzkaller dashboard.

Thus, check if we have an existing connection before generating
the CSA beacon in ieee80211_ibss_finish_csa().

Cc: stable@vger.kernel.org
Fixes: cd7760e62c2a ("mac80211: add support for CSA in IBSS mode")
Link: https://syzkaller.appspot.com/bug?id=05603ef4ae8926761b678d2939a3b2ad28ab9ca6
Reported-by: syzbot+b6c9fe29aefe68e4ad34@syzkaller.appspotmail.com
Signed-off-by: Siddh Raman Pant <code@siddh.me>
Tested-by: syzbot+b6c9fe29aefe68e4ad34@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/20220814151512.9985-1-code@siddh.me
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mac80211/ibss.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -534,6 +534,10 @@ int ieee80211_ibss_finish_csa(struct iee
 
 	sdata_assert_lock(sdata);
 
+	/* When not connected/joined, sending CSA doesn't make sense. */
+	if (ifibss->state != IEEE80211_IBSS_MLME_JOINED)
+		return -ENOLINK;
+
 	/* update cfg80211 bss information with the new channel */
 	if (!is_zero_ether_addr(ifibss->bssid)) {
 		cbss = cfg80211_get_bss(sdata->local->hw.wiphy,



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 091/107] wifi: mac80211: Fix UAF in ieee80211_scan_rx()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (89 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 090/107] wifi: mac80211: Dont finalize CSA in IBSS mode if state is disconnected Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 092/107] ip: fix triggering of icmp redirect Greg Kroah-Hartman
                   ` (24 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, syzbot+f9acff9bf08a845f225d,
	Johannes Berg, Siddh Raman Pant, Johannes Berg

From: Siddh Raman Pant <code@siddh.me>

commit 60deb9f10eec5c6a20252ed36238b55d8b614a2c upstream.

ieee80211_scan_rx() tries to access scan_req->flags after a
null check, but a UAF is observed when the scan is completed
and __ieee80211_scan_completed() executes, which then calls
cfg80211_scan_done() leading to the freeing of scan_req.

Since scan_req is rcu_dereference()'d, prevent the racing in
__ieee80211_scan_completed() by ensuring that from mac80211's
POV it is no longer accessed from an RCU read critical section
before we call cfg80211_scan_done().

Cc: stable@vger.kernel.org
Link: https://syzkaller.appspot.com/bug?extid=f9acff9bf08a845f225d
Reported-by: syzbot+f9acff9bf08a845f225d@syzkaller.appspotmail.com
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Siddh Raman Pant <code@siddh.me>
Link: https://lore.kernel.org/r/20220819200340.34826-1-code@siddh.me
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mac80211/scan.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -461,16 +461,19 @@ static void __ieee80211_scan_completed(s
 	scan_req = rcu_dereference_protected(local->scan_req,
 					     lockdep_is_held(&local->mtx));
 
-	if (scan_req != local->int_scan_req) {
-		local->scan_info.aborted = aborted;
-		cfg80211_scan_done(scan_req, &local->scan_info);
-	}
 	RCU_INIT_POINTER(local->scan_req, NULL);
 	RCU_INIT_POINTER(local->scan_sdata, NULL);
 
 	local->scanning = 0;
 	local->scan_chandef.chan = NULL;
 
+	synchronize_rcu();
+
+	if (scan_req != local->int_scan_req) {
+		local->scan_info.aborted = aborted;
+		cfg80211_scan_done(scan_req, &local->scan_info);
+	}
+
 	/* Set power back to normal operating levels. */
 	ieee80211_hw_config(local, 0);
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 092/107] ip: fix triggering of icmp redirect
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (90 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 091/107] wifi: mac80211: Fix UAF in ieee80211_scan_rx() Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31   ` Greg Kroah-Hartman
                   ` (23 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, kernel test robot, Heng Qi,
	Nicolas Dichtel, David Ahern, Jakub Kicinski

From: Nicolas Dichtel <nicolas.dichtel@6wind.com>

commit eb55dc09b5dd040232d5de32812cc83001a23da6 upstream.

__mkroute_input() uses fib_validate_source() to trigger an icmp redirect.
My understanding is that fib_validate_source() is used to know if the src
address and the gateway address are on the same link. For that,
fib_validate_source() returns 1 (same link) or 0 (not the same network).
__mkroute_input() is the only user of these positive values, all other
callers only look if the returned value is negative.

Since the below patch, fib_validate_source() didn't return anymore 1 when
both addresses are on the same network, because the route lookup returns
RT_SCOPE_LINK instead of RT_SCOPE_HOST. But this is, in fact, right.
Let's adapat the test to return 1 again when both addresses are on the same
link.

CC: stable@vger.kernel.org
Fixes: 747c14307214 ("ip: fix dflt addr selection for connected nexthop")
Reported-by: kernel test robot <yujie.liu@intel.com>
Reported-by: Heng Qi <hengqi@linux.alibaba.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20220829100121.3821-1-nicolas.dichtel@6wind.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/fib_frontend.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -389,7 +389,7 @@ static int __fib_validate_source(struct
 	dev_match = dev_match || (res.type == RTN_LOCAL &&
 				  dev == net->loopback_dev);
 	if (dev_match) {
-		ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_HOST;
+		ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_LINK;
 		return ret;
 	}
 	if (no_addr)
@@ -401,7 +401,7 @@ static int __fib_validate_source(struct
 	ret = 0;
 	if (fib_lookup(net, &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE) == 0) {
 		if (res.type == RTN_UNICAST)
-			ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_HOST;
+			ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_LINK;
 	}
 	return ret;
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 093/107] net: Use u64_stats_fetch_begin_irq() for stats fetch.
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
@ 2022-09-06 13:31   ` Greg Kroah-Hartman
  2022-09-06 13:29 ` [PATCH 5.15 002/107] drm/msm/dp: delete DP_RECOVERED_CLOCK_OUT_EN to fix tps4 Greg Kroah-Hartman
                     ` (114 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, David S. Miller, Catherine Sullivan,
	David Awogbemila, Dimitris Michailidis, Eric Dumazet,
	Hans Ulli Kroll, Jakub Kicinski, Jeroen de Borst, Johannes Berg,
	Linus Walleij, Paolo Abeni, Simon Horman, linux-arm-kernel,
	linux-wireless, netdev, oss-drivers, Sebastian Andrzej Siewior

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

commit 278d3ba61563ceed3cb248383ced19e14ec7bc1f upstream.

On 32bit-UP u64_stats_fetch_begin() disables only preemption. If the
reader is in preemptible context and the writer side
(u64_stats_update_begin*()) runs in an interrupt context (IRQ or
softirq) then the writer can update the stats during the read operation.
This update remains undetected.

Use u64_stats_fetch_begin_irq() to ensure the stats fetch on 32bit-UP
are not interrupted by a writer. 32bit-SMP remains unaffected by this
change.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Catherine Sullivan <csully@google.com>
Cc: David Awogbemila <awogbemila@google.com>
Cc: Dimitris Michailidis <dmichail@fungible.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Jeroen de Borst <jeroendb@google.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <simon.horman@corigine.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: oss-drivers@corigine.com
Cc: stable@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/cortina/gemini.c                |   24 +++++++++----------
 drivers/net/ethernet/google/gve/gve_ethtool.c        |   16 ++++++------
 drivers/net/ethernet/google/gve/gve_main.c           |   12 ++++-----
 drivers/net/ethernet/huawei/hinic/hinic_rx.c         |    4 +--
 drivers/net/ethernet/huawei/hinic/hinic_tx.c         |    4 +--
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c  |    8 +++---
 drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c |    8 +++---
 drivers/net/netdevsim/netdev.c                       |    4 +--
 net/mac80211/sta_info.c                              |    8 +++---
 net/mpls/af_mpls.c                                   |    4 +--
 10 files changed, 46 insertions(+), 46 deletions(-)

--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1920,7 +1920,7 @@ static void gmac_get_stats64(struct net_
 
 	/* Racing with RX NAPI */
 	do {
-		start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
 
 		stats->rx_packets = port->stats.rx_packets;
 		stats->rx_bytes = port->stats.rx_bytes;
@@ -1932,11 +1932,11 @@ static void gmac_get_stats64(struct net_
 		stats->rx_crc_errors = port->stats.rx_crc_errors;
 		stats->rx_frame_errors = port->stats.rx_frame_errors;
 
-	} while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
 
 	/* Racing with MIB and TX completion interrupts */
 	do {
-		start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
 
 		stats->tx_errors = port->stats.tx_errors;
 		stats->tx_packets = port->stats.tx_packets;
@@ -1946,15 +1946,15 @@ static void gmac_get_stats64(struct net_
 		stats->rx_missed_errors = port->stats.rx_missed_errors;
 		stats->rx_fifo_errors = port->stats.rx_fifo_errors;
 
-	} while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
 
 	/* Racing with hard_start_xmit */
 	do {
-		start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
 
 		stats->tx_dropped = port->stats.tx_dropped;
 
-	} while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
 
 	stats->rx_dropped += stats->rx_missed_errors;
 }
@@ -2032,18 +2032,18 @@ static void gmac_get_ethtool_stats(struc
 	/* Racing with MIB interrupt */
 	do {
 		p = values;
-		start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
 
 		for (i = 0; i < RX_STATS_NUM; i++)
 			*p++ = port->hw_stats[i];
 
-	} while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
 	values = p;
 
 	/* Racing with RX NAPI */
 	do {
 		p = values;
-		start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
 
 		for (i = 0; i < RX_STATUS_NUM; i++)
 			*p++ = port->rx_stats[i];
@@ -2051,13 +2051,13 @@ static void gmac_get_ethtool_stats(struc
 			*p++ = port->rx_csum_stats[i];
 		*p++ = port->rx_napi_exits;
 
-	} while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
 	values = p;
 
 	/* Racing with TX start_xmit */
 	do {
 		p = values;
-		start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
 
 		for (i = 0; i < TX_MAX_FRAGS; i++) {
 			*values++ = port->tx_frag_stats[i];
@@ -2066,7 +2066,7 @@ static void gmac_get_ethtool_stats(struc
 		*values++ = port->tx_frags_linearized;
 		*values++ = port->tx_hw_csummed;
 
-	} while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
 }
 
 static int gmac_get_ksettings(struct net_device *netdev,
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -174,14 +174,14 @@ gve_get_ethtool_stats(struct net_device
 				struct gve_rx_ring *rx = &priv->rx[ring];
 
 				start =
-				  u64_stats_fetch_begin(&priv->rx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
 				tmp_rx_pkts = rx->rpackets;
 				tmp_rx_bytes = rx->rbytes;
 				tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
 				tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
 				tmp_rx_desc_err_dropped_pkt =
 					rx->rx_desc_err_dropped_pkt;
-			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
 						       start));
 			rx_pkts += tmp_rx_pkts;
 			rx_bytes += tmp_rx_bytes;
@@ -195,10 +195,10 @@ gve_get_ethtool_stats(struct net_device
 		if (priv->tx) {
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->tx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
 				tmp_tx_pkts = priv->tx[ring].pkt_done;
 				tmp_tx_bytes = priv->tx[ring].bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
 						       start));
 			tx_pkts += tmp_tx_pkts;
 			tx_bytes += tmp_tx_bytes;
@@ -256,13 +256,13 @@ gve_get_ethtool_stats(struct net_device
 			data[i++] = rx->cnt;
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->rx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
 				tmp_rx_bytes = rx->rbytes;
 				tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
 				tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
 				tmp_rx_desc_err_dropped_pkt =
 					rx->rx_desc_err_dropped_pkt;
-			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
 						       start));
 			data[i++] = tmp_rx_bytes;
 			/* rx dropped packets */
@@ -323,9 +323,9 @@ gve_get_ethtool_stats(struct net_device
 			}
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->tx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
 				tmp_tx_bytes = tx->bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
 						       start));
 			data[i++] = tmp_tx_bytes;
 			data[i++] = tx->wake_queue;
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -51,10 +51,10 @@ static void gve_get_stats(struct net_dev
 		for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) {
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->rx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
 				packets = priv->rx[ring].rpackets;
 				bytes = priv->rx[ring].rbytes;
-			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
 						       start));
 			s->rx_packets += packets;
 			s->rx_bytes += bytes;
@@ -64,10 +64,10 @@ static void gve_get_stats(struct net_dev
 		for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->tx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
 				packets = priv->tx[ring].pkt_done;
 				bytes = priv->tx[ring].bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
 						       start));
 			s->tx_packets += packets;
 			s->tx_bytes += bytes;
@@ -1260,9 +1260,9 @@ void gve_handle_report_stats(struct gve_
 			}
 
 			do {
-				start = u64_stats_fetch_begin(&priv->tx[idx].statss);
+				start = u64_stats_fetch_begin_irq(&priv->tx[idx].statss);
 				tx_bytes = priv->tx[idx].bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[idx].statss, start));
+			} while (u64_stats_fetch_retry_irq(&priv->tx[idx].statss, start));
 			stats[stats_idx++] = (struct stats) {
 				.stat_name = cpu_to_be32(TX_WAKE_CNT),
 				.value = cpu_to_be64(priv->tx[idx].wake_queue),
--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
@@ -74,14 +74,14 @@ void hinic_rxq_get_stats(struct hinic_rx
 	unsigned int start;
 
 	do {
-		start = u64_stats_fetch_begin(&rxq_stats->syncp);
+		start = u64_stats_fetch_begin_irq(&rxq_stats->syncp);
 		stats->pkts = rxq_stats->pkts;
 		stats->bytes = rxq_stats->bytes;
 		stats->errors = rxq_stats->csum_errors +
 				rxq_stats->other_errors;
 		stats->csum_errors = rxq_stats->csum_errors;
 		stats->other_errors = rxq_stats->other_errors;
-	} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&rxq_stats->syncp, start));
 }
 
 /**
--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
@@ -98,14 +98,14 @@ void hinic_txq_get_stats(struct hinic_tx
 	unsigned int start;
 
 	do {
-		start = u64_stats_fetch_begin(&txq_stats->syncp);
+		start = u64_stats_fetch_begin_irq(&txq_stats->syncp);
 		stats->pkts    = txq_stats->pkts;
 		stats->bytes   = txq_stats->bytes;
 		stats->tx_busy = txq_stats->tx_busy;
 		stats->tx_wake = txq_stats->tx_wake;
 		stats->tx_dropped = txq_stats->tx_dropped;
 		stats->big_frags_pkts = txq_stats->big_frags_pkts;
-	} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&txq_stats->syncp, start));
 }
 
 /**
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3482,21 +3482,21 @@ static void nfp_net_stat64(struct net_de
 		unsigned int start;
 
 		do {
-			start = u64_stats_fetch_begin(&r_vec->rx_sync);
+			start = u64_stats_fetch_begin_irq(&r_vec->rx_sync);
 			data[0] = r_vec->rx_pkts;
 			data[1] = r_vec->rx_bytes;
 			data[2] = r_vec->rx_drops;
-		} while (u64_stats_fetch_retry(&r_vec->rx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&r_vec->rx_sync, start));
 		stats->rx_packets += data[0];
 		stats->rx_bytes += data[1];
 		stats->rx_dropped += data[2];
 
 		do {
-			start = u64_stats_fetch_begin(&r_vec->tx_sync);
+			start = u64_stats_fetch_begin_irq(&r_vec->tx_sync);
 			data[0] = r_vec->tx_pkts;
 			data[1] = r_vec->tx_bytes;
 			data[2] = r_vec->tx_errors;
-		} while (u64_stats_fetch_retry(&r_vec->tx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&r_vec->tx_sync, start));
 		stats->tx_packets += data[0];
 		stats->tx_bytes += data[1];
 		stats->tx_errors += data[2];
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -483,7 +483,7 @@ static u64 *nfp_vnic_get_sw_stats(struct
 		unsigned int start;
 
 		do {
-			start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
+			start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync);
 			data[0] = nn->r_vecs[i].rx_pkts;
 			tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
 			tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
@@ -491,10 +491,10 @@ static u64 *nfp_vnic_get_sw_stats(struct
 			tmp[3] = nn->r_vecs[i].hw_csum_rx_error;
 			tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail;
 			tmp[5] = nn->r_vecs[i].hw_tls_rx;
-		} while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start));
 
 		do {
-			start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
+			start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync);
 			data[1] = nn->r_vecs[i].tx_pkts;
 			data[2] = nn->r_vecs[i].tx_busy;
 			tmp[6] = nn->r_vecs[i].hw_csum_tx;
@@ -504,7 +504,7 @@ static u64 *nfp_vnic_get_sw_stats(struct
 			tmp[10] = nn->r_vecs[i].hw_tls_tx;
 			tmp[11] = nn->r_vecs[i].tls_tx_fallback;
 			tmp[12] = nn->r_vecs[i].tls_tx_no_fallback;
-		} while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start));
 
 		data += NN_RVEC_PER_Q_STATS;
 
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -67,10 +67,10 @@ nsim_get_stats64(struct net_device *dev,
 	unsigned int start;
 
 	do {
-		start = u64_stats_fetch_begin(&ns->syncp);
+		start = u64_stats_fetch_begin_irq(&ns->syncp);
 		stats->tx_bytes = ns->tx_bytes;
 		stats->tx_packets = ns->tx_packets;
-	} while (u64_stats_fetch_retry(&ns->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&ns->syncp, start));
 }
 
 static int
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2206,9 +2206,9 @@ static inline u64 sta_get_tidstats_msdu(
 	u64 value;
 
 	do {
-		start = u64_stats_fetch_begin(&rxstats->syncp);
+		start = u64_stats_fetch_begin_irq(&rxstats->syncp);
 		value = rxstats->msdu[tid];
-	} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
 
 	return value;
 }
@@ -2272,9 +2272,9 @@ static inline u64 sta_get_stats_bytes(st
 	u64 value;
 
 	do {
-		start = u64_stats_fetch_begin(&rxstats->syncp);
+		start = u64_stats_fetch_begin_irq(&rxstats->syncp);
 		value = rxstats->bytes;
-	} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
 
 	return value;
 }
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1079,9 +1079,9 @@ static void mpls_get_stats(struct mpls_d
 
 		p = per_cpu_ptr(mdev->stats, i);
 		do {
-			start = u64_stats_fetch_begin(&p->syncp);
+			start = u64_stats_fetch_begin_irq(&p->syncp);
 			local = p->stats;
-		} while (u64_stats_fetch_retry(&p->syncp, start));
+		} while (u64_stats_fetch_retry_irq(&p->syncp, start));
 
 		stats->rx_packets	+= local.rx_packets;
 		stats->rx_bytes		+= local.rx_bytes;



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 093/107] net: Use u64_stats_fetch_begin_irq() for stats fetch.
@ 2022-09-06 13:31   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, David S. Miller, Catherine Sullivan,
	David Awogbemila, Dimitris Michailidis, Eric Dumazet,
	Hans Ulli Kroll, Jakub Kicinski, Jeroen de Borst, Johannes Berg,
	Linus Walleij, Paolo Abeni, Simon Horman, linux-arm-kernel,
	linux-wireless, netdev, oss-drivers, Sebastian Andrzej Siewior

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

commit 278d3ba61563ceed3cb248383ced19e14ec7bc1f upstream.

On 32bit-UP u64_stats_fetch_begin() disables only preemption. If the
reader is in preemptible context and the writer side
(u64_stats_update_begin*()) runs in an interrupt context (IRQ or
softirq) then the writer can update the stats during the read operation.
This update remains undetected.

Use u64_stats_fetch_begin_irq() to ensure the stats fetch on 32bit-UP
are not interrupted by a writer. 32bit-SMP remains unaffected by this
change.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Catherine Sullivan <csully@google.com>
Cc: David Awogbemila <awogbemila@google.com>
Cc: Dimitris Michailidis <dmichail@fungible.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Jeroen de Borst <jeroendb@google.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <simon.horman@corigine.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: oss-drivers@corigine.com
Cc: stable@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/cortina/gemini.c                |   24 +++++++++----------
 drivers/net/ethernet/google/gve/gve_ethtool.c        |   16 ++++++------
 drivers/net/ethernet/google/gve/gve_main.c           |   12 ++++-----
 drivers/net/ethernet/huawei/hinic/hinic_rx.c         |    4 +--
 drivers/net/ethernet/huawei/hinic/hinic_tx.c         |    4 +--
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c  |    8 +++---
 drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c |    8 +++---
 drivers/net/netdevsim/netdev.c                       |    4 +--
 net/mac80211/sta_info.c                              |    8 +++---
 net/mpls/af_mpls.c                                   |    4 +--
 10 files changed, 46 insertions(+), 46 deletions(-)

--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1920,7 +1920,7 @@ static void gmac_get_stats64(struct net_
 
 	/* Racing with RX NAPI */
 	do {
-		start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
 
 		stats->rx_packets = port->stats.rx_packets;
 		stats->rx_bytes = port->stats.rx_bytes;
@@ -1932,11 +1932,11 @@ static void gmac_get_stats64(struct net_
 		stats->rx_crc_errors = port->stats.rx_crc_errors;
 		stats->rx_frame_errors = port->stats.rx_frame_errors;
 
-	} while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
 
 	/* Racing with MIB and TX completion interrupts */
 	do {
-		start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
 
 		stats->tx_errors = port->stats.tx_errors;
 		stats->tx_packets = port->stats.tx_packets;
@@ -1946,15 +1946,15 @@ static void gmac_get_stats64(struct net_
 		stats->rx_missed_errors = port->stats.rx_missed_errors;
 		stats->rx_fifo_errors = port->stats.rx_fifo_errors;
 
-	} while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
 
 	/* Racing with hard_start_xmit */
 	do {
-		start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
 
 		stats->tx_dropped = port->stats.tx_dropped;
 
-	} while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
 
 	stats->rx_dropped += stats->rx_missed_errors;
 }
@@ -2032,18 +2032,18 @@ static void gmac_get_ethtool_stats(struc
 	/* Racing with MIB interrupt */
 	do {
 		p = values;
-		start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
 
 		for (i = 0; i < RX_STATS_NUM; i++)
 			*p++ = port->hw_stats[i];
 
-	} while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
 	values = p;
 
 	/* Racing with RX NAPI */
 	do {
 		p = values;
-		start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
 
 		for (i = 0; i < RX_STATUS_NUM; i++)
 			*p++ = port->rx_stats[i];
@@ -2051,13 +2051,13 @@ static void gmac_get_ethtool_stats(struc
 			*p++ = port->rx_csum_stats[i];
 		*p++ = port->rx_napi_exits;
 
-	} while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
 	values = p;
 
 	/* Racing with TX start_xmit */
 	do {
 		p = values;
-		start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+		start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
 
 		for (i = 0; i < TX_MAX_FRAGS; i++) {
 			*values++ = port->tx_frag_stats[i];
@@ -2066,7 +2066,7 @@ static void gmac_get_ethtool_stats(struc
 		*values++ = port->tx_frags_linearized;
 		*values++ = port->tx_hw_csummed;
 
-	} while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+	} while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
 }
 
 static int gmac_get_ksettings(struct net_device *netdev,
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -174,14 +174,14 @@ gve_get_ethtool_stats(struct net_device
 				struct gve_rx_ring *rx = &priv->rx[ring];
 
 				start =
-				  u64_stats_fetch_begin(&priv->rx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
 				tmp_rx_pkts = rx->rpackets;
 				tmp_rx_bytes = rx->rbytes;
 				tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
 				tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
 				tmp_rx_desc_err_dropped_pkt =
 					rx->rx_desc_err_dropped_pkt;
-			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
 						       start));
 			rx_pkts += tmp_rx_pkts;
 			rx_bytes += tmp_rx_bytes;
@@ -195,10 +195,10 @@ gve_get_ethtool_stats(struct net_device
 		if (priv->tx) {
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->tx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
 				tmp_tx_pkts = priv->tx[ring].pkt_done;
 				tmp_tx_bytes = priv->tx[ring].bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
 						       start));
 			tx_pkts += tmp_tx_pkts;
 			tx_bytes += tmp_tx_bytes;
@@ -256,13 +256,13 @@ gve_get_ethtool_stats(struct net_device
 			data[i++] = rx->cnt;
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->rx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
 				tmp_rx_bytes = rx->rbytes;
 				tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
 				tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
 				tmp_rx_desc_err_dropped_pkt =
 					rx->rx_desc_err_dropped_pkt;
-			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
 						       start));
 			data[i++] = tmp_rx_bytes;
 			/* rx dropped packets */
@@ -323,9 +323,9 @@ gve_get_ethtool_stats(struct net_device
 			}
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->tx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
 				tmp_tx_bytes = tx->bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
 						       start));
 			data[i++] = tmp_tx_bytes;
 			data[i++] = tx->wake_queue;
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -51,10 +51,10 @@ static void gve_get_stats(struct net_dev
 		for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) {
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->rx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
 				packets = priv->rx[ring].rpackets;
 				bytes = priv->rx[ring].rbytes;
-			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
 						       start));
 			s->rx_packets += packets;
 			s->rx_bytes += bytes;
@@ -64,10 +64,10 @@ static void gve_get_stats(struct net_dev
 		for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
 			do {
 				start =
-				  u64_stats_fetch_begin(&priv->tx[ring].statss);
+				  u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
 				packets = priv->tx[ring].pkt_done;
 				bytes = priv->tx[ring].bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+			} while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
 						       start));
 			s->tx_packets += packets;
 			s->tx_bytes += bytes;
@@ -1260,9 +1260,9 @@ void gve_handle_report_stats(struct gve_
 			}
 
 			do {
-				start = u64_stats_fetch_begin(&priv->tx[idx].statss);
+				start = u64_stats_fetch_begin_irq(&priv->tx[idx].statss);
 				tx_bytes = priv->tx[idx].bytes_done;
-			} while (u64_stats_fetch_retry(&priv->tx[idx].statss, start));
+			} while (u64_stats_fetch_retry_irq(&priv->tx[idx].statss, start));
 			stats[stats_idx++] = (struct stats) {
 				.stat_name = cpu_to_be32(TX_WAKE_CNT),
 				.value = cpu_to_be64(priv->tx[idx].wake_queue),
--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
@@ -74,14 +74,14 @@ void hinic_rxq_get_stats(struct hinic_rx
 	unsigned int start;
 
 	do {
-		start = u64_stats_fetch_begin(&rxq_stats->syncp);
+		start = u64_stats_fetch_begin_irq(&rxq_stats->syncp);
 		stats->pkts = rxq_stats->pkts;
 		stats->bytes = rxq_stats->bytes;
 		stats->errors = rxq_stats->csum_errors +
 				rxq_stats->other_errors;
 		stats->csum_errors = rxq_stats->csum_errors;
 		stats->other_errors = rxq_stats->other_errors;
-	} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&rxq_stats->syncp, start));
 }
 
 /**
--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
@@ -98,14 +98,14 @@ void hinic_txq_get_stats(struct hinic_tx
 	unsigned int start;
 
 	do {
-		start = u64_stats_fetch_begin(&txq_stats->syncp);
+		start = u64_stats_fetch_begin_irq(&txq_stats->syncp);
 		stats->pkts    = txq_stats->pkts;
 		stats->bytes   = txq_stats->bytes;
 		stats->tx_busy = txq_stats->tx_busy;
 		stats->tx_wake = txq_stats->tx_wake;
 		stats->tx_dropped = txq_stats->tx_dropped;
 		stats->big_frags_pkts = txq_stats->big_frags_pkts;
-	} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&txq_stats->syncp, start));
 }
 
 /**
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3482,21 +3482,21 @@ static void nfp_net_stat64(struct net_de
 		unsigned int start;
 
 		do {
-			start = u64_stats_fetch_begin(&r_vec->rx_sync);
+			start = u64_stats_fetch_begin_irq(&r_vec->rx_sync);
 			data[0] = r_vec->rx_pkts;
 			data[1] = r_vec->rx_bytes;
 			data[2] = r_vec->rx_drops;
-		} while (u64_stats_fetch_retry(&r_vec->rx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&r_vec->rx_sync, start));
 		stats->rx_packets += data[0];
 		stats->rx_bytes += data[1];
 		stats->rx_dropped += data[2];
 
 		do {
-			start = u64_stats_fetch_begin(&r_vec->tx_sync);
+			start = u64_stats_fetch_begin_irq(&r_vec->tx_sync);
 			data[0] = r_vec->tx_pkts;
 			data[1] = r_vec->tx_bytes;
 			data[2] = r_vec->tx_errors;
-		} while (u64_stats_fetch_retry(&r_vec->tx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&r_vec->tx_sync, start));
 		stats->tx_packets += data[0];
 		stats->tx_bytes += data[1];
 		stats->tx_errors += data[2];
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -483,7 +483,7 @@ static u64 *nfp_vnic_get_sw_stats(struct
 		unsigned int start;
 
 		do {
-			start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
+			start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync);
 			data[0] = nn->r_vecs[i].rx_pkts;
 			tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
 			tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
@@ -491,10 +491,10 @@ static u64 *nfp_vnic_get_sw_stats(struct
 			tmp[3] = nn->r_vecs[i].hw_csum_rx_error;
 			tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail;
 			tmp[5] = nn->r_vecs[i].hw_tls_rx;
-		} while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start));
 
 		do {
-			start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
+			start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync);
 			data[1] = nn->r_vecs[i].tx_pkts;
 			data[2] = nn->r_vecs[i].tx_busy;
 			tmp[6] = nn->r_vecs[i].hw_csum_tx;
@@ -504,7 +504,7 @@ static u64 *nfp_vnic_get_sw_stats(struct
 			tmp[10] = nn->r_vecs[i].hw_tls_tx;
 			tmp[11] = nn->r_vecs[i].tls_tx_fallback;
 			tmp[12] = nn->r_vecs[i].tls_tx_no_fallback;
-		} while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
+		} while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start));
 
 		data += NN_RVEC_PER_Q_STATS;
 
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -67,10 +67,10 @@ nsim_get_stats64(struct net_device *dev,
 	unsigned int start;
 
 	do {
-		start = u64_stats_fetch_begin(&ns->syncp);
+		start = u64_stats_fetch_begin_irq(&ns->syncp);
 		stats->tx_bytes = ns->tx_bytes;
 		stats->tx_packets = ns->tx_packets;
-	} while (u64_stats_fetch_retry(&ns->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&ns->syncp, start));
 }
 
 static int
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2206,9 +2206,9 @@ static inline u64 sta_get_tidstats_msdu(
 	u64 value;
 
 	do {
-		start = u64_stats_fetch_begin(&rxstats->syncp);
+		start = u64_stats_fetch_begin_irq(&rxstats->syncp);
 		value = rxstats->msdu[tid];
-	} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
 
 	return value;
 }
@@ -2272,9 +2272,9 @@ static inline u64 sta_get_stats_bytes(st
 	u64 value;
 
 	do {
-		start = u64_stats_fetch_begin(&rxstats->syncp);
+		start = u64_stats_fetch_begin_irq(&rxstats->syncp);
 		value = rxstats->bytes;
-	} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+	} while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
 
 	return value;
 }
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1079,9 +1079,9 @@ static void mpls_get_stats(struct mpls_d
 
 		p = per_cpu_ptr(mdev->stats, i);
 		do {
-			start = u64_stats_fetch_begin(&p->syncp);
+			start = u64_stats_fetch_begin_irq(&p->syncp);
 			local = p->stats;
-		} while (u64_stats_fetch_retry(&p->syncp, start));
+		} while (u64_stats_fetch_retry_irq(&p->syncp, start));
 
 		stats->rx_packets	+= local.rx_packets;
 		stats->rx_bytes		+= local.rx_bytes;



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 094/107] net: mac802154: Fix a condition in the receive path
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (92 preceding siblings ...)
  2022-09-06 13:31   ` Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 095/107] ALSA: hda/realtek: Add speaker AMP init for Samsung laptops with ALC298 Greg Kroah-Hartman
                   ` (21 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Miquel Raynal, Stefan Schmidt

From: Miquel Raynal <miquel.raynal@bootlin.com>

commit f0da47118c7e93cdbbc6fb403dd729a5f2c90ee3 upstream.

Upon reception, a packet must be categorized, either it's destination is
the host, or it is another host. A packet with no destination addressing
fields may be valid in two situations:
- the packet has no source field: only ACKs are built like that, we
  consider the host as the destination.
- the packet has a valid source field: it is directed to the PAN
  coordinator, as for know we don't have this information we consider we
  are not the PAN coordinator.

There was likely a copy/paste error made during a previous cleanup
because the if clause is now containing exactly the same condition as in
the switch case, which can never be true. In the past the destination
address was used in the switch and the source address was used in the
if, which matches what the spec says.

Cc: stable@vger.kernel.org
Fixes: ae531b9475f6 ("ieee802154: use ieee802154_addr instead of *_sa variants")
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20220826142954.254853-1-miquel.raynal@bootlin.com
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mac802154/rx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -44,7 +44,7 @@ ieee802154_subif_frame(struct ieee802154
 
 	switch (mac_cb(skb)->dest.mode) {
 	case IEEE802154_ADDR_NONE:
-		if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE)
+		if (hdr->source.mode != IEEE802154_ADDR_NONE)
 			/* FIXME: check if we are PAN coordinator */
 			skb->pkt_type = PACKET_OTHERHOST;
 		else



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 095/107] ALSA: hda/realtek: Add speaker AMP init for Samsung laptops with ALC298
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (93 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 094/107] net: mac802154: Fix a condition in the receive path Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 096/107] ALSA: seq: oss: Fix data-race for max_midi_devs access Greg Kroah-Hartman
                   ` (20 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Kacper Michajłow, Takashi Iwai

From: Kacper Michajłow <kasper93@gmail.com>

commit a2d57ebec1e15f0ac256eb8397e82b07adfaaacc upstream.

Magic initialization sequence was extracted from Windows driver and
cleaned up manually.

Fixes internal speakers output.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=207423
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1851518
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220827203328.30363-1-kasper93@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/pci/hda/patch_realtek.c |   63 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 7 deletions(-)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4684,6 +4684,48 @@ static void alc236_fixup_hp_mute_led_mic
 	alc236_fixup_hp_micmute_led_vref(codec, fix, action);
 }
 
+static inline void alc298_samsung_write_coef_pack(struct hda_codec *codec,
+						  const unsigned short coefs[2])
+{
+	alc_write_coef_idx(codec, 0x23, coefs[0]);
+	alc_write_coef_idx(codec, 0x25, coefs[1]);
+	alc_write_coef_idx(codec, 0x26, 0xb011);
+}
+
+struct alc298_samsung_amp_desc {
+	unsigned char nid;
+	unsigned short init_seq[2][2];
+};
+
+static void alc298_fixup_samsung_amp(struct hda_codec *codec,
+				     const struct hda_fixup *fix, int action)
+{
+	int i, j;
+	static const unsigned short init_seq[][2] = {
+		{ 0x19, 0x00 }, { 0x20, 0xc0 }, { 0x22, 0x44 }, { 0x23, 0x08 },
+		{ 0x24, 0x85 }, { 0x25, 0x41 }, { 0x35, 0x40 }, { 0x36, 0x01 },
+		{ 0x38, 0x81 }, { 0x3a, 0x03 }, { 0x3b, 0x81 }, { 0x40, 0x3e },
+		{ 0x41, 0x07 }, { 0x400, 0x1 }
+	};
+	static const struct alc298_samsung_amp_desc amps[] = {
+		{ 0x3a, { { 0x18, 0x1 }, { 0x26, 0x0 } } },
+		{ 0x39, { { 0x18, 0x2 }, { 0x26, 0x1 } } }
+	};
+
+	if (action != HDA_FIXUP_ACT_INIT)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(amps); i++) {
+		alc_write_coef_idx(codec, 0x22, amps[i].nid);
+
+		for (j = 0; j < ARRAY_SIZE(amps[i].init_seq); j++)
+			alc298_samsung_write_coef_pack(codec, amps[i].init_seq[j]);
+
+		for (j = 0; j < ARRAY_SIZE(init_seq); j++)
+			alc298_samsung_write_coef_pack(codec, init_seq[j]);
+	}
+}
+
 #if IS_REACHABLE(CONFIG_INPUT)
 static void gpio2_mic_hotkey_event(struct hda_codec *codec,
 				   struct hda_jack_callback *event)
@@ -6842,6 +6884,7 @@ enum {
 	ALC236_FIXUP_HP_GPIO_LED,
 	ALC236_FIXUP_HP_MUTE_LED,
 	ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF,
+	ALC298_FIXUP_SAMSUNG_AMP,
 	ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
 	ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
 	ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
@@ -8196,6 +8239,12 @@ static const struct hda_fixup alc269_fix
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc236_fixup_hp_mute_led_micmute_vref,
 	},
+	[ALC298_FIXUP_SAMSUNG_AMP] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc298_fixup_samsung_amp,
+		.chained = true,
+		.chain_id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET
+	},
 	[ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
 		.type = HDA_FIXUP_VERBS,
 		.v.verbs = (const struct hda_verb[]) {
@@ -8985,13 +9034,13 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
 	SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
 	SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
-	SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
-	SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
-	SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
-	SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
+	SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
+	SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP),
+	SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP),
+	SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
 	SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
-	SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
-	SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
+	SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP),
+	SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP),
 	SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
 	SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
@@ -9351,7 +9400,7 @@ static const struct hda_model_fixup alc2
 	{.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
 	{.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
 	{.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
-	{.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"},
+	{.id = ALC298_FIXUP_SAMSUNG_AMP, .name = "alc298-samsung-amp"},
 	{.id = ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc256-samsung-headphone"},
 	{.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"},
 	{.id = ALC274_FIXUP_HP_MIC, .name = "alc274-hp-mic-detect"},



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 096/107] ALSA: seq: oss: Fix data-race for max_midi_devs access
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (94 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 095/107] ALSA: hda/realtek: Add speaker AMP init for Samsung laptops with ALC298 Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 097/107] ALSA: seq: Fix data-race at module auto-loading Greg Kroah-Hartman
                   ` (19 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Abhishek Shah, Takashi Iwai

From: Takashi Iwai <tiwai@suse.de>

commit 22dec134dbfa825b963f8a1807ad19b943e46a56 upstream.

ALSA OSS sequencer refers to a global variable max_midi_devs at
creating a new port, storing it to its own field.  Meanwhile this
variable may be changed by other sequencer events at
snd_seq_oss_midi_check_exit_port() in parallel, which may cause a data
race.

OTOH, this data race itself is almost harmless, as the access to the
MIDI device is done via get_mdev() and it's protected with a refcount,
hence its presence is guaranteed.

Though, it's sill better to address the data-race from the code sanity
POV, and this patch adds the proper spinlock for the protection.

Reported-by: Abhishek Shah <abhishek.shah@columbia.edu>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/CAEHB2493pZRXs863w58QWnUTtv3HHfg85aYhLn5HJHCwxqtHQg@mail.gmail.com
Link: https://lore.kernel.org/r/20220823072717.1706-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/core/seq/oss/seq_oss_midi.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -270,7 +270,9 @@ snd_seq_oss_midi_clear_all(void)
 void
 snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp)
 {
+	spin_lock_irq(&register_lock);
 	dp->max_mididev = max_midi_devs;
+	spin_unlock_irq(&register_lock);
 }
 
 /*



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 097/107] ALSA: seq: Fix data-race at module auto-loading
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (95 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 096/107] ALSA: seq: oss: Fix data-race for max_midi_devs access Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 098/107] drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk Greg Kroah-Hartman
                   ` (18 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Abhishek Shah, Takashi Iwai

From: Takashi Iwai <tiwai@suse.de>

commit 3e7e04b747adea36f349715d9f0998eeebf15d72 upstream.

It's been reported that there is a possible data-race accessing to the
global card_requested[] array at ALSA sequencer core, which is used
for determining whether to call request_module() for the card or not.
This data race itself is almost harmless, as it might end up with one
extra request_module() call for the already loaded module at most.
But it's still better to fix.

This patch addresses the possible data race of card_requested[] and
client_requested[] arrays by replacing them with bitmask.
It's an atomic operation and can work without locks.

Reported-by: Abhishek Shah <abhishek.shah@columbia.edu>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/CAEHB24_ay6YzARpA1zgCsE7=H9CSJJzux618E=Ka4h0YdKn=qA@mail.gmail.com
Link: https://lore.kernel.org/r/20220823072717.1706-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/core/seq/seq_clientmgr.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -121,13 +121,13 @@ struct snd_seq_client *snd_seq_client_us
 	spin_unlock_irqrestore(&clients_lock, flags);
 #ifdef CONFIG_MODULES
 	if (!in_interrupt()) {
-		static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
-		static char card_requested[SNDRV_CARDS];
+		static DECLARE_BITMAP(client_requested, SNDRV_SEQ_GLOBAL_CLIENTS);
+		static DECLARE_BITMAP(card_requested, SNDRV_CARDS);
+
 		if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
 			int idx;
 			
-			if (!client_requested[clientid]) {
-				client_requested[clientid] = 1;
+			if (!test_and_set_bit(clientid, client_requested)) {
 				for (idx = 0; idx < 15; idx++) {
 					if (seq_client_load[idx] < 0)
 						break;
@@ -142,10 +142,8 @@ struct snd_seq_client *snd_seq_client_us
 			int card = (clientid - SNDRV_SEQ_GLOBAL_CLIENTS) /
 				SNDRV_SEQ_CLIENTS_PER_CARD;
 			if (card < snd_ecards_limit) {
-				if (! card_requested[card]) {
-					card_requested[card] = 1;
+				if (!test_and_set_bit(card, card_requested))
 					snd_request_card(card);
-				}
 				snd_seq_device_load_drivers();
 			}
 		}



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 098/107] drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (96 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 097/107] ALSA: seq: Fix data-race at module auto-loading Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 099/107] drm/i915: Skip wm/ddb readout for disabled pipes Greg Kroah-Hartman
                   ` (17 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Diego Santa Cruz,
	Ville Syrjälä,
	Jani Nikula, Rodrigo Vivi

From: Diego Santa Cruz <Diego.SantaCruz@spinetix.com>

commit 919bef7a106ade2bda73681bbc2f3678198f44fc upstream.

The quirk added in upstream commit 90c3e2198777 ("drm/i915/glk: Add
Quirk for GLK NUC HDMI port issues.") is also required on the ECS Liva
Q2.

Note: Would be nicer to figure out the extra delay required for the
retimer without quirks, however don't know how to check for that.

Cc: stable@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/1326
Signed-off-by: Diego Santa Cruz <Diego.SantaCruz@spinetix.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220616124137.3184371-1-jani.nikula@intel.com
(cherry picked from commit 08e9505fa8f9aa00072a47b6f234d89b6b27a89c)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/i915/display/intel_quirks.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -190,6 +190,9 @@ static struct intel_quirk intel_quirks[]
 	/* ASRock ITX*/
 	{ 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time },
 	{ 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time },
+	/* ECS Liva Q2 */
+	{ 0x3185, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
+	{ 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
 };
 
 void intel_init_quirks(struct drm_i915_private *i915)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 099/107] drm/i915: Skip wm/ddb readout for disabled pipes
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (97 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 098/107] drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 100/107] tty: n_gsm: add sanity check for gsm->receive in gsm_receive_buf() Greg Kroah-Hartman
                   ` (16 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Ville Syrjälä,
	Stanislav Lisovskiy, Rodrigo Vivi

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

commit 0211c2a0ea600e25db3044daaeff4fe41c3ed6d9 upstream.

The stuff programmed into the wm/ddb registers of planes
on disabled pipes doesn't matter. So during readout just
leave our software state tracking for those zeroed.

This should avoid us trying too hard to clean up after
whatever mess the VBIOS/GOP left in there. The actual
hardware state will get cleaned up if/when we enable
the pipe anyway.

Cc: stable@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5711
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220617195948.24007-1-ville.syrjala@linux.intel.com
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
(cherry picked from commit b183db8f4783ca2efc9b47734f15aad9477a108a)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/i915/intel_pm.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6638,7 +6638,10 @@ void skl_wm_get_hw_state(struct drm_i915
 		enum plane_id plane_id;
 		u8 slices;
 
-		skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
+		memset(&crtc_state->wm.skl.optimal, 0,
+		       sizeof(crtc_state->wm.skl.optimal));
+		if (crtc_state->hw.active)
+			skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
 		crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
 
 		memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe]));
@@ -6649,6 +6652,9 @@ void skl_wm_get_hw_state(struct drm_i915
 			struct skl_ddb_entry *ddb_uv =
 				&crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
+			if (!crtc_state->hw.active)
+				continue;
+
 			skl_ddb_get_hw_plane_state(dev_priv, crtc->pipe,
 						   plane_id, ddb_y, ddb_uv);
 



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 100/107] tty: n_gsm: add sanity check for gsm->receive in gsm_receive_buf()
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (98 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 099/107] drm/i915: Skip wm/ddb readout for disabled pipes Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules Greg Kroah-Hartman
                   ` (15 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, stable, Mazin Al Haddad,
	syzbot+e3563f0c94e188366dbb

From: Mazin Al Haddad <mazinalhaddad05@gmail.com>

commit f16c6d2e58a4c2b972efcf9eb12390ee0ba3befb upstream.

A null pointer dereference can happen when attempting to access the
"gsm->receive()" function in gsmld_receive_buf(). Currently, the code
assumes that gsm->recieve is only called after MUX activation.
Since the gsmld_receive_buf() function can be accessed without the need to
initialize the MUX, the gsm->receive() function will not be set and a
NULL pointer dereference will occur.

Fix this by avoiding the call to "gsm->receive()" in case the function is
not initialized by adding a sanity check.

Call Trace:
 <TASK>
 gsmld_receive_buf+0x1c2/0x2f0 drivers/tty/n_gsm.c:2861
 tiocsti drivers/tty/tty_io.c:2293 [inline]
 tty_ioctl+0xa75/0x15d0 drivers/tty/tty_io.c:2692
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:870 [inline]
 __se_sys_ioctl fs/ioctl.c:856 [inline]
 __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:856
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

Link: https://syzkaller.appspot.com/bug?id=bdf035c61447f8c6e0e6920315d577cb5cc35ac5
Fixes: 01aecd917114 ("tty: n_gsm: fix tty registration before control channel open")
Cc: stable <stable@kernel.org>
Reported-and-tested-by: syzbot+e3563f0c94e188366dbb@syzkaller.appspotmail.com
Signed-off-by: Mazin Al Haddad <mazinalhaddad05@gmail.com>
Link: https://lore.kernel.org/r/20220814015211.84180-1-mazinalhaddad05@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/tty/n_gsm.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2753,7 +2753,8 @@ static void gsmld_receive_buf(struct tty
 			flags = *fp++;
 		switch (flags) {
 		case TTY_NORMAL:
-			gsm->receive(gsm, *cp);
+			if (gsm->receive)
+				gsm->receive(gsm, *cp);
 			break;
 		case TTY_OVERRUN:
 		case TTY_BREAK:



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (99 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 100/107] tty: n_gsm: add sanity check for gsm->receive in gsm_receive_buf() Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 18:45   ` Florian Fainelli
  2022-09-06 13:31 ` [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole Greg Kroah-Hartman
                   ` (14 subsequent siblings)
  115 siblings, 1 reply; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: Greg Kroah-Hartman, Jiri Olsa, Andrii Nakryiko

From: Jiri Olsa <jolsa@redhat.com>

commit e27f05147bff21408c1b8410ad8e90cd286e7952 upstream.

Using new PAHOLE_FLAGS variable to pass extra arguments to
pahole for both vmlinux and modules BTF data generation.

Adding new scripts/pahole-flags.sh script that detect and
prints pahole options.

[ fixed issues found by kernel test robot ]

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20211029125729.70002-1-jolsa@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Makefile                  |    3 +++
 scripts/Makefile.modfinal |    2 +-
 scripts/link-vmlinux.sh   |   11 +----------
 scripts/pahole-flags.sh   |   20 ++++++++++++++++++++
 4 files changed, 25 insertions(+), 11 deletions(-)
 create mode 100755 scripts/pahole-flags.sh

--- a/Makefile
+++ b/Makefile
@@ -480,6 +480,8 @@ LZ4		= lz4c
 XZ		= xz
 ZSTD		= zstd
 
+PAHOLE_FLAGS	= $(shell PAHOLE=$(PAHOLE) $(srctree)/scripts/pahole-flags.sh)
+
 CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
 		  -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
 NOSTDINC_FLAGS :=
@@ -534,6 +536,7 @@ export KBUILD_CFLAGS CFLAGS_KERNEL CFLAG
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
+export PAHOLE_FLAGS
 
 # Files to ignore in find ... statements
 
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -40,7 +40,7 @@ quiet_cmd_ld_ko_o = LD [M]  $@
 quiet_cmd_btf_ko = BTF [M] $@
       cmd_btf_ko = 							\
 	if [ -f vmlinux ]; then						\
-		LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J --btf_base vmlinux $@; \
+		LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \
 	else								\
 		printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
 	fi;
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -211,7 +211,6 @@ vmlinux_link()
 gen_btf()
 {
 	local pahole_ver
-	local extra_paholeopt=
 
 	if ! [ -x "$(command -v ${PAHOLE})" ]; then
 		echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
@@ -226,16 +225,8 @@ gen_btf()
 
 	vmlinux_link ${1}
 
-	if [ "${pahole_ver}" -ge "118" ] && [ "${pahole_ver}" -le "121" ]; then
-		# pahole 1.18 through 1.21 can't handle zero-sized per-CPU vars
-		extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_vars"
-	fi
-	if [ "${pahole_ver}" -ge "121" ]; then
-		extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
-	fi
-
 	info "BTF" ${2}
-	LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${extra_paholeopt} ${1}
+	LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
 
 	# Create ${2} which contains just .BTF section but no symbols. Add
 	# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
--- /dev/null
+++ b/scripts/pahole-flags.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+extra_paholeopt=
+
+if ! [ -x "$(command -v ${PAHOLE})" ]; then
+	exit 0
+fi
+
+pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
+
+if [ "${pahole_ver}" -ge "118" ] && [ "${pahole_ver}" -le "121" ]; then
+	# pahole 1.18 through 1.21 can't handle zero-sized per-CPU vars
+	extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_vars"
+fi
+if [ "${pahole_ver}" -ge "121" ]; then
+	extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
+fi
+
+echo ${extra_paholeopt}



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (100 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-16 10:21   ` Thorsten Leemhuis
  2022-09-06 13:31 ` [PATCH 5.15 103/107] usb: dwc3: fix PHY disable sequence Greg Kroah-Hartman
                   ` (13 subsequent siblings)
  115 siblings, 1 reply; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Greg Kroah-Hartman, Martin Rodriguez Reboredo, Jiri Olsa

From: Martin Rodriguez Reboredo <yakoyoku@gmail.com>

New pahole (version 1.24) generates by default new BTF_KIND_ENUM64 BTF tag,
which is not supported by stable kernel.

As a result the kernel with CONFIG_DEBUG_INFO_BTF option will fail to
compile with following error:

  BTFIDS  vmlinux
FAILED: load BTF from vmlinux: Invalid argument

New pahole provides --skip_encoding_btf_enum64 option to skip BTF_KIND_ENUM64
generation and produce BTF supported by stable kernel.

Adding this option to scripts/pahole-flags.sh.

This change does not have equivalent commit in linus tree, because linus tree
has support for BTF_KIND_ENUM64 tag, so it does not need to be disabled.

Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 scripts/pahole-flags.sh |    4 ++++
 1 file changed, 4 insertions(+)

--- a/scripts/pahole-flags.sh
+++ b/scripts/pahole-flags.sh
@@ -17,4 +17,8 @@ if [ "${pahole_ver}" -ge "121" ]; then
 	extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
 fi
 
+if [ "${pahole_ver}" -ge "124" ]; then
+	extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_enum64"
+fi
+
 echo ${extra_paholeopt}



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 103/107] usb: dwc3: fix PHY disable sequence
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (101 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 104/107] usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup Greg Kroah-Hartman
                   ` (12 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Andrew Halaney, Matthias Kaehlcke,
	Manivannan Sadhasivam, Johan Hovold

From: Johan Hovold <johan+linaro@kernel.org>

commit d2ac7bef95c9ead307801ccb6cb6dfbeb14247bf upstream.

Generic PHYs must be powered-off before they can be tore down.

Similarly, suspending legacy PHYs after having powered them off makes no
sense.

Fix the dwc3_core_exit() (e.g. called during suspend) and open-coded
dwc3_probe() error-path sequences that got this wrong.

Note that this makes dwc3_core_exit() match the dwc3_core_init() error
path with respect to powering off the PHYs.

Fixes: 03c1fd622f72 ("usb: dwc3: core: add phy cleanup for probe error handling")
Fixes: c499ff71ff2a ("usb: dwc3: core: re-factor init and exit paths")
Cc: stable@vger.kernel.org      # 4.8
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20220804151001.23612-2-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ johan: adjust context to 5.15 ]
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/core.c |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -731,15 +731,16 @@ static void dwc3_core_exit(struct dwc3 *
 {
 	dwc3_event_buffers_cleanup(dwc);
 
+	usb_phy_set_suspend(dwc->usb2_phy, 1);
+	usb_phy_set_suspend(dwc->usb3_phy, 1);
+	phy_power_off(dwc->usb2_generic_phy);
+	phy_power_off(dwc->usb3_generic_phy);
+
 	usb_phy_shutdown(dwc->usb2_phy);
 	usb_phy_shutdown(dwc->usb3_phy);
 	phy_exit(dwc->usb2_generic_phy);
 	phy_exit(dwc->usb3_generic_phy);
 
-	usb_phy_set_suspend(dwc->usb2_phy, 1);
-	usb_phy_set_suspend(dwc->usb3_phy, 1);
-	phy_power_off(dwc->usb2_generic_phy);
-	phy_power_off(dwc->usb3_generic_phy);
 	clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks);
 	reset_control_assert(dwc->reset);
 }
@@ -1662,16 +1663,16 @@ err5:
 	dwc3_debugfs_exit(dwc);
 	dwc3_event_buffers_cleanup(dwc);
 
-	usb_phy_shutdown(dwc->usb2_phy);
-	usb_phy_shutdown(dwc->usb3_phy);
-	phy_exit(dwc->usb2_generic_phy);
-	phy_exit(dwc->usb3_generic_phy);
-
 	usb_phy_set_suspend(dwc->usb2_phy, 1);
 	usb_phy_set_suspend(dwc->usb3_phy, 1);
 	phy_power_off(dwc->usb2_generic_phy);
 	phy_power_off(dwc->usb3_generic_phy);
 
+	usb_phy_shutdown(dwc->usb2_phy);
+	usb_phy_shutdown(dwc->usb3_phy);
+	phy_exit(dwc->usb2_generic_phy);
+	phy_exit(dwc->usb3_generic_phy);
+
 	dwc3_ulpi_exit(dwc);
 
 err4:



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 104/107] usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (102 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 103/107] usb: dwc3: fix PHY disable sequence Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 105/107] usb: dwc3: disable USB core PHY management Greg Kroah-Hartman
                   ` (11 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Matthias Kaehlcke,
	Manivannan Sadhasivam, Johan Hovold

From: Johan Hovold <johan+linaro@kernel.org>

commit  a872ab303d5ddd4c965f9cd868677781a33ce35a upstream.

The Qualcomm dwc3 runtime-PM implementation checks the xhci
platform-device pointer in the wakeup-interrupt handler to determine
whether the controller is in host mode and if so triggers a resume.

After a role switch in OTG mode the xhci platform-device would have been
freed and the next wakeup from runtime suspend would access the freed
memory.

Note that role switching is executed from a freezable workqueue, which
guarantees that the pointer is stable during suspend.

Also note that runtime PM has been broken since commit 2664deb09306
("usb: dwc3: qcom: Honor wakeup enabled/disabled state"), which
incidentally also prevents this issue from being triggered.

Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver")
Cc: stable@vger.kernel.org      # 4.18
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20220804151001.23612-5-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ johan: adjust context for 5.15 ]
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/dwc3-qcom.c |   14 +++++++++++++-
 drivers/usb/dwc3/host.c      |    1 +
 2 files changed, 14 insertions(+), 1 deletion(-)

--- a/drivers/usb/dwc3/dwc3-qcom.c
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -296,6 +296,14 @@ static void dwc3_qcom_interconnect_exit(
 	icc_put(qcom->icc_path_apps);
 }
 
+/* Only usable in contexts where the role can not change. */
+static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
+{
+	struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
+
+	return dwc->xhci;
+}
+
 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
 {
 	if (qcom->hs_phy_irq) {
@@ -411,7 +419,11 @@ static irqreturn_t qcom_dwc3_resume_irq(
 	if (qcom->pm_suspended)
 		return IRQ_HANDLED;
 
-	if (dwc->xhci)
+	/*
+	 * This is safe as role switching is done from a freezable workqueue
+	 * and the wakeup interrupts are disabled as part of resume.
+	 */
+	if (dwc3_qcom_is_host(qcom))
 		pm_runtime_resume(&dwc->xhci->dev);
 
 	return IRQ_HANDLED;
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -130,4 +130,5 @@ err:
 void dwc3_host_exit(struct dwc3 *dwc)
 {
 	platform_device_unregister(dwc->xhci);
+	dwc->xhci = NULL;
 }



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 105/107] usb: dwc3: disable USB core PHY management
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (103 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 104/107] usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 106/107] USB: serial: ch341: fix lost character on LCR updates Greg Kroah-Hartman
                   ` (10 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Matthias Kaehlcke, stable, Johan Hovold

From: Johan Hovold <johan+linaro@kernel.org>

commit 6000b8d900cd5f52fbcd0776d0cc396e88c8c2ea upstream.

The dwc3 driver manages its PHYs itself so the USB core PHY management
needs to be disabled.

Use the struct xhci_plat_priv hack added by commits 46034a999c07 ("usb:
host: xhci-plat: add platform data support") and f768e718911e ("usb:
host: xhci-plat: add priv quirk for skip PHY initialization") to
propagate the setting for now.

Fixes: 4e88d4c08301 ("usb: add a flag to skip PHY initialization to struct usb_hcd")
Fixes: 178a0bce05cb ("usb: core: hcd: integrate the PHY wrapper into the HCD core")
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Cc: stable <stable@kernel.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20220825131836.19769-1-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ johan: adjust context to 5.15 ]
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/host.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -10,8 +10,13 @@
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
 
+#include "../host/xhci-plat.h"
 #include "core.h"
 
+static const struct xhci_plat_priv dwc3_xhci_plat_priv = {
+	.quirks = XHCI_SKIP_PHY_INIT,
+};
+
 static int dwc3_host_get_irq(struct dwc3 *dwc)
 {
 	struct platform_device	*dwc3_pdev = to_platform_device(dwc->dev);
@@ -87,6 +92,11 @@ int dwc3_host_init(struct dwc3 *dwc)
 		goto err;
 	}
 
+	ret = platform_device_add_data(xhci, &dwc3_xhci_plat_priv,
+					sizeof(dwc3_xhci_plat_priv));
+	if (ret)
+		goto err;
+
 	memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
 
 	if (dwc->usb3_lpm_capable)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 106/107] USB: serial: ch341: fix lost character on LCR updates
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (104 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 105/107] usb: dwc3: disable USB core PHY management Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 13:31 ` [PATCH 5.15 107/107] USB: serial: ch341: fix disabled rx timer on older devices Greg Kroah-Hartman
                   ` (9 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Jonathan Woithe, Johan Hovold

From: Johan Hovold <johan@kernel.org>

commit 8e83622ae7ca481c76c8fd9579877f6abae64ca2 upstream.

Disable LCR updates for pre-0x30 devices which use a different (unknown)
protocol for line control and where the current register write causes
the next received character to be lost.

Note that updating LCR using the INIT command has no effect on these
devices either.

Reported-by: Jonathan Woithe <jwoithe@just42.net>
Tested-by: Jonathan Woithe <jwoithe@just42.net>
Link: https://lore.kernel.org/r/Ys1iPTfiZRWj2gXs@marvin.atrad.com.au
Fixes: 4e46c410e050 ("USB: serial: ch341: reinitialize chip on reconfiguration")
Fixes: 55fa15b5987d ("USB: serial: ch341: fix baud rate and line-control handling")
Cc: stable@vger.kernel.org      # 4.10
Signed-off-by: Johan Hovold <johan@kernel.org>
[ johan: adjust context to 5.15 ]
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/ch341.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -97,7 +97,10 @@ struct ch341_private {
 	u8 mcr;
 	u8 msr;
 	u8 lcr;
+
 	unsigned long quirks;
+	u8 version;
+
 	unsigned long break_end;
 };
 
@@ -271,6 +274,9 @@ static int ch341_set_baudrate_lcr(struct
 	 * (stop bits, parity and word length). Version 0x30 and above use
 	 * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero.
 	 */
+	if (priv->version < 0x30)
+		return 0;
+
 	r = ch341_control_out(dev, CH341_REQ_WRITE_REG,
 			      CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr);
 	if (r)
@@ -323,7 +329,9 @@ static int ch341_configure(struct usb_de
 	r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size);
 	if (r < 0)
 		goto out;
-	dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]);
+
+	priv->version = buffer[0];
+	dev_dbg(&dev->dev, "Chip version: 0x%02x\n", priv->version);
 
 	r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);
 	if (r < 0)



^ permalink raw reply	[flat|nested] 133+ messages in thread

* [PATCH 5.15 107/107] USB: serial: ch341: fix disabled rx timer on older devices
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (105 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 106/107] USB: serial: ch341: fix lost character on LCR updates Greg Kroah-Hartman
@ 2022-09-06 13:31 ` Greg Kroah-Hartman
  2022-09-06 18:33 ` [PATCH 5.15 000/107] 5.15.66-rc1 review Florian Fainelli
                   ` (8 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-06 13:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Jonathan Woithe, Johan Hovold

From: Johan Hovold <johan@kernel.org>

commit 41ca302a697b64a3dab4676e01d0d11bb184737d upstream.

At least one older CH341 appears to have the RX timer enable bit
inverted so that setting it disables the RX timer and prevents the FIFO
from emptying until it is full.

Only set the RX timer enable bit for devices with version newer than
0x27 (even though this probably affects all pre-0x30 devices).

Reported-by: Jonathan Woithe <jwoithe@just42.net>
Tested-by: Jonathan Woithe <jwoithe@just42.net>
Link: https://lore.kernel.org/r/Ys1iPTfiZRWj2gXs@marvin.atrad.com.au
Fixes: 4e46c410e050 ("USB: serial: ch341: reinitialize chip on reconfiguration")
Cc: stable@vger.kernel.org      # 4.10
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/ch341.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -259,8 +259,12 @@ static int ch341_set_baudrate_lcr(struct
 	/*
 	 * CH341A buffers data until a full endpoint-size packet (32 bytes)
 	 * has been received unless bit 7 is set.
+	 *
+	 * At least one device with version 0x27 appears to have this bit
+	 * inverted.
 	 */
-	val |= BIT(7);
+	if (priv->version > 0x27)
+		val |= BIT(7);
 
 	r = ch341_control_out(dev, CH341_REQ_WRITE_REG,
 			      CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER,



^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (106 preceding siblings ...)
  2022-09-06 13:31 ` [PATCH 5.15 107/107] USB: serial: ch341: fix disabled rx timer on older devices Greg Kroah-Hartman
@ 2022-09-06 18:33 ` Florian Fainelli
  2022-09-06 18:42   ` Florian Fainelli
  2022-09-06 20:20 ` Naresh Kamboju
                   ` (7 subsequent siblings)
  115 siblings, 1 reply; 133+ messages in thread
From: Florian Fainelli @ 2022-09-06 18:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman, linux-kernel
  Cc: stable, torvalds, akpm, linux, shuah, patches, lkft-triage,
	pavel, jonathanh, sudipm.mukherjee, slade



On 9/6/2022 6:29 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.
> 
> The whole patch series can be found in one patch at:
> 	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
> or in the git tree and branch at:
> 	git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h

On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on 
BMIPS_GENERIC:

Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 18:33 ` [PATCH 5.15 000/107] 5.15.66-rc1 review Florian Fainelli
@ 2022-09-06 18:42   ` Florian Fainelli
  0 siblings, 0 replies; 133+ messages in thread
From: Florian Fainelli @ 2022-09-06 18:42 UTC (permalink / raw)
  To: Greg Kroah-Hartman, linux-kernel
  Cc: stable, torvalds, akpm, linux, shuah, patches, lkft-triage,
	pavel, jonathanh, sudipm.mukherjee, slade



On 9/6/2022 11:33 AM, Florian Fainelli wrote:
> 
> 
> On 9/6/2022 6:29 AM, Greg Kroah-Hartman wrote:
>> This is the start of the stable review cycle for the 5.15.66 release.
>> There are 107 patches in this series, all will be posted as a response
>> to this one.  If anyone has any issues with these being applied, please
>> let me know.
>>
>> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
>> Anything received after that time might be too late.
>>
>> The whole patch series can be found in one patch at:
>>     https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
>> or in the git tree and branch at:
>>     git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
>> and the diffstat can be found below.
>>
>> thanks,
>>
>> greg k-h
> 
> On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on 
> BMIPS_GENERIC:
> 
> Tested-by: Florian Fainelli <f.fainelli@gmail.com>

There is an issue with the lack of executable permission on 
scripts/pahole-flags.sh that I will be responding to in the appropriate 
patch.
-- 
Florian

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules
  2022-09-06 13:31 ` [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules Greg Kroah-Hartman
@ 2022-09-06 18:45   ` Florian Fainelli
  2022-09-07  5:40     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 133+ messages in thread
From: Florian Fainelli @ 2022-09-06 18:45 UTC (permalink / raw)
  To: Greg Kroah-Hartman, linux-kernel, stable, Jiri Olsa, Andrii Nakryiko



On 9/6/2022 6:31 AM, Greg Kroah-Hartman wrote:
> From: Jiri Olsa <jolsa@redhat.com>
> 
> commit e27f05147bff21408c1b8410ad8e90cd286e7952 upstream.
> 
> Using new PAHOLE_FLAGS variable to pass extra arguments to
> pahole for both vmlinux and modules BTF data generation.
> 
> Adding new scripts/pahole-flags.sh script that detect and
> prints pahole options.
> 
> [ fixed issues found by kernel test robot ]
> 
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> Link: https://lore.kernel.org/bpf/20211029125729.70002-1-jolsa@kernel.org
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>   Makefile                  |    3 +++
>   scripts/Makefile.modfinal |    2 +-
>   scripts/link-vmlinux.sh   |   11 +----------
>   scripts/pahole-flags.sh   |   20 ++++++++++++++++++++
>   4 files changed, 25 insertions(+), 11 deletions(-)
>   create mode 100755 scripts/pahole-flags.sh

My linux-stable-rc/linux-5.15.y checkout shows that 
scripts/pahole-flags.sh does not have an executable permission and 
commit 128e3cc0beffc92154d9af6bd8c107f46e830000 ("kbuild: Unify options 
for BTF generation for vmlinux and modules") does have:

diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
new file mode 100644
index 000000000000..e6093adf4c06

whereas your email does have the proper 100755 permission set on the 
file, any idea what happened here?
-- 
Florian

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (107 preceding siblings ...)
  2022-09-06 18:33 ` [PATCH 5.15 000/107] 5.15.66-rc1 review Florian Fainelli
@ 2022-09-06 20:20 ` Naresh Kamboju
  2022-09-06 20:46 ` Sudip Mukherjee
                   ` (6 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Naresh Kamboju @ 2022-09-06 20:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, stable, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	slade

On Tue, 6 Sept 2022 at 19:07, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
>         https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
> or in the git tree and branch at:
>         git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h


Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.

Tested-by: Linux Kernel Functional Testing <lkft@linaro.org>

## Build
* kernel: 5.15.66-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.15.y
* git commit: 78a6337a09dea696f5296f00bf8ae5e5283eef89
* git describe: v5.15.63-319-g78a6337a09de
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.63-319-g78a6337a09de

## No test Regressions (compared to v5.15.63-211-gad2e22e028e7)

## No metric Regressions (compared to v5.15.63-211-gad2e22e028e7)

## No test Fixes (compared to v5.15.63-211-gad2e22e028e7)

## No metric Fixes (compared to v5.15.63-211-gad2e22e028e7)

## Test result summary
total: 74572, pass: 67375, fail: 420, skip: 6561, xfail: 216

## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 333 total, 333 passed, 0 failed
* arm64: 65 total, 63 passed, 2 failed
* i386: 55 total, 53 passed, 2 failed
* mips: 56 total, 56 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 63 total, 63 passed, 0 failed
* riscv: 22 total, 22 passed, 0 failed
* s390: 24 total, 24 passed, 0 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x86_64: 58 total, 56 passed, 2 failed

## Test suites summary
* fwts
* igt-gpu-tools
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* rcutorture
* v4l2-compliance
* vdso

--
Linaro LKFT
https://lkft.linaro.org

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (108 preceding siblings ...)
  2022-09-06 20:20 ` Naresh Kamboju
@ 2022-09-06 20:46 ` Sudip Mukherjee
  2022-09-07  5:49   ` Greg Kroah-Hartman
  2022-09-06 21:48 ` Shuah Khan
                   ` (5 subsequent siblings)
  115 siblings, 1 reply; 133+ messages in thread
From: Sudip Mukherjee @ 2022-09-06 20:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Stable, Linus Torvalds, Andrew Morton,
	Guenter Roeck, Shuah Khan, patches, lkft-triage, Pavel Machek,
	Jonathan Hunter, Florian Fainelli, slade

Hi Greg,

On Tue, Sep 6, 2022 at 2:37 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.

My test pipelines are still running, but x86_64 allmodconfig failed
with gcc-12 with the error:

drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c: In function
'ipc_protocol_dl_td_process':
drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:406:13: error: the
comparison will always evaluate as 'true' for the address of 'cb' will
never be NULL [-Werror=address]
  406 |         if (!IPC_CB(skb)) {
      |             ^
In file included from drivers/net/wwan/iosm/iosm_ipc_imem.h:9,
                 from drivers/net/wwan/iosm/iosm_ipc_protocol.h:9,
                 from drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:6:
./include/linux/skbuff.h:794:33: note: 'cb' declared here
  794 |         char                    cb[48] __aligned(8);

It will need dbbc7d04c549 ("net: wwan: iosm: remove pointless null check").


-- 
Regards
Sudip

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (109 preceding siblings ...)
  2022-09-06 20:46 ` Sudip Mukherjee
@ 2022-09-06 21:48 ` Shuah Khan
  2022-09-07  4:44 ` Guenter Roeck
                   ` (4 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Shuah Khan @ 2022-09-06 21:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, linux-kernel
  Cc: stable, torvalds, akpm, linux, shuah, patches, lkft-triage,
	pavel, jonathanh, f.fainelli, sudipm.mukherjee, slade,
	Shuah Khan

On 9/6/22 07:29, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.
> 
> The whole patch series can be found in one patch at:
> 	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
> or in the git tree and branch at:
> 	git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h
> 

Compiled and booted on my test system. No dmesg regressions.

Tested-by: Shuah Khan <skhan@linuxfoundation.org>

thanks,
-- Shuah

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file
  2022-09-06 13:29 ` [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file Greg Kroah-Hartman
@ 2022-09-06 22:13   ` Lyude Paul
  2022-09-07 11:41     ` Sasha Levin
  0 siblings, 1 reply; 133+ messages in thread
From: Lyude Paul @ 2022-09-06 22:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman, linux-kernel; +Cc: stable, Jani Nikula, Sasha Levin

Were there parts of this series that weren't Cc'd to me via email? Trying to
understand why this patch would be pulled in since it might be required for
other fixes, but on it's own there should be no functional changes so it's not
really a candidate for stable.

On Tue, 2022-09-06 at 15:29 +0200, Greg Kroah-Hartman wrote:
> From: Jani Nikula <jani.nikula@intel.com>
> 
> [ Upstream commit 6cc42fbeb150ff33b17cbf108713ca4be23994d8 ]
> 
> In a long overdue refactoring, split out backlight code to new
> intel_backlight.[ch]. Simple code movement, leave renames for follow-up
> work. No functional changes.
> 
> Cc: Lyude Paul <lyude@redhat.com>
> Reviewed-by: Lyude Paul <lyude@redhat.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> Link: https://patchwork.freedesktop.org/patch/msgid/97d310848f03061473b9b2328e2c5c4dcf263cfa.1629888677.git.jani.nikula@intel.com
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>  drivers/gpu/drm/i915/Makefile                 |    1 +
>  drivers/gpu/drm/i915/display/g4x_dp.c         |    2 +-
>  drivers/gpu/drm/i915/display/icl_dsi.c        |    1 +
>  .../gpu/drm/i915/display/intel_backlight.c    | 1778 +++++++++++++++++
>  .../gpu/drm/i915/display/intel_backlight.h    |   51 +
>  .../gpu/drm/i915/display/intel_connector.c    |    4 +-
>  drivers/gpu/drm/i915/display/intel_ddi.c      |    2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       |    1 +
>  .../drm/i915/display/intel_dp_aux_backlight.c |    2 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c     |    1 +
>  drivers/gpu/drm/i915/display/intel_opregion.c |    3 +-
>  drivers/gpu/drm/i915/display/intel_panel.c    | 1767 +---------------
>  drivers/gpu/drm/i915/display/intel_panel.h    |   34 +-
>  drivers/gpu/drm/i915/display/vlv_dsi.c        |    1 +
>  14 files changed, 1843 insertions(+), 1805 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/display/intel_backlight.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_backlight.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 26cf754229451..9d371be7dc5cd 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -249,6 +249,7 @@ i915-y += \
>  	display/g4x_dp.o \
>  	display/g4x_hdmi.o \
>  	display/icl_dsi.o \
> +	display/intel_backlight.o \
>  	display/intel_crt.o \
>  	display/intel_ddi.o \
>  	display/intel_ddi_buf_trans.o \
> diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
> index de0f358184aa3..29c0eca647e34 100644
> --- a/drivers/gpu/drm/i915/display/g4x_dp.c
> +++ b/drivers/gpu/drm/i915/display/g4x_dp.c
> @@ -7,6 +7,7 @@
>  
>  #include "g4x_dp.h"
>  #include "intel_audio.h"
> +#include "intel_backlight.h"
>  #include "intel_connector.h"
>  #include "intel_de.h"
>  #include "intel_display_types.h"
> @@ -16,7 +17,6 @@
>  #include "intel_fifo_underrun.h"
>  #include "intel_hdmi.h"
>  #include "intel_hotplug.h"
> -#include "intel_panel.h"
>  #include "intel_pps.h"
>  #include "intel_sideband.h"
>  
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 638a00b2dc2d2..2601873e15466 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -29,6 +29,7 @@
>  #include <drm/drm_mipi_dsi.h>
>  
>  #include "intel_atomic.h"
> +#include "intel_backlight.h"
>  #include "intel_combo_phy.h"
>  #include "intel_connector.h"
>  #include "intel_crtc.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c
> new file mode 100644
> index 0000000000000..4b0086ee48519
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_backlight.c
> @@ -0,0 +1,1778 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/pwm.h>
> +
> +#include "intel_backlight.h"
> +#include "intel_connector.h"
> +#include "intel_de.h"
> +#include "intel_display_types.h"
> +#include "intel_dp_aux_backlight.h"
> +#include "intel_dsi_dcs_backlight.h"
> +#include "intel_panel.h"
> +
> +/**
> + * scale - scale values from one range to another
> + * @source_val: value in range [@source_min..@source_max]
> + * @source_min: minimum legal value for @source_val
> + * @source_max: maximum legal value for @source_val
> + * @target_min: corresponding target value for @source_min
> + * @target_max: corresponding target value for @source_max
> + *
> + * Return @source_val in range [@source_min..@source_max] scaled to range
> + * [@target_min..@target_max].
> + */
> +static u32 scale(u32 source_val,
> +		 u32 source_min, u32 source_max,
> +		 u32 target_min, u32 target_max)
> +{
> +	u64 target_val;
> +
> +	WARN_ON(source_min > source_max);
> +	WARN_ON(target_min > target_max);
> +
> +	/* defensive */
> +	source_val = clamp(source_val, source_min, source_max);
> +
> +	/* avoid overflows */
> +	target_val = mul_u32_u32(source_val - source_min,
> +				 target_max - target_min);
> +	target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min);
> +	target_val += target_min;
> +
> +	return target_val;
> +}
> +
> +/*
> + * Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
> + * to [hw_min..hw_max].
> + */
> +static u32 clamp_user_to_hw(struct intel_connector *connector,
> +			    u32 user_level, u32 user_max)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	u32 hw_level;
> +
> +	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
> +	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
> +
> +	return hw_level;
> +}
> +
> +/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
> +static u32 scale_hw_to_user(struct intel_connector *connector,
> +			    u32 hw_level, u32 user_max)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +
> +	return scale(hw_level, panel->backlight.min, panel->backlight.max,
> +		     0, user_max);
> +}
> +
> +u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
> +
> +	if (dev_priv->params.invert_brightness < 0)
> +		return val;
> +
> +	if (dev_priv->params.invert_brightness > 0 ||
> +	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
> +		return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min;
> +	}
> +
> +	return val;
> +}
> +
> +void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val);
> +	panel->backlight.pwm_funcs->set(conn_state, val);
> +}
> +
> +u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	drm_WARN_ON_ONCE(&dev_priv->drm,
> +			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
> +
> +	val = scale(val, panel->backlight.min, panel->backlight.max,
> +		    panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
> +
> +	return intel_panel_invert_pwm_level(connector, val);
> +}
> +
> +u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	drm_WARN_ON_ONCE(&dev_priv->drm,
> +			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
> +
> +	if (dev_priv->params.invert_brightness > 0 ||
> +	    (dev_priv->params.invert_brightness == 0 && dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS))
> +		val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min);
> +
> +	return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max,
> +		     panel->backlight.min, panel->backlight.max);
> +}
> +
> +static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
> +}
> +
> +static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> +}
> +
> +static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 val;
> +
> +	val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> +	if (DISPLAY_VER(dev_priv) < 4)
> +		val >>= 1;
> +
> +	if (panel->backlight.combination_mode) {
> +		u8 lbpc;
> +
> +		pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc);
> +		val *= lbpc;
> +	}
> +
> +	return val;
> +}
> +
> +static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
> +		return 0;
> +
> +	return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
> +}
> +
> +static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	return intel_de_read(dev_priv,
> +			     BXT_BLC_PWM_DUTY(panel->backlight.controller));
> +}
> +
> +static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	struct pwm_state state;
> +
> +	pwm_get_state(panel->backlight.pwm, &state);
> +	return pwm_get_relative_duty_cycle(&state, 100);
> +}
> +
> +static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level);
> +}
> +
> +static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	u32 tmp;
> +
> +	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level);
> +}
> +
> +static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 tmp, mask;
> +
> +	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
> +
> +	if (panel->backlight.combination_mode) {
> +		u8 lbpc;
> +
> +		lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1;
> +		level /= lbpc;
> +		pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc);
> +	}
> +
> +	if (DISPLAY_VER(dev_priv) == 4) {
> +		mask = BACKLIGHT_DUTY_CYCLE_MASK;
> +	} else {
> +		level <<= 1;
> +		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
> +	}
> +
> +	tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask;
> +	intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level);
> +}
> +
> +static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
> +	u32 tmp;
> +
> +	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level);
> +}
> +
> +static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	intel_de_write(dev_priv,
> +		       BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
> +}
> +
> +static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
> +
> +	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
> +	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> +}
> +
> +static void
> +intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level);
> +
> +	panel->backlight.funcs->set(conn_state, level);
> +}
> +
> +/* set backlight brightness to level in range [0..max], assuming hw min is
> + * respected.
> + */
> +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
> +				    u32 user_level, u32 user_max)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 hw_level;
> +
> +	/*
> +	 * Lack of crtc may occur during driver init because
> +	 * connection_mutex isn't held across the entire backlight
> +	 * setup + modeset readout, and the BIOS can issue the
> +	 * requests at any time.
> +	 */
> +	if (!panel->backlight.present || !conn_state->crtc)
> +		return;
> +
> +	mutex_lock(&dev_priv->backlight_lock);
> +
> +	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
> +
> +	hw_level = clamp_user_to_hw(connector, user_level, user_max);
> +	panel->backlight.level = hw_level;
> +
> +	if (panel->backlight.device)
> +		panel->backlight.device->props.brightness =
> +			scale_hw_to_user(connector,
> +					 panel->backlight.level,
> +					 panel->backlight.device->props.max_brightness);
> +
> +	if (panel->backlight.enabled)
> +		intel_panel_actually_set_backlight(conn_state, hw_level);
> +
> +	mutex_unlock(&dev_priv->backlight_lock);
> +}
> +
> +static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	u32 tmp;
> +
> +	intel_panel_set_pwm_level(old_conn_state, level);
> +
> +	/*
> +	 * Although we don't support or enable CPU PWM with LPT/SPT based
> +	 * systems, it may have been enabled prior to loading the
> +	 * driver. Disable to avoid warnings on LCPLL disable.
> +	 *
> +	 * This needs rework if we need to add support for CPU PWM on PCH split
> +	 * platforms.
> +	 */
> +	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> +	if (tmp & BLM_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "cpu backlight was enabled, disabling\n");
> +		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
> +			       tmp & ~BLM_PWM_ENABLE);
> +	}
> +
> +	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
> +}
> +
> +static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	u32 tmp;
> +
> +	intel_panel_set_pwm_level(old_conn_state, val);
> +
> +	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> +	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
> +
> +	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
> +}
> +
> +static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> +{
> +	intel_panel_set_pwm_level(old_conn_state, val);
> +}
> +
> +static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev);
> +	u32 tmp;
> +
> +	intel_panel_set_pwm_level(old_conn_state, val);
> +
> +	tmp = intel_de_read(dev_priv, BLC_PWM_CTL2);
> +	intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
> +}
> +
> +static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe;
> +	u32 tmp;
> +
> +	intel_panel_set_pwm_level(old_conn_state, val);
> +
> +	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> +	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
> +		       tmp & ~BLM_PWM_ENABLE);
> +}
> +
> +static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 tmp;
> +
> +	intel_panel_set_pwm_level(old_conn_state, val);
> +
> +	tmp = intel_de_read(dev_priv,
> +			    BXT_BLC_PWM_CTL(panel->backlight.controller));
> +	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> +		       tmp & ~BXT_BLC_PWM_ENABLE);
> +
> +	if (panel->backlight.controller == 1) {
> +		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
> +		val &= ~UTIL_PIN_ENABLE;
> +		intel_de_write(dev_priv, UTIL_PIN_CTL, val);
> +	}
> +}
> +
> +static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 tmp;
> +
> +	intel_panel_set_pwm_level(old_conn_state, val);
> +
> +	tmp = intel_de_read(dev_priv,
> +			    BXT_BLC_PWM_CTL(panel->backlight.controller));
> +	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> +		       tmp & ~BXT_BLC_PWM_ENABLE);
> +}
> +
> +static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	panel->backlight.pwm_state.enabled = false;
> +	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> +}
> +
> +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state)
> +{
> +	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (!panel->backlight.present)
> +		return;
> +
> +	/*
> +	 * Do not disable backlight on the vga_switcheroo path. When switching
> +	 * away from i915, the other client may depend on i915 to handle the
> +	 * backlight. This will leave the backlight on unnecessarily when
> +	 * another client is not activated.
> +	 */
> +	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Skipping backlight disable on vga switch\n");
> +		return;
> +	}
> +
> +	mutex_lock(&dev_priv->backlight_lock);
> +
> +	if (panel->backlight.device)
> +		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
> +	panel->backlight.enabled = false;
> +	panel->backlight.funcs->disable(old_conn_state, 0);
> +
> +	mutex_unlock(&dev_priv->backlight_lock);
> +}
> +
> +static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				 const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 pch_ctl1, pch_ctl2, schicken;
> +
> +	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> +		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> +	}
> +
> +	if (HAS_PCH_LPT(dev_priv)) {
> +		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2);
> +		if (panel->backlight.alternate_pwm_increment)
> +			schicken |= LPT_PWM_GRANULARITY;
> +		else
> +			schicken &= ~LPT_PWM_GRANULARITY;
> +		intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken);
> +	} else {
> +		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1);
> +		if (panel->backlight.alternate_pwm_increment)
> +			schicken |= SPT_PWM_GRANULARITY;
> +		else
> +			schicken &= ~SPT_PWM_GRANULARITY;
> +		intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken);
> +	}
> +
> +	pch_ctl2 = panel->backlight.pwm_level_max << 16;
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
> +
> +	pch_ctl1 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		pch_ctl1 |= BLM_PCH_POLARITY;
> +
> +	/* After LPT, override is the default. */
> +	if (HAS_PCH_LPT(dev_priv))
> +		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
> +
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> +	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
> +		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
> +
> +	/* This won't stick until the above enable. */
> +	intel_panel_set_pwm_level(conn_state, level);
> +}
> +
> +static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				 const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
> +
> +	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> +	if (cpu_ctl2 & BLM_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n");
> +		cpu_ctl2 &= ~BLM_PWM_ENABLE;
> +		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
> +	}
> +
> +	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> +		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> +	}
> +
> +	if (cpu_transcoder == TRANSCODER_EDP)
> +		cpu_ctl2 = BLM_TRANSCODER_EDP;
> +	else
> +		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
> +	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
> +	intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2);
> +	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
> +
> +	/* This won't stick until the above enable. */
> +	intel_panel_set_pwm_level(conn_state, level);
> +
> +	pch_ctl2 = panel->backlight.pwm_level_max << 16;
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
> +
> +	pch_ctl1 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		pch_ctl1 |= BLM_PCH_POLARITY;
> +
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> +	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
> +		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
> +}
> +
> +static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 ctl, freq;
> +
> +	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
> +	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
> +		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> +		intel_de_write(dev_priv, BLC_PWM_CTL, 0);
> +	}
> +
> +	freq = panel->backlight.pwm_level_max;
> +	if (panel->backlight.combination_mode)
> +		freq /= 0xff;
> +
> +	ctl = freq << 17;
> +	if (panel->backlight.combination_mode)
> +		ctl |= BLM_LEGACY_MODE;
> +	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
> +		ctl |= BLM_POLARITY_PNV;
> +
> +	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
> +	intel_de_posting_read(dev_priv, BLC_PWM_CTL);
> +
> +	/* XXX: combine this into above write? */
> +	intel_panel_set_pwm_level(conn_state, level);
> +
> +	/*
> +	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
> +	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
> +	 * that has backlight.
> +	 */
> +	if (DISPLAY_VER(dev_priv) == 2)
> +		intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
> +}
> +
> +static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
> +	u32 ctl, ctl2, freq;
> +
> +	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
> +	if (ctl2 & BLM_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> +		ctl2 &= ~BLM_PWM_ENABLE;
> +		intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
> +	}
> +
> +	freq = panel->backlight.pwm_level_max;
> +	if (panel->backlight.combination_mode)
> +		freq /= 0xff;
> +
> +	ctl = freq << 16;
> +	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
> +
> +	ctl2 = BLM_PIPE(pipe);
> +	if (panel->backlight.combination_mode)
> +		ctl2 |= BLM_COMBINATION_MODE;
> +	if (panel->backlight.active_low_pwm)
> +		ctl2 |= BLM_POLARITY_I965;
> +	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
> +	intel_de_posting_read(dev_priv, BLC_PWM_CTL2);
> +	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
> +
> +	intel_panel_set_pwm_level(conn_state, level);
> +}
> +
> +static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				 const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +	u32 ctl, ctl2;
> +
> +	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> +	if (ctl2 & BLM_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> +		ctl2 &= ~BLM_PWM_ENABLE;
> +		intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
> +	}
> +
> +	ctl = panel->backlight.pwm_level_max << 16;
> +	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl);
> +
> +	/* XXX: combine this into above write? */
> +	intel_panel_set_pwm_level(conn_state, level);
> +
> +	ctl2 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		ctl2 |= BLM_POLARITY_I965;
> +	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
> +	intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> +	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
> +		       ctl2 | BLM_PWM_ENABLE);
> +}
> +
> +static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				 const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +	u32 pwm_ctl, val;
> +
> +	/* Controller 1 uses the utility pin. */
> +	if (panel->backlight.controller == 1) {
> +		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
> +		if (val & UTIL_PIN_ENABLE) {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "util pin already enabled\n");
> +			val &= ~UTIL_PIN_ENABLE;
> +			intel_de_write(dev_priv, UTIL_PIN_CTL, val);
> +		}
> +
> +		val = 0;
> +		if (panel->backlight.util_pin_active_low)
> +			val |= UTIL_PIN_POLARITY;
> +		intel_de_write(dev_priv, UTIL_PIN_CTL,
> +			       val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
> +	}
> +
> +	pwm_ctl = intel_de_read(dev_priv,
> +				BXT_BLC_PWM_CTL(panel->backlight.controller));
> +	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> +		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
> +		intel_de_write(dev_priv,
> +			       BXT_BLC_PWM_CTL(panel->backlight.controller),
> +			       pwm_ctl);
> +	}
> +
> +	intel_de_write(dev_priv,
> +		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
> +		       panel->backlight.pwm_level_max);
> +
> +	intel_panel_set_pwm_level(conn_state, level);
> +
> +	pwm_ctl = 0;
> +	if (panel->backlight.active_low_pwm)
> +		pwm_ctl |= BXT_BLC_PWM_POLARITY;
> +
> +	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> +		       pwm_ctl);
> +	intel_de_posting_read(dev_priv,
> +			      BXT_BLC_PWM_CTL(panel->backlight.controller));
> +	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> +		       pwm_ctl | BXT_BLC_PWM_ENABLE);
> +}
> +
> +static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				 const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 pwm_ctl;
> +
> +	pwm_ctl = intel_de_read(dev_priv,
> +				BXT_BLC_PWM_CTL(panel->backlight.controller));
> +	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
> +		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> +		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
> +		intel_de_write(dev_priv,
> +			       BXT_BLC_PWM_CTL(panel->backlight.controller),
> +			       pwm_ctl);
> +	}
> +
> +	intel_de_write(dev_priv,
> +		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
> +		       panel->backlight.pwm_level_max);
> +
> +	intel_panel_set_pwm_level(conn_state, level);
> +
> +	pwm_ctl = 0;
> +	if (panel->backlight.active_low_pwm)
> +		pwm_ctl |= BXT_BLC_PWM_POLARITY;
> +
> +	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> +		       pwm_ctl);
> +	intel_de_posting_read(dev_priv,
> +			      BXT_BLC_PWM_CTL(panel->backlight.controller));
> +	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> +		       pwm_ctl | BXT_BLC_PWM_ENABLE);
> +}
> +
> +static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				     const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
> +	panel->backlight.pwm_state.enabled = true;
> +	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> +}
> +
> +static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
> +					   const struct drm_connector_state *conn_state)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	WARN_ON(panel->backlight.max == 0);
> +
> +	if (panel->backlight.level <= panel->backlight.min) {
> +		panel->backlight.level = panel->backlight.max;
> +		if (panel->backlight.device)
> +			panel->backlight.device->props.brightness =
> +				scale_hw_to_user(connector,
> +						 panel->backlight.level,
> +						 panel->backlight.device->props.max_brightness);
> +	}
> +
> +	panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level);
> +	panel->backlight.enabled = true;
> +	if (panel->backlight.device)
> +		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
> +}
> +
> +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +
> +	if (!panel->backlight.present)
> +		return;
> +
> +	drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe));
> +
> +	mutex_lock(&dev_priv->backlight_lock);
> +
> +	__intel_panel_enable_backlight(crtc_state, conn_state);
> +
> +	mutex_unlock(&dev_priv->backlight_lock);
> +}
> +
> +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
> +static u32 intel_panel_get_backlight(struct intel_connector *connector)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 val = 0;
> +
> +	mutex_lock(&dev_priv->backlight_lock);
> +
> +	if (panel->backlight.enabled)
> +		val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector));
> +
> +	mutex_unlock(&dev_priv->backlight_lock);
> +
> +	drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val);
> +	return val;
> +}
> +
> +/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
> +static u32 scale_user_to_hw(struct intel_connector *connector,
> +			    u32 user_level, u32 user_max)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +
> +	return scale(user_level, 0, user_max,
> +		     panel->backlight.min, panel->backlight.max);
> +}
> +
> +/* set backlight brightness to level in range [0..max], scaling wrt hw min */
> +static void intel_panel_set_backlight(const struct drm_connector_state *conn_state,
> +				      u32 user_level, u32 user_max)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 hw_level;
> +
> +	if (!panel->backlight.present)
> +		return;
> +
> +	mutex_lock(&dev_priv->backlight_lock);
> +
> +	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
> +
> +	hw_level = scale_user_to_hw(connector, user_level, user_max);
> +	panel->backlight.level = hw_level;
> +
> +	if (panel->backlight.enabled)
> +		intel_panel_actually_set_backlight(conn_state, hw_level);
> +
> +	mutex_unlock(&dev_priv->backlight_lock);
> +}
> +
> +static int intel_backlight_device_update_status(struct backlight_device *bd)
> +{
> +	struct intel_connector *connector = bl_get_data(bd);
> +	struct intel_panel *panel = &connector->panel;
> +	struct drm_device *dev = connector->base.dev;
> +
> +	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> +	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
> +		      bd->props.brightness, bd->props.max_brightness);
> +	intel_panel_set_backlight(connector->base.state, bd->props.brightness,
> +				  bd->props.max_brightness);
> +
> +	/*
> +	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
> +	 * backlight class device does not make it easy to differentiate
> +	 * between callbacks for brightness and bl_power, so our backlight_power
> +	 * callback needs to take this into account.
> +	 */
> +	if (panel->backlight.enabled) {
> +		if (panel->backlight.power) {
> +			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
> +				bd->props.brightness != 0;
> +			panel->backlight.power(connector, enable);
> +		}
> +	} else {
> +		bd->props.power = FB_BLANK_POWERDOWN;
> +	}
> +
> +	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +	return 0;
> +}
> +
> +static int intel_backlight_device_get_brightness(struct backlight_device *bd)
> +{
> +	struct intel_connector *connector = bl_get_data(bd);
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	intel_wakeref_t wakeref;
> +	int ret = 0;
> +
> +	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
> +		u32 hw_level;
> +
> +		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> +
> +		hw_level = intel_panel_get_backlight(connector);
> +		ret = scale_hw_to_user(connector,
> +				       hw_level, bd->props.max_brightness);
> +
> +		drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct backlight_ops intel_backlight_device_ops = {
> +	.update_status = intel_backlight_device_update_status,
> +	.get_brightness = intel_backlight_device_get_brightness,
> +};
> +
> +int intel_backlight_device_register(struct intel_connector *connector)
> +{
> +	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	struct backlight_properties props;
> +	struct backlight_device *bd;
> +	const char *name;
> +	int ret = 0;
> +
> +	if (WARN_ON(panel->backlight.device))
> +		return -ENODEV;
> +
> +	if (!panel->backlight.present)
> +		return 0;
> +
> +	WARN_ON(panel->backlight.max == 0);
> +
> +	memset(&props, 0, sizeof(props));
> +	props.type = BACKLIGHT_RAW;
> +
> +	/*
> +	 * Note: Everything should work even if the backlight device max
> +	 * presented to the userspace is arbitrarily chosen.
> +	 */
> +	props.max_brightness = panel->backlight.max;
> +	props.brightness = scale_hw_to_user(connector,
> +					    panel->backlight.level,
> +					    props.max_brightness);
> +
> +	if (panel->backlight.enabled)
> +		props.power = FB_BLANK_UNBLANK;
> +	else
> +		props.power = FB_BLANK_POWERDOWN;
> +
> +	name = kstrdup("intel_backlight", GFP_KERNEL);
> +	if (!name)
> +		return -ENOMEM;
> +
> +	bd = backlight_device_register(name, connector->base.kdev, connector,
> +				       &intel_backlight_device_ops, &props);
> +
> +	/*
> +	 * Using the same name independent of the drm device or connector
> +	 * prevents registration of multiple backlight devices in the
> +	 * driver. However, we need to use the default name for backward
> +	 * compatibility. Use unique names for subsequent backlight devices as a
> +	 * fallback when the default name already exists.
> +	 */
> +	if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) {
> +		kfree(name);
> +		name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
> +				 i915->drm.primary->index, connector->base.name);
> +		if (!name)
> +			return -ENOMEM;
> +
> +		bd = backlight_device_register(name, connector->base.kdev, connector,
> +					       &intel_backlight_device_ops, &props);
> +	}
> +
> +	if (IS_ERR(bd)) {
> +		drm_err(&i915->drm,
> +			"[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n",
> +			connector->base.base.id, connector->base.name, name, PTR_ERR(bd));
> +		ret = PTR_ERR(bd);
> +		goto out;
> +	}
> +
> +	panel->backlight.device = bd;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[CONNECTOR:%d:%s] backlight device %s registered\n",
> +		    connector->base.base.id, connector->base.name, name);
> +
> +out:
> +	kfree(name);
> +
> +	return ret;
> +}
> +
> +void intel_backlight_device_unregister(struct intel_connector *connector)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (panel->backlight.device) {
> +		backlight_device_unregister(panel->backlight.device);
> +		panel->backlight.device = NULL;
> +	}
> +}
> +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> +
> +/*
> + * CNP: PWM clock frequency is 19.2 MHz or 24 MHz.
> + *      PWM increment = 1
> + */
> +static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
> +				 pwm_freq_hz);
> +}
> +
> +/*
> + * BXT: PWM clock frequency = 19.2 MHz.
> + */
> +static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
> +}
> +
> +/*
> + * SPT: This value represents the period of the PWM stream in clock periods
> + * multiplied by 16 (default increment) or 128 (alternate increment selected in
> + * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
> + */
> +static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	u32 mul;
> +
> +	if (panel->backlight.alternate_pwm_increment)
> +		mul = 128;
> +	else
> +		mul = 16;
> +
> +	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
> +}
> +
> +/*
> + * LPT: This value represents the period of the PWM stream in clock periods
> + * multiplied by 128 (default increment) or 16 (alternate increment, selected in
> + * LPT SOUTH_CHICKEN2 register bit 5).
> + */
> +static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 mul, clock;
> +
> +	if (panel->backlight.alternate_pwm_increment)
> +		mul = 16;
> +	else
> +		mul = 128;
> +
> +	if (HAS_PCH_LPT_H(dev_priv))
> +		clock = MHz(135); /* LPT:H */
> +	else
> +		clock = MHz(24); /* LPT:LP */
> +
> +	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
> +}
> +
> +/*
> + * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
> + * display raw clocks multiplied by 128.
> + */
> +static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
> +				 pwm_freq_hz * 128);
> +}
> +
> +/*
> + * Gen2: This field determines the number of time base events (display core
> + * clock frequency/32) in total for a complete cycle of modulated backlight
> + * control.
> + *
> + * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
> + * divided by 32.
> + */
> +static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	int clock;
> +
> +	if (IS_PINEVIEW(dev_priv))
> +		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
> +	else
> +		clock = KHz(dev_priv->cdclk.hw.cdclk);
> +
> +	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
> +}
> +
> +/*
> + * Gen4: This value represents the period of the PWM stream in display core
> + * clocks ([DevCTG] HRAW clocks) multiplied by 128.
> + *
> + */
> +static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	int clock;
> +
> +	if (IS_G4X(dev_priv))
> +		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
> +	else
> +		clock = KHz(dev_priv->cdclk.hw.cdclk);
> +
> +	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
> +}
> +
> +/*
> + * VLV: This value represents the period of the PWM stream in display core
> + * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
> + * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
> + */
> +static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	int mul, clock;
> +
> +	if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
> +		if (IS_CHERRYVIEW(dev_priv))
> +			clock = KHz(19200);
> +		else
> +			clock = MHz(25);
> +		mul = 16;
> +	} else {
> +		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
> +		mul = 128;
> +	}
> +
> +	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
> +}
> +
> +static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv)
> +{
> +	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
> +
> +	if (pwm_freq_hz) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "VBT defined backlight frequency %u Hz\n",
> +			    pwm_freq_hz);
> +	} else {
> +		pwm_freq_hz = 200;
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "default backlight frequency %u Hz\n",
> +			    pwm_freq_hz);
> +	}
> +
> +	return pwm_freq_hz;
> +}
> +
> +static u32 get_backlight_max_vbt(struct intel_connector *connector)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
> +	u32 pwm;
> +
> +	if (!panel->backlight.pwm_funcs->hz_to_pwm) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "backlight frequency conversion not supported\n");
> +		return 0;
> +	}
> +
> +	pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz);
> +	if (!pwm) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "backlight frequency conversion failed\n");
> +		return 0;
> +	}
> +
> +	return pwm;
> +}
> +
> +/*
> + * Note: The setup hooks can't assume pipe is set!
> + */
> +static u32 get_backlight_min_vbt(struct intel_connector *connector)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	int min;
> +
> +	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
> +
> +	/*
> +	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
> +	 * to problems. There are such machines out there. Either our
> +	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
> +	 * against this by letting the minimum be at most (arbitrarily chosen)
> +	 * 25% of the max.
> +	 */
> +	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
> +	if (min != dev_priv->vbt.backlight.min_brightness) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "clamping VBT min backlight %d/255 to %d/255\n",
> +			    dev_priv->vbt.backlight.min_brightness, min);
> +	}
> +
> +	/* vbt value is a coefficient in range [0..255] */
> +	return scale(min, 0, 255, 0, panel->backlight.pwm_level_max);
> +}
> +
> +static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
> +	bool alt, cpu_mode;
> +
> +	if (HAS_PCH_LPT(dev_priv))
> +		alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
> +	else
> +		alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
> +	panel->backlight.alternate_pwm_increment = alt;
> +
> +	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> +
> +	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
> +	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
> +
> +	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
> +
> +	cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) &&
> +		   !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) &&
> +		   (cpu_ctl2 & BLM_PWM_ENABLE);
> +
> +	if (cpu_mode) {
> +		val = pch_get_backlight(connector, unused);
> +
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "CPU backlight register was enabled, switching to PCH override\n");
> +
> +		/* Write converted CPU PWM value to PCH override register */
> +		lpt_set_backlight(connector->base.state, val);
> +		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
> +			       pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE);
> +
> +		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
> +			       cpu_ctl2 & ~BLM_PWM_ENABLE);
> +	}
> +
> +	return 0;
> +}
> +
> +static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
> +
> +	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> +	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> +
> +	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
> +	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
> +
> +	if (!panel->backlight.pwm_level_max)
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> +	panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
> +		(pch_ctl1 & BLM_PCH_PWM_ENABLE);
> +
> +	return 0;
> +}
> +
> +static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 ctl, val;
> +
> +	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
> +
> +	if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
> +		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
> +
> +	if (IS_PINEVIEW(dev_priv))
> +		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
> +
> +	panel->backlight.pwm_level_max = ctl >> 17;
> +
> +	if (!panel->backlight.pwm_level_max) {
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +		panel->backlight.pwm_level_max >>= 1;
> +	}
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	if (panel->backlight.combination_mode)
> +		panel->backlight.pwm_level_max *= 0xff;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	val = i9xx_get_backlight(connector, unused);
> +	val = intel_panel_invert_pwm_level(connector, val);
> +	val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
> +
> +	panel->backlight.pwm_enabled = val != 0;
> +
> +	return 0;
> +}
> +
> +static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 ctl, ctl2;
> +
> +	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
> +	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
> +	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
> +
> +	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
> +	panel->backlight.pwm_level_max = ctl >> 16;
> +
> +	if (!panel->backlight.pwm_level_max)
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	if (panel->backlight.combination_mode)
> +		panel->backlight.pwm_level_max *= 0xff;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
> +
> +	return 0;
> +}
> +
> +static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 ctl, ctl2;
> +
> +	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
> +		return -ENODEV;
> +
> +	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> +	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
> +
> +	ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe));
> +	panel->backlight.pwm_level_max = ctl >> 16;
> +
> +	if (!panel->backlight.pwm_level_max)
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
> +
> +	return 0;
> +}
> +
> +static int
> +bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 pwm_ctl, val;
> +
> +	panel->backlight.controller = dev_priv->vbt.backlight.controller;
> +
> +	pwm_ctl = intel_de_read(dev_priv,
> +				BXT_BLC_PWM_CTL(panel->backlight.controller));
> +
> +	/* Controller 1 uses the utility pin. */
> +	if (panel->backlight.controller == 1) {
> +		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
> +		panel->backlight.util_pin_active_low =
> +					val & UTIL_PIN_POLARITY;
> +	}
> +
> +	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
> +	panel->backlight.pwm_level_max =
> +		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
> +
> +	if (!panel->backlight.pwm_level_max)
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
> +
> +	return 0;
> +}
> +
> +static int
> +cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +	u32 pwm_ctl;
> +
> +	/*
> +	 * CNP has the BXT implementation of backlight, but with only one
> +	 * controller. TODO: ICP has multiple controllers but we only use
> +	 * controller 0 for now.
> +	 */
> +	panel->backlight.controller = 0;
> +
> +	pwm_ctl = intel_de_read(dev_priv,
> +				BXT_BLC_PWM_CTL(panel->backlight.controller));
> +
> +	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
> +	panel->backlight.pwm_level_max =
> +		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
> +
> +	if (!panel->backlight.pwm_level_max)
> +		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> +
> +	if (!panel->backlight.pwm_level_max)
> +		return -ENODEV;
> +
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
> +
> +	return 0;
> +}
> +
> +static int ext_pwm_setup_backlight(struct intel_connector *connector,
> +				   enum pipe pipe)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_panel *panel = &connector->panel;
> +	const char *desc;
> +	u32 level;
> +
> +	/* Get the right PWM chip for DSI backlight according to VBT */
> +	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
> +		panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
> +		desc = "PMIC";
> +	} else {
> +		panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight");
> +		desc = "SoC";
> +	}
> +
> +	if (IS_ERR(panel->backlight.pwm)) {
> +		drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n",
> +			desc);
> +		panel->backlight.pwm = NULL;
> +		return -ENODEV;
> +	}
> +
> +	panel->backlight.pwm_level_max = 100; /* 100% */
> +	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> +
> +	if (pwm_is_enabled(panel->backlight.pwm)) {
> +		/* PWM is already enabled, use existing settings */
> +		pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> +
> +		level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state,
> +						    100);
> +		level = intel_panel_invert_pwm_level(connector, level);
> +		panel->backlight.pwm_enabled = true;
> +
> +		drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",
> +			    NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,
> +			    get_vbt_pwm_freq(dev_priv), level);
> +	} else {
> +		/* Set period from VBT frequency, leave other settings at 0. */
> +		panel->backlight.pwm_state.period =
> +			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
> +	}
> +
> +	drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
> +		 desc);
> +	return 0;
> +}
> +
> +static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	panel->backlight.pwm_funcs->set(conn_state,
> +				       intel_panel_invert_pwm_level(connector, level));
> +}
> +
> +static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +
> +	return intel_panel_invert_pwm_level(connector,
> +					    panel->backlight.pwm_funcs->get(connector, pipe));
> +}
> +
> +static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				       const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	panel->backlight.pwm_funcs->enable(crtc_state, conn_state,
> +					   intel_panel_invert_pwm_level(connector, level));
> +}
> +
> +static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	panel->backlight.pwm_funcs->disable(conn_state,
> +					    intel_panel_invert_pwm_level(connector, level));
> +}
> +
> +static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	int ret = panel->backlight.pwm_funcs->setup(connector, pipe);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	panel->backlight.min = panel->backlight.pwm_level_min;
> +	panel->backlight.max = panel->backlight.pwm_level_max;
> +	panel->backlight.level = intel_pwm_get_backlight(connector, pipe);
> +	panel->backlight.enabled = panel->backlight.pwm_enabled;
> +
> +	return 0;
> +}
> +
> +void intel_panel_update_backlight(struct intel_atomic_state *state,
> +				  struct intel_encoder *encoder,
> +				  const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state)
> +{
> +	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (!panel->backlight.present)
> +		return;
> +
> +	mutex_lock(&dev_priv->backlight_lock);
> +	if (!panel->backlight.enabled)
> +		__intel_panel_enable_backlight(crtc_state, conn_state);
> +
> +	mutex_unlock(&dev_priv->backlight_lock);
> +}
> +
> +int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_connector *intel_connector = to_intel_connector(connector);
> +	struct intel_panel *panel = &intel_connector->panel;
> +	int ret;
> +
> +	if (!dev_priv->vbt.backlight.present) {
> +		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "no backlight present per VBT, but present per quirk\n");
> +		} else {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "no backlight present per VBT\n");
> +			return 0;
> +		}
> +	}
> +
> +	/* ensure intel_panel has been initialized first */
> +	if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs))
> +		return -ENODEV;
> +
> +	/* set level and max in panel struct */
> +	mutex_lock(&dev_priv->backlight_lock);
> +	ret = panel->backlight.funcs->setup(intel_connector, pipe);
> +	mutex_unlock(&dev_priv->backlight_lock);
> +
> +	if (ret) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "failed to setup backlight for connector %s\n",
> +			    connector->name);
> +		return ret;
> +	}
> +
> +	panel->backlight.present = true;
> +
> +	drm_dbg_kms(&dev_priv->drm,
> +		    "Connector %s backlight initialized, %s, brightness %u/%u\n",
> +		    connector->name,
> +		    enableddisabled(panel->backlight.enabled),
> +		    panel->backlight.level, panel->backlight.max);
> +
> +	return 0;
> +}
> +
> +void intel_panel_destroy_backlight(struct intel_panel *panel)
> +{
> +	/* dispose of the pwm */
> +	if (panel->backlight.pwm)
> +		pwm_put(panel->backlight.pwm);
> +
> +	panel->backlight.present = false;
> +}
> +
> +static const struct intel_panel_bl_funcs bxt_pwm_funcs = {
> +	.setup = bxt_setup_backlight,
> +	.enable = bxt_enable_backlight,
> +	.disable = bxt_disable_backlight,
> +	.set = bxt_set_backlight,
> +	.get = bxt_get_backlight,
> +	.hz_to_pwm = bxt_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs cnp_pwm_funcs = {
> +	.setup = cnp_setup_backlight,
> +	.enable = cnp_enable_backlight,
> +	.disable = cnp_disable_backlight,
> +	.set = bxt_set_backlight,
> +	.get = bxt_get_backlight,
> +	.hz_to_pwm = cnp_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs lpt_pwm_funcs = {
> +	.setup = lpt_setup_backlight,
> +	.enable = lpt_enable_backlight,
> +	.disable = lpt_disable_backlight,
> +	.set = lpt_set_backlight,
> +	.get = lpt_get_backlight,
> +	.hz_to_pwm = lpt_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs spt_pwm_funcs = {
> +	.setup = lpt_setup_backlight,
> +	.enable = lpt_enable_backlight,
> +	.disable = lpt_disable_backlight,
> +	.set = lpt_set_backlight,
> +	.get = lpt_get_backlight,
> +	.hz_to_pwm = spt_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs pch_pwm_funcs = {
> +	.setup = pch_setup_backlight,
> +	.enable = pch_enable_backlight,
> +	.disable = pch_disable_backlight,
> +	.set = pch_set_backlight,
> +	.get = pch_get_backlight,
> +	.hz_to_pwm = pch_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs ext_pwm_funcs = {
> +	.setup = ext_pwm_setup_backlight,
> +	.enable = ext_pwm_enable_backlight,
> +	.disable = ext_pwm_disable_backlight,
> +	.set = ext_pwm_set_backlight,
> +	.get = ext_pwm_get_backlight,
> +};
> +
> +static const struct intel_panel_bl_funcs vlv_pwm_funcs = {
> +	.setup = vlv_setup_backlight,
> +	.enable = vlv_enable_backlight,
> +	.disable = vlv_disable_backlight,
> +	.set = vlv_set_backlight,
> +	.get = vlv_get_backlight,
> +	.hz_to_pwm = vlv_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs i965_pwm_funcs = {
> +	.setup = i965_setup_backlight,
> +	.enable = i965_enable_backlight,
> +	.disable = i965_disable_backlight,
> +	.set = i9xx_set_backlight,
> +	.get = i9xx_get_backlight,
> +	.hz_to_pwm = i965_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs i9xx_pwm_funcs = {
> +	.setup = i9xx_setup_backlight,
> +	.enable = i9xx_enable_backlight,
> +	.disable = i9xx_disable_backlight,
> +	.set = i9xx_set_backlight,
> +	.get = i9xx_get_backlight,
> +	.hz_to_pwm = i9xx_hz_to_pwm,
> +};
> +
> +static const struct intel_panel_bl_funcs pwm_bl_funcs = {
> +	.setup = intel_pwm_setup_backlight,
> +	.enable = intel_pwm_enable_backlight,
> +	.disable = intel_pwm_disable_backlight,
> +	.set = intel_pwm_set_backlight,
> +	.get = intel_pwm_get_backlight,
> +};
> +
> +/* Set up chip specific backlight functions */
> +void
> +intel_panel_init_backlight_funcs(struct intel_panel *panel)
> +{
> +	struct intel_connector *connector =
> +		container_of(panel, struct intel_connector, panel);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +
> +	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
> +	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
> +		return;
> +
> +	if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
> +		panel->backlight.pwm_funcs = &bxt_pwm_funcs;
> +	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
> +		panel->backlight.pwm_funcs = &cnp_pwm_funcs;
> +	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) {
> +		if (HAS_PCH_LPT(dev_priv))
> +			panel->backlight.pwm_funcs = &lpt_pwm_funcs;
> +		else
> +			panel->backlight.pwm_funcs = &spt_pwm_funcs;
> +	} else if (HAS_PCH_SPLIT(dev_priv)) {
> +		panel->backlight.pwm_funcs = &pch_pwm_funcs;
> +	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> +		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
> +			panel->backlight.pwm_funcs = &ext_pwm_funcs;
> +		} else {
> +			panel->backlight.pwm_funcs = &vlv_pwm_funcs;
> +		}
> +	} else if (DISPLAY_VER(dev_priv) == 4) {
> +		panel->backlight.pwm_funcs = &i965_pwm_funcs;
> +	} else {
> +		panel->backlight.pwm_funcs = &i9xx_pwm_funcs;
> +	}
> +
> +	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
> +	    intel_dp_aux_init_backlight_funcs(connector) == 0)
> +		return;
> +
> +	/* We're using a standard PWM backlight interface */
> +	panel->backlight.funcs = &pwm_bl_funcs;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_backlight.h b/drivers/gpu/drm/i915/display/intel_backlight.h
> new file mode 100644
> index 0000000000000..282020cb47d5b
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_backlight.h
> @@ -0,0 +1,51 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#ifndef __INTEL_BACKLIGHT_H__
> +#define __INTEL_BACKLIGHT_H__
> +
> +#include <linux/types.h>
> +
> +struct drm_connector;
> +struct drm_connector_state;
> +struct intel_atomic_state;
> +struct intel_connector;
> +struct intel_crtc_state;
> +struct intel_encoder;
> +struct intel_panel;
> +enum pipe;
> +
> +void intel_panel_init_backlight_funcs(struct intel_panel *panel);
> +void intel_panel_destroy_backlight(struct intel_panel *panel);
> +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
> +				    u32 level, u32 max);
> +int intel_panel_setup_backlight(struct drm_connector *connector,
> +				enum pipe pipe);
> +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state);
> +void intel_panel_update_backlight(struct intel_atomic_state *state,
> +				  struct intel_encoder *encoder,
> +				  const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state);
> +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state);
> +void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level);
> +u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level);
> +u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level);
> +u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val);
> +
> +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
> +int intel_backlight_device_register(struct intel_connector *connector);
> +void intel_backlight_device_unregister(struct intel_connector *connector);
> +#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> +static inline int intel_backlight_device_register(struct intel_connector *connector)
> +{
> +	return 0;
> +}
> +static inline void intel_backlight_device_unregister(struct intel_connector *connector)
> +{
> +}
> +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> +
> +#endif /* __INTEL_BACKLIGHT_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
> index 9bed1ccecea0d..4f49d782eca23 100644
> --- a/drivers/gpu/drm/i915/display/intel_connector.c
> +++ b/drivers/gpu/drm/i915/display/intel_connector.c
> @@ -29,13 +29,13 @@
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_edid.h>
>  
> -#include "display/intel_panel.h"
> -
>  #include "i915_drv.h"
> +#include "intel_backlight.h"
>  #include "intel_connector.h"
>  #include "intel_display_debugfs.h"
>  #include "intel_display_types.h"
>  #include "intel_hdcp.h"
> +#include "intel_panel.h"
>  
>  int intel_connector_init(struct intel_connector *connector)
>  {
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index f61901e26409e..68489c7298302 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -29,6 +29,7 @@
>  
>  #include "i915_drv.h"
>  #include "intel_audio.h"
> +#include "intel_backlight.h"
>  #include "intel_combo_phy.h"
>  #include "intel_connector.h"
>  #include "intel_crtc.h"
> @@ -49,7 +50,6 @@
>  #include "intel_hdmi.h"
>  #include "intel_hotplug.h"
>  #include "intel_lspcon.h"
> -#include "intel_panel.h"
>  #include "intel_pps.h"
>  #include "intel_psr.h"
>  #include "intel_snps_phy.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 631cf7d4323c8..f87e4d510ea5e 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -45,6 +45,7 @@
>  #include "i915_drv.h"
>  #include "intel_atomic.h"
>  #include "intel_audio.h"
> +#include "intel_backlight.h"
>  #include "intel_connector.h"
>  #include "intel_ddi.h"
>  #include "intel_de.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
> index e7b90863aa43d..0a77f0e48aa11 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
> @@ -34,10 +34,10 @@
>   * for some reason.
>   */
>  
> +#include "intel_backlight.h"
>  #include "intel_display_types.h"
>  #include "intel_dp.h"
>  #include "intel_dp_aux_backlight.h"
> -#include "intel_panel.h"
>  
>  /* TODO:
>   * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we
> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
> index e0381b0fce914..8f5741ebd58dd 100644
> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
> @@ -40,6 +40,7 @@
>  
>  #include "i915_drv.h"
>  #include "intel_atomic.h"
> +#include "intel_backlight.h"
>  #include "intel_connector.h"
>  #include "intel_de.h"
>  #include "intel_display_types.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c
> index f7f49b69830fa..aad5c1cd3898e 100644
> --- a/drivers/gpu/drm/i915/display/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/display/intel_opregion.c
> @@ -30,10 +30,9 @@
>  #include <linux/firmware.h>
>  #include <acpi/video.h>
>  
> -#include "display/intel_panel.h"
> -
>  #include "i915_drv.h"
>  #include "intel_acpi.h"
> +#include "intel_backlight.h"
>  #include "intel_display_types.h"
>  #include "intel_opregion.h"
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
> index 7d7a60b4d2de7..ad54767440c15 100644
> --- a/drivers/gpu/drm/i915/display/intel_panel.c
> +++ b/drivers/gpu/drm/i915/display/intel_panel.c
> @@ -28,17 +28,13 @@
>   *      Chris Wilson <chris@chris-wilson.co.uk>
>   */
>  
> -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> -
>  #include <linux/kernel.h>
> -#include <linux/moduleparam.h>
>  #include <linux/pwm.h>
>  
> +#include "intel_backlight.h"
>  #include "intel_connector.h"
>  #include "intel_de.h"
>  #include "intel_display_types.h"
> -#include "intel_dp_aux_backlight.h"
> -#include "intel_dsi_dcs_backlight.h"
>  #include "intel_panel.h"
>  
>  void
> @@ -456,1767 +452,6 @@ int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state,
>  	return 0;
>  }
>  
> -/**
> - * scale - scale values from one range to another
> - * @source_val: value in range [@source_min..@source_max]
> - * @source_min: minimum legal value for @source_val
> - * @source_max: maximum legal value for @source_val
> - * @target_min: corresponding target value for @source_min
> - * @target_max: corresponding target value for @source_max
> - *
> - * Return @source_val in range [@source_min..@source_max] scaled to range
> - * [@target_min..@target_max].
> - */
> -static u32 scale(u32 source_val,
> -		 u32 source_min, u32 source_max,
> -		 u32 target_min, u32 target_max)
> -{
> -	u64 target_val;
> -
> -	WARN_ON(source_min > source_max);
> -	WARN_ON(target_min > target_max);
> -
> -	/* defensive */
> -	source_val = clamp(source_val, source_min, source_max);
> -
> -	/* avoid overflows */
> -	target_val = mul_u32_u32(source_val - source_min,
> -				 target_max - target_min);
> -	target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min);
> -	target_val += target_min;
> -
> -	return target_val;
> -}
> -
> -/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
> - * to [hw_min..hw_max]. */
> -static u32 clamp_user_to_hw(struct intel_connector *connector,
> -			    u32 user_level, u32 user_max)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -	u32 hw_level;
> -
> -	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
> -	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
> -
> -	return hw_level;
> -}
> -
> -/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
> -static u32 scale_hw_to_user(struct intel_connector *connector,
> -			    u32 hw_level, u32 user_max)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -
> -	return scale(hw_level, panel->backlight.min, panel->backlight.max,
> -		     0, user_max);
> -}
> -
> -u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
> -
> -	if (dev_priv->params.invert_brightness < 0)
> -		return val;
> -
> -	if (dev_priv->params.invert_brightness > 0 ||
> -	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
> -		return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min;
> -	}
> -
> -	return val;
> -}
> -
> -void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val);
> -	panel->backlight.pwm_funcs->set(conn_state, val);
> -}
> -
> -u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	drm_WARN_ON_ONCE(&dev_priv->drm,
> -			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
> -
> -	val = scale(val, panel->backlight.min, panel->backlight.max,
> -		    panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
> -
> -	return intel_panel_invert_pwm_level(connector, val);
> -}
> -
> -u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	drm_WARN_ON_ONCE(&dev_priv->drm,
> -			 panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
> -
> -	if (dev_priv->params.invert_brightness > 0 ||
> -	    (dev_priv->params.invert_brightness == 0 && dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS))
> -		val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min);
> -
> -	return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max,
> -		     panel->backlight.min, panel->backlight.max);
> -}
> -
> -static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
> -}
> -
> -static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> -}
> -
> -static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 val;
> -
> -	val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> -	if (DISPLAY_VER(dev_priv) < 4)
> -		val >>= 1;
> -
> -	if (panel->backlight.combination_mode) {
> -		u8 lbpc;
> -
> -		pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc);
> -		val *= lbpc;
> -	}
> -
> -	return val;
> -}
> -
> -static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
> -		return 0;
> -
> -	return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
> -}
> -
> -static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	return intel_de_read(dev_priv,
> -			     BXT_BLC_PWM_DUTY(panel->backlight.controller));
> -}
> -
> -static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -	struct pwm_state state;
> -
> -	pwm_get_state(panel->backlight.pwm, &state);
> -	return pwm_get_relative_duty_cycle(&state, 100);
> -}
> -
> -static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level);
> -}
> -
> -static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	u32 tmp;
> -
> -	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> -	intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level);
> -}
> -
> -static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 tmp, mask;
> -
> -	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
> -
> -	if (panel->backlight.combination_mode) {
> -		u8 lbpc;
> -
> -		lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1;
> -		level /= lbpc;
> -		pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc);
> -	}
> -
> -	if (DISPLAY_VER(dev_priv) == 4) {
> -		mask = BACKLIGHT_DUTY_CYCLE_MASK;
> -	} else {
> -		level <<= 1;
> -		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
> -	}
> -
> -	tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask;
> -	intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level);
> -}
> -
> -static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
> -	u32 tmp;
> -
> -	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> -	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level);
> -}
> -
> -static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	intel_de_write(dev_priv,
> -		       BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
> -}
> -
> -static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
> -
> -	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
> -	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> -}
> -
> -static void
> -intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level);
> -
> -	panel->backlight.funcs->set(conn_state, level);
> -}
> -
> -/* set backlight brightness to level in range [0..max], assuming hw min is
> - * respected.
> - */
> -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
> -				    u32 user_level, u32 user_max)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 hw_level;
> -
> -	/*
> -	 * Lack of crtc may occur during driver init because
> -	 * connection_mutex isn't held across the entire backlight
> -	 * setup + modeset readout, and the BIOS can issue the
> -	 * requests at any time.
> -	 */
> -	if (!panel->backlight.present || !conn_state->crtc)
> -		return;
> -
> -	mutex_lock(&dev_priv->backlight_lock);
> -
> -	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
> -
> -	hw_level = clamp_user_to_hw(connector, user_level, user_max);
> -	panel->backlight.level = hw_level;
> -
> -	if (panel->backlight.device)
> -		panel->backlight.device->props.brightness =
> -			scale_hw_to_user(connector,
> -					 panel->backlight.level,
> -					 panel->backlight.device->props.max_brightness);
> -
> -	if (panel->backlight.enabled)
> -		intel_panel_actually_set_backlight(conn_state, hw_level);
> -
> -	mutex_unlock(&dev_priv->backlight_lock);
> -}
> -
> -static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	u32 tmp;
> -
> -	intel_panel_set_pwm_level(old_conn_state, level);
> -
> -	/*
> -	 * Although we don't support or enable CPU PWM with LPT/SPT based
> -	 * systems, it may have been enabled prior to loading the
> -	 * driver. Disable to avoid warnings on LCPLL disable.
> -	 *
> -	 * This needs rework if we need to add support for CPU PWM on PCH split
> -	 * platforms.
> -	 */
> -	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> -	if (tmp & BLM_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "cpu backlight was enabled, disabling\n");
> -		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
> -			       tmp & ~BLM_PWM_ENABLE);
> -	}
> -
> -	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
> -}
> -
> -static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	u32 tmp;
> -
> -	intel_panel_set_pwm_level(old_conn_state, val);
> -
> -	tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> -	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
> -
> -	tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
> -}
> -
> -static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> -{
> -	intel_panel_set_pwm_level(old_conn_state, val);
> -}
> -
> -static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev);
> -	u32 tmp;
> -
> -	intel_panel_set_pwm_level(old_conn_state, val);
> -
> -	tmp = intel_de_read(dev_priv, BLC_PWM_CTL2);
> -	intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
> -}
> -
> -static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe;
> -	u32 tmp;
> -
> -	intel_panel_set_pwm_level(old_conn_state, val);
> -
> -	tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> -	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
> -		       tmp & ~BLM_PWM_ENABLE);
> -}
> -
> -static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 tmp;
> -
> -	intel_panel_set_pwm_level(old_conn_state, val);
> -
> -	tmp = intel_de_read(dev_priv,
> -			    BXT_BLC_PWM_CTL(panel->backlight.controller));
> -	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> -		       tmp & ~BXT_BLC_PWM_ENABLE);
> -
> -	if (panel->backlight.controller == 1) {
> -		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
> -		val &= ~UTIL_PIN_ENABLE;
> -		intel_de_write(dev_priv, UTIL_PIN_CTL, val);
> -	}
> -}
> -
> -static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 tmp;
> -
> -	intel_panel_set_pwm_level(old_conn_state, val);
> -
> -	tmp = intel_de_read(dev_priv,
> -			    BXT_BLC_PWM_CTL(panel->backlight.controller));
> -	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> -		       tmp & ~BXT_BLC_PWM_ENABLE);
> -}
> -
> -static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	panel->backlight.pwm_state.enabled = false;
> -	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> -}
> -
> -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state)
> -{
> -	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	if (!panel->backlight.present)
> -		return;
> -
> -	/*
> -	 * Do not disable backlight on the vga_switcheroo path. When switching
> -	 * away from i915, the other client may depend on i915 to handle the
> -	 * backlight. This will leave the backlight on unnecessarily when
> -	 * another client is not activated.
> -	 */
> -	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Skipping backlight disable on vga switch\n");
> -		return;
> -	}
> -
> -	mutex_lock(&dev_priv->backlight_lock);
> -
> -	if (panel->backlight.device)
> -		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
> -	panel->backlight.enabled = false;
> -	panel->backlight.funcs->disable(old_conn_state, 0);
> -
> -	mutex_unlock(&dev_priv->backlight_lock);
> -}
> -
> -static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				 const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 pch_ctl1, pch_ctl2, schicken;
> -
> -	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
> -		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> -		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> -	}
> -
> -	if (HAS_PCH_LPT(dev_priv)) {
> -		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2);
> -		if (panel->backlight.alternate_pwm_increment)
> -			schicken |= LPT_PWM_GRANULARITY;
> -		else
> -			schicken &= ~LPT_PWM_GRANULARITY;
> -		intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken);
> -	} else {
> -		schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1);
> -		if (panel->backlight.alternate_pwm_increment)
> -			schicken |= SPT_PWM_GRANULARITY;
> -		else
> -			schicken &= ~SPT_PWM_GRANULARITY;
> -		intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken);
> -	}
> -
> -	pch_ctl2 = panel->backlight.pwm_level_max << 16;
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
> -
> -	pch_ctl1 = 0;
> -	if (panel->backlight.active_low_pwm)
> -		pch_ctl1 |= BLM_PCH_POLARITY;
> -
> -	/* After LPT, override is the default. */
> -	if (HAS_PCH_LPT(dev_priv))
> -		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
> -
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> -	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
> -		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
> -
> -	/* This won't stick until the above enable. */
> -	intel_panel_set_pwm_level(conn_state, level);
> -}
> -
> -static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				 const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> -	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
> -
> -	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> -	if (cpu_ctl2 & BLM_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n");
> -		cpu_ctl2 &= ~BLM_PWM_ENABLE;
> -		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
> -	}
> -
> -	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n");
> -		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> -		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> -	}
> -
> -	if (cpu_transcoder == TRANSCODER_EDP)
> -		cpu_ctl2 = BLM_TRANSCODER_EDP;
> -	else
> -		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
> -	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2);
> -	intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2);
> -	intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
> -
> -	/* This won't stick until the above enable. */
> -	intel_panel_set_pwm_level(conn_state, level);
> -
> -	pch_ctl2 = panel->backlight.pwm_level_max << 16;
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
> -
> -	pch_ctl1 = 0;
> -	if (panel->backlight.active_low_pwm)
> -		pch_ctl1 |= BLM_PCH_POLARITY;
> -
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1);
> -	intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
> -		       pch_ctl1 | BLM_PCH_PWM_ENABLE);
> -}
> -
> -static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 ctl, freq;
> -
> -	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
> -	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
> -		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> -		intel_de_write(dev_priv, BLC_PWM_CTL, 0);
> -	}
> -
> -	freq = panel->backlight.pwm_level_max;
> -	if (panel->backlight.combination_mode)
> -		freq /= 0xff;
> -
> -	ctl = freq << 17;
> -	if (panel->backlight.combination_mode)
> -		ctl |= BLM_LEGACY_MODE;
> -	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
> -		ctl |= BLM_POLARITY_PNV;
> -
> -	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
> -	intel_de_posting_read(dev_priv, BLC_PWM_CTL);
> -
> -	/* XXX: combine this into above write? */
> -	intel_panel_set_pwm_level(conn_state, level);
> -
> -	/*
> -	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
> -	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
> -	 * that has backlight.
> -	 */
> -	if (DISPLAY_VER(dev_priv) == 2)
> -		intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
> -}
> -
> -static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
> -	u32 ctl, ctl2, freq;
> -
> -	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
> -	if (ctl2 & BLM_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> -		ctl2 &= ~BLM_PWM_ENABLE;
> -		intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
> -	}
> -
> -	freq = panel->backlight.pwm_level_max;
> -	if (panel->backlight.combination_mode)
> -		freq /= 0xff;
> -
> -	ctl = freq << 16;
> -	intel_de_write(dev_priv, BLC_PWM_CTL, ctl);
> -
> -	ctl2 = BLM_PIPE(pipe);
> -	if (panel->backlight.combination_mode)
> -		ctl2 |= BLM_COMBINATION_MODE;
> -	if (panel->backlight.active_low_pwm)
> -		ctl2 |= BLM_POLARITY_I965;
> -	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
> -	intel_de_posting_read(dev_priv, BLC_PWM_CTL2);
> -	intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
> -
> -	intel_panel_set_pwm_level(conn_state, level);
> -}
> -
> -static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				 const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> -	u32 ctl, ctl2;
> -
> -	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> -	if (ctl2 & BLM_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> -		ctl2 &= ~BLM_PWM_ENABLE;
> -		intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
> -	}
> -
> -	ctl = panel->backlight.pwm_level_max << 16;
> -	intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl);
> -
> -	/* XXX: combine this into above write? */
> -	intel_panel_set_pwm_level(conn_state, level);
> -
> -	ctl2 = 0;
> -	if (panel->backlight.active_low_pwm)
> -		ctl2 |= BLM_POLARITY_I965;
> -	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
> -	intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> -	intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe),
> -		       ctl2 | BLM_PWM_ENABLE);
> -}
> -
> -static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				 const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> -	u32 pwm_ctl, val;
> -
> -	/* Controller 1 uses the utility pin. */
> -	if (panel->backlight.controller == 1) {
> -		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
> -		if (val & UTIL_PIN_ENABLE) {
> -			drm_dbg_kms(&dev_priv->drm,
> -				    "util pin already enabled\n");
> -			val &= ~UTIL_PIN_ENABLE;
> -			intel_de_write(dev_priv, UTIL_PIN_CTL, val);
> -		}
> -
> -		val = 0;
> -		if (panel->backlight.util_pin_active_low)
> -			val |= UTIL_PIN_POLARITY;
> -		intel_de_write(dev_priv, UTIL_PIN_CTL,
> -			       val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
> -	}
> -
> -	pwm_ctl = intel_de_read(dev_priv,
> -				BXT_BLC_PWM_CTL(panel->backlight.controller));
> -	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> -		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
> -		intel_de_write(dev_priv,
> -			       BXT_BLC_PWM_CTL(panel->backlight.controller),
> -			       pwm_ctl);
> -	}
> -
> -	intel_de_write(dev_priv,
> -		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
> -		       panel->backlight.pwm_level_max);
> -
> -	intel_panel_set_pwm_level(conn_state, level);
> -
> -	pwm_ctl = 0;
> -	if (panel->backlight.active_low_pwm)
> -		pwm_ctl |= BXT_BLC_PWM_POLARITY;
> -
> -	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> -		       pwm_ctl);
> -	intel_de_posting_read(dev_priv,
> -			      BXT_BLC_PWM_CTL(panel->backlight.controller));
> -	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> -		       pwm_ctl | BXT_BLC_PWM_ENABLE);
> -}
> -
> -static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				 const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 pwm_ctl;
> -
> -	pwm_ctl = intel_de_read(dev_priv,
> -				BXT_BLC_PWM_CTL(panel->backlight.controller));
> -	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
> -		drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n");
> -		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
> -		intel_de_write(dev_priv,
> -			       BXT_BLC_PWM_CTL(panel->backlight.controller),
> -			       pwm_ctl);
> -	}
> -
> -	intel_de_write(dev_priv,
> -		       BXT_BLC_PWM_FREQ(panel->backlight.controller),
> -		       panel->backlight.pwm_level_max);
> -
> -	intel_panel_set_pwm_level(conn_state, level);
> -
> -	pwm_ctl = 0;
> -	if (panel->backlight.active_low_pwm)
> -		pwm_ctl |= BXT_BLC_PWM_POLARITY;
> -
> -	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> -		       pwm_ctl);
> -	intel_de_posting_read(dev_priv,
> -			      BXT_BLC_PWM_CTL(panel->backlight.controller));
> -	intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller),
> -		       pwm_ctl | BXT_BLC_PWM_ENABLE);
> -}
> -
> -static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				     const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
> -	panel->backlight.pwm_state.enabled = true;
> -	pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> -}
> -
> -static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
> -					   const struct drm_connector_state *conn_state)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	WARN_ON(panel->backlight.max == 0);
> -
> -	if (panel->backlight.level <= panel->backlight.min) {
> -		panel->backlight.level = panel->backlight.max;
> -		if (panel->backlight.device)
> -			panel->backlight.device->props.brightness =
> -				scale_hw_to_user(connector,
> -						 panel->backlight.level,
> -						 panel->backlight.device->props.max_brightness);
> -	}
> -
> -	panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level);
> -	panel->backlight.enabled = true;
> -	if (panel->backlight.device)
> -		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
> -}
> -
> -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state *conn_state)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> -
> -	if (!panel->backlight.present)
> -		return;
> -
> -	drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe));
> -
> -	mutex_lock(&dev_priv->backlight_lock);
> -
> -	__intel_panel_enable_backlight(crtc_state, conn_state);
> -
> -	mutex_unlock(&dev_priv->backlight_lock);
> -}
> -
> -#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
> -static u32 intel_panel_get_backlight(struct intel_connector *connector)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 val = 0;
> -
> -	mutex_lock(&dev_priv->backlight_lock);
> -
> -	if (panel->backlight.enabled)
> -		val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector));
> -
> -	mutex_unlock(&dev_priv->backlight_lock);
> -
> -	drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val);
> -	return val;
> -}
> -
> -/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
> -static u32 scale_user_to_hw(struct intel_connector *connector,
> -			    u32 user_level, u32 user_max)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -
> -	return scale(user_level, 0, user_max,
> -		     panel->backlight.min, panel->backlight.max);
> -}
> -
> -/* set backlight brightness to level in range [0..max], scaling wrt hw min */
> -static void intel_panel_set_backlight(const struct drm_connector_state *conn_state,
> -				      u32 user_level, u32 user_max)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 hw_level;
> -
> -	if (!panel->backlight.present)
> -		return;
> -
> -	mutex_lock(&dev_priv->backlight_lock);
> -
> -	drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
> -
> -	hw_level = scale_user_to_hw(connector, user_level, user_max);
> -	panel->backlight.level = hw_level;
> -
> -	if (panel->backlight.enabled)
> -		intel_panel_actually_set_backlight(conn_state, hw_level);
> -
> -	mutex_unlock(&dev_priv->backlight_lock);
> -}
> -
> -static int intel_backlight_device_update_status(struct backlight_device *bd)
> -{
> -	struct intel_connector *connector = bl_get_data(bd);
> -	struct intel_panel *panel = &connector->panel;
> -	struct drm_device *dev = connector->base.dev;
> -
> -	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> -	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
> -		      bd->props.brightness, bd->props.max_brightness);
> -	intel_panel_set_backlight(connector->base.state, bd->props.brightness,
> -				  bd->props.max_brightness);
> -
> -	/*
> -	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
> -	 * backlight class device does not make it easy to to differentiate
> -	 * between callbacks for brightness and bl_power, so our backlight_power
> -	 * callback needs to take this into account.
> -	 */
> -	if (panel->backlight.enabled) {
> -		if (panel->backlight.power) {
> -			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
> -				bd->props.brightness != 0;
> -			panel->backlight.power(connector, enable);
> -		}
> -	} else {
> -		bd->props.power = FB_BLANK_POWERDOWN;
> -	}
> -
> -	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> -	return 0;
> -}
> -
> -static int intel_backlight_device_get_brightness(struct backlight_device *bd)
> -{
> -	struct intel_connector *connector = bl_get_data(bd);
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	intel_wakeref_t wakeref;
> -	int ret = 0;
> -
> -	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
> -		u32 hw_level;
> -
> -		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> -
> -		hw_level = intel_panel_get_backlight(connector);
> -		ret = scale_hw_to_user(connector,
> -				       hw_level, bd->props.max_brightness);
> -
> -		drm_modeset_unlock(&dev->mode_config.connection_mutex);
> -	}
> -
> -	return ret;
> -}
> -
> -static const struct backlight_ops intel_backlight_device_ops = {
> -	.update_status = intel_backlight_device_update_status,
> -	.get_brightness = intel_backlight_device_get_brightness,
> -};
> -
> -int intel_backlight_device_register(struct intel_connector *connector)
> -{
> -	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	struct backlight_properties props;
> -	struct backlight_device *bd;
> -	const char *name;
> -	int ret = 0;
> -
> -	if (WARN_ON(panel->backlight.device))
> -		return -ENODEV;
> -
> -	if (!panel->backlight.present)
> -		return 0;
> -
> -	WARN_ON(panel->backlight.max == 0);
> -
> -	memset(&props, 0, sizeof(props));
> -	props.type = BACKLIGHT_RAW;
> -
> -	/*
> -	 * Note: Everything should work even if the backlight device max
> -	 * presented to the userspace is arbitrarily chosen.
> -	 */
> -	props.max_brightness = panel->backlight.max;
> -	props.brightness = scale_hw_to_user(connector,
> -					    panel->backlight.level,
> -					    props.max_brightness);
> -
> -	if (panel->backlight.enabled)
> -		props.power = FB_BLANK_UNBLANK;
> -	else
> -		props.power = FB_BLANK_POWERDOWN;
> -
> -	name = kstrdup("intel_backlight", GFP_KERNEL);
> -	if (!name)
> -		return -ENOMEM;
> -
> -	bd = backlight_device_register(name, connector->base.kdev, connector,
> -				       &intel_backlight_device_ops, &props);
> -
> -	/*
> -	 * Using the same name independent of the drm device or connector
> -	 * prevents registration of multiple backlight devices in the
> -	 * driver. However, we need to use the default name for backward
> -	 * compatibility. Use unique names for subsequent backlight devices as a
> -	 * fallback when the default name already exists.
> -	 */
> -	if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) {
> -		kfree(name);
> -		name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
> -				 i915->drm.primary->index, connector->base.name);
> -		if (!name)
> -			return -ENOMEM;
> -
> -		bd = backlight_device_register(name, connector->base.kdev, connector,
> -					       &intel_backlight_device_ops, &props);
> -	}
> -
> -	if (IS_ERR(bd)) {
> -		drm_err(&i915->drm,
> -			"[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n",
> -			connector->base.base.id, connector->base.name, name, PTR_ERR(bd));
> -		ret = PTR_ERR(bd);
> -		goto out;
> -	}
> -
> -	panel->backlight.device = bd;
> -
> -	drm_dbg_kms(&i915->drm,
> -		    "[CONNECTOR:%d:%s] backlight device %s registered\n",
> -		    connector->base.base.id, connector->base.name, name);
> -
> -out:
> -	kfree(name);
> -
> -	return ret;
> -}
> -
> -void intel_backlight_device_unregister(struct intel_connector *connector)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -
> -	if (panel->backlight.device) {
> -		backlight_device_unregister(panel->backlight.device);
> -		panel->backlight.device = NULL;
> -	}
> -}
> -#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> -
> -/*
> - * CNP: PWM clock frequency is 19.2 MHz or 24 MHz.
> - *      PWM increment = 1
> - */
> -static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
> -				 pwm_freq_hz);
> -}
> -
> -/*
> - * BXT: PWM clock frequency = 19.2 MHz.
> - */
> -static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
> -}
> -
> -/*
> - * SPT: This value represents the period of the PWM stream in clock periods
> - * multiplied by 16 (default increment) or 128 (alternate increment selected in
> - * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
> - */
> -static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -	u32 mul;
> -
> -	if (panel->backlight.alternate_pwm_increment)
> -		mul = 128;
> -	else
> -		mul = 16;
> -
> -	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
> -}
> -
> -/*
> - * LPT: This value represents the period of the PWM stream in clock periods
> - * multiplied by 128 (default increment) or 16 (alternate increment, selected in
> - * LPT SOUTH_CHICKEN2 register bit 5).
> - */
> -static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 mul, clock;
> -
> -	if (panel->backlight.alternate_pwm_increment)
> -		mul = 16;
> -	else
> -		mul = 128;
> -
> -	if (HAS_PCH_LPT_H(dev_priv))
> -		clock = MHz(135); /* LPT:H */
> -	else
> -		clock = MHz(24); /* LPT:LP */
> -
> -	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
> -}
> -
> -/*
> - * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
> - * display raw clocks multiplied by 128.
> - */
> -static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),
> -				 pwm_freq_hz * 128);
> -}
> -
> -/*
> - * Gen2: This field determines the number of time base events (display core
> - * clock frequency/32) in total for a complete cycle of modulated backlight
> - * control.
> - *
> - * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
> - * divided by 32.
> - */
> -static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	int clock;
> -
> -	if (IS_PINEVIEW(dev_priv))
> -		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
> -	else
> -		clock = KHz(dev_priv->cdclk.hw.cdclk);
> -
> -	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
> -}
> -
> -/*
> - * Gen4: This value represents the period of the PWM stream in display core
> - * clocks ([DevCTG] HRAW clocks) multiplied by 128.
> - *
> - */
> -static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	int clock;
> -
> -	if (IS_G4X(dev_priv))
> -		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
> -	else
> -		clock = KHz(dev_priv->cdclk.hw.cdclk);
> -
> -	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
> -}
> -
> -/*
> - * VLV: This value represents the period of the PWM stream in display core
> - * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
> - * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
> - */
> -static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	int mul, clock;
> -
> -	if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
> -		if (IS_CHERRYVIEW(dev_priv))
> -			clock = KHz(19200);
> -		else
> -			clock = MHz(25);
> -		mul = 16;
> -	} else {
> -		clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
> -		mul = 128;
> -	}
> -
> -	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
> -}
> -
> -static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv)
> -{
> -	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
> -
> -	if (pwm_freq_hz) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "VBT defined backlight frequency %u Hz\n",
> -			    pwm_freq_hz);
> -	} else {
> -		pwm_freq_hz = 200;
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "default backlight frequency %u Hz\n",
> -			    pwm_freq_hz);
> -	}
> -
> -	return pwm_freq_hz;
> -}
> -
> -static u32 get_backlight_max_vbt(struct intel_connector *connector)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
> -	u32 pwm;
> -
> -	if (!panel->backlight.pwm_funcs->hz_to_pwm) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "backlight frequency conversion not supported\n");
> -		return 0;
> -	}
> -
> -	pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz);
> -	if (!pwm) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "backlight frequency conversion failed\n");
> -		return 0;
> -	}
> -
> -	return pwm;
> -}
> -
> -/*
> - * Note: The setup hooks can't assume pipe is set!
> - */
> -static u32 get_backlight_min_vbt(struct intel_connector *connector)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	int min;
> -
> -	drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
> -
> -	/*
> -	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
> -	 * to problems. There are such machines out there. Either our
> -	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
> -	 * against this by letting the minimum be at most (arbitrarily chosen)
> -	 * 25% of the max.
> -	 */
> -	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
> -	if (min != dev_priv->vbt.backlight.min_brightness) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "clamping VBT min backlight %d/255 to %d/255\n",
> -			    dev_priv->vbt.backlight.min_brightness, min);
> -	}
> -
> -	/* vbt value is a coefficient in range [0..255] */
> -	return scale(min, 0, 255, 0, panel->backlight.pwm_level_max);
> -}
> -
> -static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
> -	bool alt, cpu_mode;
> -
> -	if (HAS_PCH_LPT(dev_priv))
> -		alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
> -	else
> -		alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
> -	panel->backlight.alternate_pwm_increment = alt;
> -
> -	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> -
> -	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
> -	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
> -
> -	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
> -
> -	cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) &&
> -		   !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) &&
> -		   (cpu_ctl2 & BLM_PWM_ENABLE);
> -
> -	if (cpu_mode) {
> -		val = pch_get_backlight(connector, unused);
> -
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "CPU backlight register was enabled, switching to PCH override\n");
> -
> -		/* Write converted CPU PWM value to PCH override register */
> -		lpt_set_backlight(connector->base.state, val);
> -		intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
> -			       pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE);
> -
> -		intel_de_write(dev_priv, BLC_PWM_CPU_CTL2,
> -			       cpu_ctl2 & ~BLM_PWM_ENABLE);
> -	}
> -
> -	return 0;
> -}
> -
> -static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
> -
> -	pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1);
> -	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> -
> -	pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
> -	panel->backlight.pwm_level_max = pch_ctl2 >> 16;
> -
> -	if (!panel->backlight.pwm_level_max)
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
> -	panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
> -		(pch_ctl1 & BLM_PCH_PWM_ENABLE);
> -
> -	return 0;
> -}
> -
> -static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 ctl, val;
> -
> -	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
> -
> -	if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
> -		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
> -
> -	if (IS_PINEVIEW(dev_priv))
> -		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
> -
> -	panel->backlight.pwm_level_max = ctl >> 17;
> -
> -	if (!panel->backlight.pwm_level_max) {
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -		panel->backlight.pwm_level_max >>= 1;
> -	}
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	if (panel->backlight.combination_mode)
> -		panel->backlight.pwm_level_max *= 0xff;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	val = i9xx_get_backlight(connector, unused);
> -	val = intel_panel_invert_pwm_level(connector, val);
> -	val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
> -
> -	panel->backlight.pwm_enabled = val != 0;
> -
> -	return 0;
> -}
> -
> -static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 ctl, ctl2;
> -
> -	ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2);
> -	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
> -	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
> -
> -	ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
> -	panel->backlight.pwm_level_max = ctl >> 16;
> -
> -	if (!panel->backlight.pwm_level_max)
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	if (panel->backlight.combination_mode)
> -		panel->backlight.pwm_level_max *= 0xff;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
> -
> -	return 0;
> -}
> -
> -static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 ctl, ctl2;
> -
> -	if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
> -		return -ENODEV;
> -
> -	ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe));
> -	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
> -
> -	ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe));
> -	panel->backlight.pwm_level_max = ctl >> 16;
> -
> -	if (!panel->backlight.pwm_level_max)
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
> -
> -	return 0;
> -}
> -
> -static int
> -bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 pwm_ctl, val;
> -
> -	panel->backlight.controller = dev_priv->vbt.backlight.controller;
> -
> -	pwm_ctl = intel_de_read(dev_priv,
> -				BXT_BLC_PWM_CTL(panel->backlight.controller));
> -
> -	/* Controller 1 uses the utility pin. */
> -	if (panel->backlight.controller == 1) {
> -		val = intel_de_read(dev_priv, UTIL_PIN_CTL);
> -		panel->backlight.util_pin_active_low =
> -					val & UTIL_PIN_POLARITY;
> -	}
> -
> -	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
> -	panel->backlight.pwm_level_max =
> -		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
> -
> -	if (!panel->backlight.pwm_level_max)
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
> -
> -	return 0;
> -}
> -
> -static int
> -cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -	u32 pwm_ctl;
> -
> -	/*
> -	 * CNP has the BXT implementation of backlight, but with only one
> -	 * controller. TODO: ICP has multiple controllers but we only use
> -	 * controller 0 for now.
> -	 */
> -	panel->backlight.controller = 0;
> -
> -	pwm_ctl = intel_de_read(dev_priv,
> -				BXT_BLC_PWM_CTL(panel->backlight.controller));
> -
> -	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
> -	panel->backlight.pwm_level_max =
> -		intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
> -
> -	if (!panel->backlight.pwm_level_max)
> -		panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
> -
> -	if (!panel->backlight.pwm_level_max)
> -		return -ENODEV;
> -
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
> -
> -	return 0;
> -}
> -
> -static int ext_pwm_setup_backlight(struct intel_connector *connector,
> -				   enum pipe pipe)
> -{
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_panel *panel = &connector->panel;
> -	const char *desc;
> -	u32 level;
> -
> -	/* Get the right PWM chip for DSI backlight according to VBT */
> -	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
> -		panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
> -		desc = "PMIC";
> -	} else {
> -		panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight");
> -		desc = "SoC";
> -	}
> -
> -	if (IS_ERR(panel->backlight.pwm)) {
> -		drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n",
> -			desc);
> -		panel->backlight.pwm = NULL;
> -		return -ENODEV;
> -	}
> -
> -	panel->backlight.pwm_level_max = 100; /* 100% */
> -	panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
> -
> -	if (pwm_is_enabled(panel->backlight.pwm)) {
> -		/* PWM is already enabled, use existing settings */
> -		pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state);
> -
> -		level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state,
> -						    100);
> -		level = intel_panel_invert_pwm_level(connector, level);
> -		panel->backlight.pwm_enabled = true;
> -
> -		drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",
> -			    NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,
> -			    get_vbt_pwm_freq(dev_priv), level);
> -	} else {
> -		/* Set period from VBT frequency, leave other settings at 0. */
> -		panel->backlight.pwm_state.period =
> -			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
> -	}
> -
> -	drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
> -		 desc);
> -	return 0;
> -}
> -
> -static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	panel->backlight.pwm_funcs->set(conn_state,
> -				       intel_panel_invert_pwm_level(connector, level));
> -}
> -
> -static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -
> -	return intel_panel_invert_pwm_level(connector,
> -					    panel->backlight.pwm_funcs->get(connector, pipe));
> -}
> -
> -static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				       const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	panel->backlight.pwm_funcs->enable(crtc_state, conn_state,
> -					   intel_panel_invert_pwm_level(connector, level));
> -}
> -
> -static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	panel->backlight.pwm_funcs->disable(conn_state,
> -					    intel_panel_invert_pwm_level(connector, level));
> -}
> -
> -static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe)
> -{
> -	struct intel_panel *panel = &connector->panel;
> -	int ret = panel->backlight.pwm_funcs->setup(connector, pipe);
> -
> -	if (ret < 0)
> -		return ret;
> -
> -	panel->backlight.min = panel->backlight.pwm_level_min;
> -	panel->backlight.max = panel->backlight.pwm_level_max;
> -	panel->backlight.level = intel_pwm_get_backlight(connector, pipe);
> -	panel->backlight.enabled = panel->backlight.pwm_enabled;
> -
> -	return 0;
> -}
> -
> -void intel_panel_update_backlight(struct intel_atomic_state *state,
> -				  struct intel_encoder *encoder,
> -				  const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state *conn_state)
> -{
> -	struct intel_connector *connector = to_intel_connector(conn_state->connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct intel_panel *panel = &connector->panel;
> -
> -	if (!panel->backlight.present)
> -		return;
> -
> -	mutex_lock(&dev_priv->backlight_lock);
> -	if (!panel->backlight.enabled)
> -		__intel_panel_enable_backlight(crtc_state, conn_state);
> -
> -	mutex_unlock(&dev_priv->backlight_lock);
> -}
> -
> -int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> -	struct intel_connector *intel_connector = to_intel_connector(connector);
> -	struct intel_panel *panel = &intel_connector->panel;
> -	int ret;
> -
> -	if (!dev_priv->vbt.backlight.present) {
> -		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
> -			drm_dbg_kms(&dev_priv->drm,
> -				    "no backlight present per VBT, but present per quirk\n");
> -		} else {
> -			drm_dbg_kms(&dev_priv->drm,
> -				    "no backlight present per VBT\n");
> -			return 0;
> -		}
> -	}
> -
> -	/* ensure intel_panel has been initialized first */
> -	if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs))
> -		return -ENODEV;
> -
> -	/* set level and max in panel struct */
> -	mutex_lock(&dev_priv->backlight_lock);
> -	ret = panel->backlight.funcs->setup(intel_connector, pipe);
> -	mutex_unlock(&dev_priv->backlight_lock);
> -
> -	if (ret) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "failed to setup backlight for connector %s\n",
> -			    connector->name);
> -		return ret;
> -	}
> -
> -	panel->backlight.present = true;
> -
> -	drm_dbg_kms(&dev_priv->drm,
> -		    "Connector %s backlight initialized, %s, brightness %u/%u\n",
> -		    connector->name,
> -		    enableddisabled(panel->backlight.enabled),
> -		    panel->backlight.level, panel->backlight.max);
> -
> -	return 0;
> -}
> -
> -static void intel_panel_destroy_backlight(struct intel_panel *panel)
> -{
> -	/* dispose of the pwm */
> -	if (panel->backlight.pwm)
> -		pwm_put(panel->backlight.pwm);
> -
> -	panel->backlight.present = false;
> -}
> -
> -static const struct intel_panel_bl_funcs bxt_pwm_funcs = {
> -	.setup = bxt_setup_backlight,
> -	.enable = bxt_enable_backlight,
> -	.disable = bxt_disable_backlight,
> -	.set = bxt_set_backlight,
> -	.get = bxt_get_backlight,
> -	.hz_to_pwm = bxt_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs cnp_pwm_funcs = {
> -	.setup = cnp_setup_backlight,
> -	.enable = cnp_enable_backlight,
> -	.disable = cnp_disable_backlight,
> -	.set = bxt_set_backlight,
> -	.get = bxt_get_backlight,
> -	.hz_to_pwm = cnp_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs lpt_pwm_funcs = {
> -	.setup = lpt_setup_backlight,
> -	.enable = lpt_enable_backlight,
> -	.disable = lpt_disable_backlight,
> -	.set = lpt_set_backlight,
> -	.get = lpt_get_backlight,
> -	.hz_to_pwm = lpt_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs spt_pwm_funcs = {
> -	.setup = lpt_setup_backlight,
> -	.enable = lpt_enable_backlight,
> -	.disable = lpt_disable_backlight,
> -	.set = lpt_set_backlight,
> -	.get = lpt_get_backlight,
> -	.hz_to_pwm = spt_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs pch_pwm_funcs = {
> -	.setup = pch_setup_backlight,
> -	.enable = pch_enable_backlight,
> -	.disable = pch_disable_backlight,
> -	.set = pch_set_backlight,
> -	.get = pch_get_backlight,
> -	.hz_to_pwm = pch_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs ext_pwm_funcs = {
> -	.setup = ext_pwm_setup_backlight,
> -	.enable = ext_pwm_enable_backlight,
> -	.disable = ext_pwm_disable_backlight,
> -	.set = ext_pwm_set_backlight,
> -	.get = ext_pwm_get_backlight,
> -};
> -
> -static const struct intel_panel_bl_funcs vlv_pwm_funcs = {
> -	.setup = vlv_setup_backlight,
> -	.enable = vlv_enable_backlight,
> -	.disable = vlv_disable_backlight,
> -	.set = vlv_set_backlight,
> -	.get = vlv_get_backlight,
> -	.hz_to_pwm = vlv_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs i965_pwm_funcs = {
> -	.setup = i965_setup_backlight,
> -	.enable = i965_enable_backlight,
> -	.disable = i965_disable_backlight,
> -	.set = i9xx_set_backlight,
> -	.get = i9xx_get_backlight,
> -	.hz_to_pwm = i965_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs i9xx_pwm_funcs = {
> -	.setup = i9xx_setup_backlight,
> -	.enable = i9xx_enable_backlight,
> -	.disable = i9xx_disable_backlight,
> -	.set = i9xx_set_backlight,
> -	.get = i9xx_get_backlight,
> -	.hz_to_pwm = i9xx_hz_to_pwm,
> -};
> -
> -static const struct intel_panel_bl_funcs pwm_bl_funcs = {
> -	.setup = intel_pwm_setup_backlight,
> -	.enable = intel_pwm_enable_backlight,
> -	.disable = intel_pwm_disable_backlight,
> -	.set = intel_pwm_set_backlight,
> -	.get = intel_pwm_get_backlight,
> -};
> -
> -/* Set up chip specific backlight functions */
> -static void
> -intel_panel_init_backlight_funcs(struct intel_panel *panel)
> -{
> -	struct intel_connector *connector =
> -		container_of(panel, struct intel_connector, panel);
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -
> -	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
> -	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
> -		return;
> -
> -	if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
> -		panel->backlight.pwm_funcs = &bxt_pwm_funcs;
> -	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
> -		panel->backlight.pwm_funcs = &cnp_pwm_funcs;
> -	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) {
> -		if (HAS_PCH_LPT(dev_priv))
> -			panel->backlight.pwm_funcs = &lpt_pwm_funcs;
> -		else
> -			panel->backlight.pwm_funcs = &spt_pwm_funcs;
> -	} else if (HAS_PCH_SPLIT(dev_priv)) {
> -		panel->backlight.pwm_funcs = &pch_pwm_funcs;
> -	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> -		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
> -			panel->backlight.pwm_funcs = &ext_pwm_funcs;
> -		} else {
> -			panel->backlight.pwm_funcs = &vlv_pwm_funcs;
> -		}
> -	} else if (DISPLAY_VER(dev_priv) == 4) {
> -		panel->backlight.pwm_funcs = &i965_pwm_funcs;
> -	} else {
> -		panel->backlight.pwm_funcs = &i9xx_pwm_funcs;
> -	}
> -
> -	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
> -	    intel_dp_aux_init_backlight_funcs(connector) == 0)
> -		return;
> -
> -	/* We're using a standard PWM backlight interface */
> -	panel->backlight.funcs = &pwm_bl_funcs;
> -}
> -
>  enum drm_connector_status
>  intel_panel_detect(struct drm_connector *connector, bool force)
>  {
> diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h
> index 1d340f77bffc7..67dbb15026bf1 100644
> --- a/drivers/gpu/drm/i915/display/intel_panel.h
> +++ b/drivers/gpu/drm/i915/display/intel_panel.h
> @@ -8,15 +8,13 @@
>  
>  #include <linux/types.h>
>  
> -#include "intel_display.h"
> -
> +enum drm_connector_status;
>  struct drm_connector;
>  struct drm_connector_state;
>  struct drm_display_mode;
> +struct drm_i915_private;
>  struct intel_connector;
> -struct intel_crtc;
>  struct intel_crtc_state;
> -struct intel_encoder;
>  struct intel_panel;
>  
>  int intel_panel_init(struct intel_panel *panel,
> @@ -31,17 +29,6 @@ int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state,
>  			    const struct drm_connector_state *conn_state);
>  int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state,
>  			     const struct drm_connector_state *conn_state);
> -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
> -				    u32 level, u32 max);
> -int intel_panel_setup_backlight(struct drm_connector *connector,
> -				enum pipe pipe);
> -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state *conn_state);
> -void intel_panel_update_backlight(struct intel_atomic_state *state,
> -				  struct intel_encoder *encoder,
> -				  const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state *conn_state);
> -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state);
>  struct drm_display_mode *
>  intel_panel_edid_downclock_mode(struct intel_connector *connector,
>  				const struct drm_display_mode *fixed_mode);
> @@ -49,22 +36,5 @@ struct drm_display_mode *
>  intel_panel_edid_fixed_mode(struct intel_connector *connector);
>  struct drm_display_mode *
>  intel_panel_vbt_fixed_mode(struct intel_connector *connector);
> -void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level);
> -u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level);
> -u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level);
> -u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val);
> -
> -#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
> -int intel_backlight_device_register(struct intel_connector *connector);
> -void intel_backlight_device_unregister(struct intel_connector *connector);
> -#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> -static inline int intel_backlight_device_register(struct intel_connector *connector)
> -{
> -	return 0;
> -}
> -static inline void intel_backlight_device_unregister(struct intel_connector *connector)
> -{
> -}
> -#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
>  
>  #endif /* __INTEL_PANEL_H__ */
> diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
> index 0ee4ff341e25d..b27738df447d0 100644
> --- a/drivers/gpu/drm/i915/display/vlv_dsi.c
> +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
> @@ -32,6 +32,7 @@
>  
>  #include "i915_drv.h"
>  #include "intel_atomic.h"
> +#include "intel_backlight.h"
>  #include "intel_connector.h"
>  #include "intel_crtc.h"
>  #include "intel_de.h"

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (110 preceding siblings ...)
  2022-09-06 21:48 ` Shuah Khan
@ 2022-09-07  4:44 ` Guenter Roeck
  2022-09-07  9:40 ` Sudip Mukherjee (Codethink)
                   ` (3 subsequent siblings)
  115 siblings, 0 replies; 133+ messages in thread
From: Guenter Roeck @ 2022-09-07  4:44 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, stable, torvalds, akpm, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	slade

On Tue, Sep 06, 2022 at 03:29:41PM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.
> 

Build results:
	total: 159 pass: 159 fail: 0
Qemu test results:
	total: 486 pass: 486 fail: 0

Tested-by: Guenter Roeck <linux@roeck-us.net>

Guenter

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules
  2022-09-06 18:45   ` Florian Fainelli
@ 2022-09-07  5:40     ` Greg Kroah-Hartman
  2022-09-07  7:02       ` Jiri Olsa
  2022-09-07  8:13       ` Ron Economos
  0 siblings, 2 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-07  5:40 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: linux-kernel, stable, Jiri Olsa, Andrii Nakryiko

On Tue, Sep 06, 2022 at 11:45:00AM -0700, Florian Fainelli wrote:
> 
> 
> On 9/6/2022 6:31 AM, Greg Kroah-Hartman wrote:
> > From: Jiri Olsa <jolsa@redhat.com>
> > 
> > commit e27f05147bff21408c1b8410ad8e90cd286e7952 upstream.
> > 
> > Using new PAHOLE_FLAGS variable to pass extra arguments to
> > pahole for both vmlinux and modules BTF data generation.
> > 
> > Adding new scripts/pahole-flags.sh script that detect and
> > prints pahole options.
> > 
> > [ fixed issues found by kernel test robot ]
> > 
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> > Acked-by: Andrii Nakryiko <andrii@kernel.org>
> > Link: https://lore.kernel.org/bpf/20211029125729.70002-1-jolsa@kernel.org
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> >   Makefile                  |    3 +++
> >   scripts/Makefile.modfinal |    2 +-
> >   scripts/link-vmlinux.sh   |   11 +----------
> >   scripts/pahole-flags.sh   |   20 ++++++++++++++++++++
> >   4 files changed, 25 insertions(+), 11 deletions(-)
> >   create mode 100755 scripts/pahole-flags.sh
> 
> My linux-stable-rc/linux-5.15.y checkout shows that scripts/pahole-flags.sh
> does not have an executable permission and commit
> 128e3cc0beffc92154d9af6bd8c107f46e830000 ("kbuild: Unify options for BTF
> generation for vmlinux and modules") does have:
> 
> diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
> new file mode 100644
> index 000000000000..e6093adf4c06
> 
> whereas your email does have the proper 100755 permission set on the file,
> any idea what happened here?

Yeah, quilt does not like dealing with file permissions at all :(

We have over time, not required executable permissions on kernel files
because of this issue.  Is it required here?  If so, I'll try to
remember to fix it up "by hand".

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 20:46 ` Sudip Mukherjee
@ 2022-09-07  5:49   ` Greg Kroah-Hartman
  2022-09-07  9:27     ` Sudip Mukherjee (Codethink)
  0 siblings, 1 reply; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-07  5:49 UTC (permalink / raw)
  To: Sudip Mukherjee
  Cc: linux-kernel, Stable, Linus Torvalds, Andrew Morton,
	Guenter Roeck, Shuah Khan, patches, lkft-triage, Pavel Machek,
	Jonathan Hunter, Florian Fainelli, slade

On Tue, Sep 06, 2022 at 09:46:37PM +0100, Sudip Mukherjee wrote:
> Hi Greg,
> 
> On Tue, Sep 6, 2022 at 2:37 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > This is the start of the stable review cycle for the 5.15.66 release.
> > There are 107 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> > Anything received after that time might be too late.
> 
> My test pipelines are still running, but x86_64 allmodconfig failed
> with gcc-12 with the error:
> 
> drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c: In function
> 'ipc_protocol_dl_td_process':
> drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:406:13: error: the
> comparison will always evaluate as 'true' for the address of 'cb' will
> never be NULL [-Werror=address]
>   406 |         if (!IPC_CB(skb)) {
>       |             ^
> In file included from drivers/net/wwan/iosm/iosm_ipc_imem.h:9,
>                  from drivers/net/wwan/iosm/iosm_ipc_protocol.h:9,
>                  from drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:6:
> ./include/linux/skbuff.h:794:33: note: 'cb' declared here
>   794 |         char                    cb[48] __aligned(8);
> 
> It will need dbbc7d04c549 ("net: wwan: iosm: remove pointless null check").

Thanks, I have not been testing any branches with gcc12 just yet because
of these issues :(

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules
  2022-09-07  5:40     ` Greg Kroah-Hartman
@ 2022-09-07  7:02       ` Jiri Olsa
  2022-09-07  8:13       ` Ron Economos
  1 sibling, 0 replies; 133+ messages in thread
From: Jiri Olsa @ 2022-09-07  7:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Florian Fainelli, linux-kernel, stable, Andrii Nakryiko

On Wed, Sep 07, 2022 at 07:40:16AM +0200, Greg Kroah-Hartman wrote:
> On Tue, Sep 06, 2022 at 11:45:00AM -0700, Florian Fainelli wrote:
> > 
> > 
> > On 9/6/2022 6:31 AM, Greg Kroah-Hartman wrote:
> > > From: Jiri Olsa <jolsa@redhat.com>
> > > 
> > > commit e27f05147bff21408c1b8410ad8e90cd286e7952 upstream.
> > > 
> > > Using new PAHOLE_FLAGS variable to pass extra arguments to
> > > pahole for both vmlinux and modules BTF data generation.
> > > 
> > > Adding new scripts/pahole-flags.sh script that detect and
> > > prints pahole options.
> > > 
> > > [ fixed issues found by kernel test robot ]
> > > 
> > > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > > Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> > > Acked-by: Andrii Nakryiko <andrii@kernel.org>
> > > Link: https://lore.kernel.org/bpf/20211029125729.70002-1-jolsa@kernel.org
> > > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > ---
> > >   Makefile                  |    3 +++
> > >   scripts/Makefile.modfinal |    2 +-
> > >   scripts/link-vmlinux.sh   |   11 +----------
> > >   scripts/pahole-flags.sh   |   20 ++++++++++++++++++++
> > >   4 files changed, 25 insertions(+), 11 deletions(-)
> > >   create mode 100755 scripts/pahole-flags.sh
> > 
> > My linux-stable-rc/linux-5.15.y checkout shows that scripts/pahole-flags.sh
> > does not have an executable permission and commit
> > 128e3cc0beffc92154d9af6bd8c107f46e830000 ("kbuild: Unify options for BTF
> > generation for vmlinux and modules") does have:
> > 
> > diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
> > new file mode 100644
> > index 000000000000..e6093adf4c06
> > 
> > whereas your email does have the proper 100755 permission set on the file,
> > any idea what happened here?
> 
> Yeah, quilt does not like dealing with file permissions at all :(
> 
> We have over time, not required executable permissions on kernel files
> because of this issue.  Is it required here?  If so, I'll try to
> remember to fix it up "by hand".

yes, pahole-flags.sh needs to have +x

thanks,
jirka

> 
> thanks,
> 
> greg k-h

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules
  2022-09-07  5:40     ` Greg Kroah-Hartman
  2022-09-07  7:02       ` Jiri Olsa
@ 2022-09-07  8:13       ` Ron Economos
  1 sibling, 0 replies; 133+ messages in thread
From: Ron Economos @ 2022-09-07  8:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Florian Fainelli
  Cc: linux-kernel, stable, Jiri Olsa, Andrii Nakryiko

On 9/6/22 10:40 PM, Greg Kroah-Hartman wrote:
> On Tue, Sep 06, 2022 at 11:45:00AM -0700, Florian Fainelli wrote:
>>
>> On 9/6/2022 6:31 AM, Greg Kroah-Hartman wrote:
>>> From: Jiri Olsa <jolsa@redhat.com>
>>>
>>> commit e27f05147bff21408c1b8410ad8e90cd286e7952 upstream.
>>>
>>> Using new PAHOLE_FLAGS variable to pass extra arguments to
>>> pahole for both vmlinux and modules BTF data generation.
>>>
>>> Adding new scripts/pahole-flags.sh script that detect and
>>> prints pahole options.
>>>
>>> [ fixed issues found by kernel test robot ]
>>>
>>> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
>>> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
>>> Acked-by: Andrii Nakryiko <andrii@kernel.org>
>>> Link: https://lore.kernel.org/bpf/20211029125729.70002-1-jolsa@kernel.org
>>> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>> ---
>>>    Makefile                  |    3 +++
>>>    scripts/Makefile.modfinal |    2 +-
>>>    scripts/link-vmlinux.sh   |   11 +----------
>>>    scripts/pahole-flags.sh   |   20 ++++++++++++++++++++
>>>    4 files changed, 25 insertions(+), 11 deletions(-)
>>>    create mode 100755 scripts/pahole-flags.sh
>> My linux-stable-rc/linux-5.15.y checkout shows that scripts/pahole-flags.sh
>> does not have an executable permission and commit
>> 128e3cc0beffc92154d9af6bd8c107f46e830000 ("kbuild: Unify options for BTF
>> generation for vmlinux and modules") does have:
>>
>> diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
>> new file mode 100644
>> index 000000000000..e6093adf4c06
>>
>> whereas your email does have the proper 100755 permission set on the file,
>> any idea what happened here?
> Yeah, quilt does not like dealing with file permissions at all :(
>
> We have over time, not required executable permissions on kernel files
> because of this issue.  Is it required here?  If so, I'll try to
> remember to fix it up "by hand".
>
> thanks,
>
> greg k-h

I'm seeing this on my RISC-V build also. The error message (repeated 
many times) is:

/bin/sh: 1: ./scripts/pahole-flags.sh: Permission denied

So the script isn't running.


^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-07  5:49   ` Greg Kroah-Hartman
@ 2022-09-07  9:27     ` Sudip Mukherjee (Codethink)
  0 siblings, 0 replies; 133+ messages in thread
From: Sudip Mukherjee (Codethink) @ 2022-09-07  9:27 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Stable, Linus Torvalds, Andrew Morton,
	Guenter Roeck, Shuah Khan, patches, lkft-triage, Pavel Machek,
	Jonathan Hunter, Florian Fainelli, slade


On Wed, Sep 07, 2022 at 07:49:29AM +0200, Greg Kroah-Hartman wrote:
> On Tue, Sep 06, 2022 at 09:46:37PM +0100, Sudip Mukherjee wrote:
> > Hi Greg,
> > 
> > On Tue, Sep 6, 2022 at 2:37 PM Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > >
> > > This is the start of the stable review cycle for the 5.15.66 release.
> > > There are 107 patches in this series, all will be posted as a response
> > > to this one.  If anyone has any issues with these being applied, please
> > > let me know.
> > >
> > > Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> > > Anything received after that time might be too late.
> > 
> > My test pipelines are still running, but x86_64 allmodconfig failed
> > with gcc-12 with the error:
> > 
> > drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c: In function
> > 'ipc_protocol_dl_td_process':
> > drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:406:13: error: the
> > comparison will always evaluate as 'true' for the address of 'cb' will
> > never be NULL [-Werror=address]
> >   406 |         if (!IPC_CB(skb)) {
> >       |             ^
> > In file included from drivers/net/wwan/iosm/iosm_ipc_imem.h:9,
> >                  from drivers/net/wwan/iosm/iosm_ipc_protocol.h:9,
> >                  from drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:6:
> > ./include/linux/skbuff.h:794:33: note: 'cb' declared here
> >   794 |         char                    cb[48] __aligned(8);
> > 
> > It will need dbbc7d04c549 ("net: wwan: iosm: remove pointless null check").
> 
> Thanks, I have not been testing any branches with gcc12 just yet because
> of these issues :(

All the other arch I build are now ok with gcc-12, except x86_64.
I will make a complete list for x86_64 today and send you.

--
Regards
Sudip

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (111 preceding siblings ...)
  2022-09-07  4:44 ` Guenter Roeck
@ 2022-09-07  9:40 ` Sudip Mukherjee (Codethink)
  2022-09-07 11:30   ` Sudip Mukherjee
  2022-09-07  9:52 ` Bagas Sanjaya
                   ` (2 subsequent siblings)
  115 siblings, 1 reply; 133+ messages in thread
From: Sudip Mukherjee (Codethink) @ 2022-09-07  9:40 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, stable, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, slade

Hi Greg,

On Tue, Sep 06, 2022 at 03:29:41PM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.

Build test (gcc version 11.3.1 20220819):
mips: 62 configs -> no failure
arm: 99 configs -> no failure
arm64: 3 configs -> no failure
x86_64: 4 configs -> no failure
alpha allmodconfig -> no failure
csky allmodconfig -> no failure
powerpc allmodconfig -> no failure
riscv allmodconfig -> no failure
s390 allmodconfig -> no failure
xtensa allmodconfig -> no failure

Note:
Except x86_64, all the other arch I built were ok with gcc-12.

Boot test:
x86_64: Booted on my test laptop. No regression.
x86_64: Booted on qemu. No regression. [1]
arm64: Booted on rpi4b (4GB model). No regression. [2]
mips: Booted on ci20 board. No regression. [3]

[1]. https://openqa.qa.codethink.co.uk/tests/1780
[2]. https://openqa.qa.codethink.co.uk/tests/1785
[3]. https://openqa.qa.codethink.co.uk/tests/1787

Tested-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>

--
Regards
Sudip

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (112 preceding siblings ...)
  2022-09-07  9:40 ` Sudip Mukherjee (Codethink)
@ 2022-09-07  9:52 ` Bagas Sanjaya
  2022-09-07 12:48 ` Ron Economos
  2022-09-08 10:50 ` Jon Hunter
  115 siblings, 0 replies; 133+ messages in thread
From: Bagas Sanjaya @ 2022-09-07  9:52 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, stable, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	slade

[-- Attachment #1: Type: text/plain, Size: 745 bytes --]

On Tue, Sep 06, 2022 at 03:29:41PM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 

Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0) and
powerpc (ps3_defconfig, GCC 12.1.0).

However, Florian reported permission issue on pahole script [1]. The issue
is also appeared on my builds.

Thanks.

Tested-by: Bagas Sanjaya <bagasdotme@gmail.com>

[1]: https://lore.kernel.org/lkml/814a334f-c2dc-3880-8d57-8267ee4911a1@gmail.com/

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-07  9:40 ` Sudip Mukherjee (Codethink)
@ 2022-09-07 11:30   ` Sudip Mukherjee
  2022-09-07 11:45     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 133+ messages in thread
From: Sudip Mukherjee @ 2022-09-07 11:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Stable, Linus Torvalds, Andrew Morton,
	Guenter Roeck, Shuah Khan, patches, lkft-triage, Pavel Machek,
	Jonathan Hunter, Florian Fainelli, slade

On Wed, Sep 7, 2022 at 10:40 AM Sudip Mukherjee (Codethink)
<sudipm.mukherjee@gmail.com> wrote:
>
> Hi Greg,
>
> On Tue, Sep 06, 2022 at 03:29:41PM +0200, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 5.15.66 release.
> > There are 107 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> > Anything received after that time might be too late.
>
> Build test (gcc version 11.3.1 20220819):

Missed reporting that the build is full of "/bin/sh: 1:
./scripts/pahole-flags.sh: Permission denied".
On checking it turns out, the execute permission is not set in the
v5.15.y branch, but its set in v5.19.y branch.

On v5.19.y:
$ ls -l scripts/pahole-flags.sh
-rwxr-xr-x 1 sudip sudip 585 Sep  6 18:03 scripts/pahole-flags.sh

on v5.15.y:
$ ls -l scripts/pahole-flags.sh
-rw-r--r-- 1 sudip sudip 627 Sep  7 12:27 scripts/pahole-flags.sh


-- 
Regards
Sudip

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file
  2022-09-06 22:13   ` Lyude Paul
@ 2022-09-07 11:41     ` Sasha Levin
  2022-09-07 20:37       ` Lyude Paul
  0 siblings, 1 reply; 133+ messages in thread
From: Sasha Levin @ 2022-09-07 11:41 UTC (permalink / raw)
  To: Lyude Paul; +Cc: Greg Kroah-Hartman, linux-kernel, stable, Jani Nikula

On Tue, Sep 06, 2022 at 06:13:17PM -0400, Lyude Paul wrote:
>Were there parts of this series that weren't Cc'd to me via email? Trying to
>understand why this patch would be pulled in since it might be required for
>other fixes, but on it's own there should be no functional changes so it's not
>really a candidate for stable.

It's useful for the patch that immediately follows it: 868e8e5156a1
("drm/i915/display: avoid warnings when registering dual panel
backlight").

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-07 11:30   ` Sudip Mukherjee
@ 2022-09-07 11:45     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 133+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-07 11:45 UTC (permalink / raw)
  To: Sudip Mukherjee
  Cc: linux-kernel, Stable, Linus Torvalds, Andrew Morton,
	Guenter Roeck, Shuah Khan, patches, lkft-triage, Pavel Machek,
	Jonathan Hunter, Florian Fainelli, slade

On Wed, Sep 07, 2022 at 12:30:34PM +0100, Sudip Mukherjee wrote:
> On Wed, Sep 7, 2022 at 10:40 AM Sudip Mukherjee (Codethink)
> <sudipm.mukherjee@gmail.com> wrote:
> >
> > Hi Greg,
> >
> > On Tue, Sep 06, 2022 at 03:29:41PM +0200, Greg Kroah-Hartman wrote:
> > > This is the start of the stable review cycle for the 5.15.66 release.
> > > There are 107 patches in this series, all will be posted as a response
> > > to this one.  If anyone has any issues with these being applied, please
> > > let me know.
> > >
> > > Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> > > Anything received after that time might be too late.
> >
> > Build test (gcc version 11.3.1 20220819):
> 
> Missed reporting that the build is full of "/bin/sh: 1:
> ./scripts/pahole-flags.sh: Permission denied".
> On checking it turns out, the execute permission is not set in the
> v5.15.y branch, but its set in v5.19.y branch.
> 
> On v5.19.y:
> $ ls -l scripts/pahole-flags.sh
> -rwxr-xr-x 1 sudip sudip 585 Sep  6 18:03 scripts/pahole-flags.sh
> 
> on v5.15.y:
> $ ls -l scripts/pahole-flags.sh
> -rw-r--r-- 1 sudip sudip 627 Sep  7 12:27 scripts/pahole-flags.sh

Known issue, see the thread here:
	https://lore.kernel.org/r/YxguwCpBEKAJJDU6@kroah.com

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (113 preceding siblings ...)
  2022-09-07  9:52 ` Bagas Sanjaya
@ 2022-09-07 12:48 ` Ron Economos
  2022-09-08 10:50 ` Jon Hunter
  115 siblings, 0 replies; 133+ messages in thread
From: Ron Economos @ 2022-09-07 12:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, linux-kernel
  Cc: stable, torvalds, akpm, linux, shuah, patches, lkft-triage,
	pavel, jonathanh, f.fainelli, sudipm.mukherjee, slade

On 9/6/22 6:29 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> 	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
> or in the git tree and branch at:
> 	git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Built and booted successfully on RISC-V RV64 (HiFive Unmatched).

Tested-by: Ron Economos <re@w6rz.net>


^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file
  2022-09-07 11:41     ` Sasha Levin
@ 2022-09-07 20:37       ` Lyude Paul
  0 siblings, 0 replies; 133+ messages in thread
From: Lyude Paul @ 2022-09-07 20:37 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Greg Kroah-Hartman, linux-kernel, stable, Jani Nikula

Ahhhh, sgtm then

On Wed, 2022-09-07 at 07:41 -0400, Sasha Levin wrote:
> On Tue, Sep 06, 2022 at 06:13:17PM -0400, Lyude Paul wrote:
> > Were there parts of this series that weren't Cc'd to me via email? Trying to
> > understand why this patch would be pulled in since it might be required for
> > other fixes, but on it's own there should be no functional changes so it's not
> > really a candidate for stable.
> 
> It's useful for the patch that immediately follows it: 868e8e5156a1
> ("drm/i915/display: avoid warnings when registering dual panel
> backlight").
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 000/107] 5.15.66-rc1 review
  2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
                   ` (114 preceding siblings ...)
  2022-09-07 12:48 ` Ron Economos
@ 2022-09-08 10:50 ` Jon Hunter
  115 siblings, 0 replies; 133+ messages in thread
From: Jon Hunter @ 2022-09-08 10:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Greg Kroah-Hartman, stable, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, slade, linux-tegra

On Tue, 06 Sep 2022 15:29:41 +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.66 release.
> There are 107 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Thu, 08 Sep 2022 13:27:58 +0000.
> Anything received after that time might be too late.
> 
> The whole patch series can be found in one patch at:
> 	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.66-rc1.gz
> or in the git tree and branch at:
> 	git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h

All tests passing for Tegra ...

Test results for stable-v5.15:
    10 builds:	10 pass, 0 fail
    28 boots:	28 pass, 0 fail
    114 tests:	114 pass, 0 fail

Linux version:	5.15.66-rc1-g78a6337a09de
Boards tested:	tegra124-jetson-tk1, tegra186-p2771-0000,
                tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
                tegra20-ventana, tegra210-p2371-2180,
                tegra210-p3450-0000, tegra30-cardhu-a04

Tested-by: Jon Hunter <jonathanh@nvidia.com>

Jon

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole
  2022-09-06 13:31 ` [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole Greg Kroah-Hartman
@ 2022-09-16 10:21   ` Thorsten Leemhuis
  2022-09-16 13:01     ` Jiri Olsa
  2022-09-16 16:25     ` Martin Rodriguez Reboredo
  0 siblings, 2 replies; 133+ messages in thread
From: Thorsten Leemhuis @ 2022-09-16 10:21 UTC (permalink / raw)
  To: Martin Rodriguez Reboredo
  Cc: Jiri Olsa, Greg Kroah-Hartman, linux-kernel, stable

On 06.09.22 14:31, Greg Kroah-Hartman wrote:
> From: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> 
> New pahole (version 1.24) generates by default new BTF_KIND_ENUM64 BTF tag,
> which is not supported by stable kernel.

Martin, when you wrote "not supported by stable kernel", did you mean
just 5.15.y or 5.19.y as well? Because I ran into...

> As a result the kernel with CONFIG_DEBUG_INFO_BTF option will fail to
> compile with following error:
> 
>   BTFIDS  vmlinux
> FAILED: load BTF from vmlinux: Invalid argument

...this compile error when compiling 5.19.9 for F37 and from a quick
look into this it seems this was caused by a update of dwarves to 1.24
that recently landed in that distribution. This patch seems to fix the
problem (it got past the point of the error, but modules are still
compiling).

Ciao, Thorsten

> New pahole provides --skip_encoding_btf_enum64 option to skip BTF_KIND_ENUM64
> generation and produce BTF supported by stable kernel.
> 
> Adding this option to scripts/pahole-flags.sh.
> 
> This change does not have equivalent commit in linus tree, because linus tree
> has support for BTF_KIND_ENUM64 tag, so it does not need to be disabled.
> 
> Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  scripts/pahole-flags.sh |    4 ++++
>  1 file changed, 4 insertions(+)
> 
> --- a/scripts/pahole-flags.sh
> +++ b/scripts/pahole-flags.sh
> @@ -17,4 +17,8 @@ if [ "${pahole_ver}" -ge "121" ]; then
>  	extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
>  fi
>  
> +if [ "${pahole_ver}" -ge "124" ]; then
> +	extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_enum64"
> +fi
> +
>  echo ${extra_paholeopt}
> 
> 

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole
  2022-09-16 10:21   ` Thorsten Leemhuis
@ 2022-09-16 13:01     ` Jiri Olsa
  2022-09-16 16:25     ` Martin Rodriguez Reboredo
  1 sibling, 0 replies; 133+ messages in thread
From: Jiri Olsa @ 2022-09-16 13:01 UTC (permalink / raw)
  To: Thorsten Leemhuis
  Cc: Martin Rodriguez Reboredo, Greg Kroah-Hartman, linux-kernel, stable

On Fri, Sep 16, 2022 at 11:21:46AM +0100, Thorsten Leemhuis wrote:
> On 06.09.22 14:31, Greg Kroah-Hartman wrote:
> > From: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> > 
> > New pahole (version 1.24) generates by default new BTF_KIND_ENUM64 BTF tag,
> > which is not supported by stable kernel.
> 
> Martin, when you wrote "not supported by stable kernel", did you mean
> just 5.15.y or 5.19.y as well? Because I ran into...
> 
> > As a result the kernel with CONFIG_DEBUG_INFO_BTF option will fail to
> > compile with following error:
> > 
> >   BTFIDS  vmlinux
> > FAILED: load BTF from vmlinux: Invalid argument
> 
> ...this compile error when compiling 5.19.9 for F37 and from a quick
> look into this it seems this was caused by a update of dwarves to 1.24
> that recently landed in that distribution. This patch seems to fix the
> problem (it got past the point of the error, but modules are still
> compiling).

hi,
IIUC Martin planned to send that for 5.19, I can do that if needed

jirka

> 
> Ciao, Thorsten
> 
> > New pahole provides --skip_encoding_btf_enum64 option to skip BTF_KIND_ENUM64
> > generation and produce BTF supported by stable kernel.
> > 
> > Adding this option to scripts/pahole-flags.sh.
> > 
> > This change does not have equivalent commit in linus tree, because linus tree
> > has support for BTF_KIND_ENUM64 tag, so it does not need to be disabled.
> > 
> > Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> >  scripts/pahole-flags.sh |    4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > --- a/scripts/pahole-flags.sh
> > +++ b/scripts/pahole-flags.sh
> > @@ -17,4 +17,8 @@ if [ "${pahole_ver}" -ge "121" ]; then
> >  	extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
> >  fi
> >  
> > +if [ "${pahole_ver}" -ge "124" ]; then
> > +	extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_enum64"
> > +fi
> > +
> >  echo ${extra_paholeopt}
> > 
> > 

^ permalink raw reply	[flat|nested] 133+ messages in thread

* Re: [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole
  2022-09-16 10:21   ` Thorsten Leemhuis
  2022-09-16 13:01     ` Jiri Olsa
@ 2022-09-16 16:25     ` Martin Rodriguez Reboredo
  1 sibling, 0 replies; 133+ messages in thread
From: Martin Rodriguez Reboredo @ 2022-09-16 16:25 UTC (permalink / raw)
  To: Thorsten Leemhuis; +Cc: Jiri Olsa, Greg Kroah-Hartman, linux-kernel, stable

On 9/16/22 07:21, Thorsten Leemhuis wrote:
> On 06.09.22 14:31, Greg Kroah-Hartman wrote:
>> From: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
>>
>> New pahole (version 1.24) generates by default new BTF_KIND_ENUM64 BTF tag,
>> which is not supported by stable kernel.
> 
> Martin, when you wrote "not supported by stable kernel", did you mean
> just 5.15.y or 5.19.y as well? Because I ran into...
> 
>> As a result the kernel with CONFIG_DEBUG_INFO_BTF option will fail to
>> compile with following error:
>>
>>   BTFIDS  vmlinux
>> FAILED: load BTF from vmlinux: Invalid argument
> 
> ...this compile error when compiling 5.19.9 for F37 and from a quick
> look into this it seems this was caused by a update of dwarves to 1.24
> that recently landed in that distribution. This patch seems to fix the
> problem (it got past the point of the error, but modules are still
> compiling).

Thorsten, by stable I've meant both current stable and longterm, i.e.
5.19 and below, and yes, I didn't sent a patch according to the stable
submission guidelines for 5.19 in time so I apologize for that. Gonna
send the patch for it. Thanks for reminding me.

^ permalink raw reply	[flat|nested] 133+ messages in thread

end of thread, other threads:[~2022-09-16 16:25 UTC | newest]

Thread overview: 133+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-06 13:29 [PATCH 5.15 000/107] 5.15.66-rc1 review Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 001/107] drm/msm/dsi: fix the inconsistent indenting Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 002/107] drm/msm/dp: delete DP_RECOVERED_CLOCK_OUT_EN to fix tps4 Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 003/107] drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 004/107] drm/msm/dsi: Fix number of regulators for SDM660 Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 005/107] platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 006/107] iio: adc: mcp3911: make use of the sign bit Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 007/107] skmsg: Fix wrong last sg check in sk_msg_recvmsg() Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 008/107] bpf: Restrict bpf_sys_bpf to CAP_PERFMON Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 009/107] bpf, cgroup: Fix kernel BUG in purge_effective_progs Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 010/107] ieee802154/adf7242: defer destroy_workqueue call Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 011/107] drm/i915/backlight: extract backlight code to a separate file Greg Kroah-Hartman
2022-09-06 22:13   ` Lyude Paul
2022-09-07 11:41     ` Sasha Levin
2022-09-07 20:37       ` Lyude Paul
2022-09-06 13:29 ` [PATCH 5.15 012/107] drm/i915/display: avoid warnings when registering dual panel backlight Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 013/107] ALSA: hda: intel-nhlt: remove use of __func__ in dev_dbg Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 014/107] ALSA: hda: intel-nhlt: Correct the handling of fmt_config flexible array Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 015/107] wifi: cfg80211: debugfs: fix return type in ht40allow_map_read() Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 016/107] Revert "xhci: turn off port power in shutdown" Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 017/107] net: sparx5: fix handling uneven length packets in manual extraction Greg Kroah-Hartman
2022-09-06 13:29 ` [PATCH 5.15 018/107] net: smsc911x: Stop and start PHY during suspend and resume Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 019/107] openvswitch: fix memory leak at failed datapath creation Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 020/107] net: dsa: xrs700x: Use irqsave variant for u64 stats update Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 021/107] net: sched: tbf: dont call qdisc_put() while holding tree lock Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 022/107] net/sched: fix netdevice reference leaks in attach_default_qdiscs() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 023/107] ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 024/107] mlxbf_gige: compute MDIO period based on i1clk Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 025/107] kcm: fix strp_init() order and cleanup Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 026/107] sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 027/107] tcp: annotate data-race around challenge_timestamp Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 028/107] Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb" Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 029/107] net/smc: Remove redundant refcount increase Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 030/107] soundwire: qcom: fix device status array range Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 031/107] serial: fsl_lpuart: RS485 RTS polariy is inverse Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 032/107] staging: rtl8712: fix use after free bugs Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 033/107] staging: r8188eu: add firmware dependency Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 034/107] powerpc: align syscall table for ppc32 Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 035/107] vt: Clear selection before changing the font Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 036/107] musb: fix USB_MUSB_TUSB6010 dependency Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 037/107] tty: serial: lpuart: disable flow control while waiting for the transmit engine to complete Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 038/107] Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 039/107] iio: ad7292: Prevent regulator double disable Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 040/107] iio: adc: mcp3911: use correct formula for AD conversion Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 041/107] misc: fastrpc: fix memory corruption on probe Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 042/107] misc: fastrpc: fix memory corruption on open Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 043/107] USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 044/107] mmc: core: Fix UHS-I SD 1.8V workaround branch Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 045/107] mmc: core: Fix inconsistent sd3_bus_mode at UHS-I SD voltage switch failure Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 046/107] binder: fix UAF of ref->proc caused by race condition Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 047/107] binder: fix alloc->vma_vm_mm null-ptr dereference Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 048/107] cifs: fix small mempool leak in SMB2_negotiate() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 049/107] KVM: VMX: Heed the msr argument in msr_write_intercepted() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 050/107] drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 051/107] clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 052/107] Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops" Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 053/107] clk: core: Fix runtime PM sequence in clk_core_unprepare() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 054/107] Input: rk805-pwrkey - fix module autoloading Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 055/107] clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 056/107] clk: bcm: rpi: Use correct order for the parameters of devm_kcalloc() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 057/107] clk: bcm: rpi: Prevent out-of-bounds access Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 058/107] clk: bcm: rpi: Add missing newline Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 059/107] hwmon: (gpio-fan) Fix array out of bounds access Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 060/107] gpio: pca953x: Add mutex_lock for regcache sync in PM Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 061/107] KVM: x86: Mask off unsupported and unknown bits of IA32_ARCH_CAPABILITIES Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 062/107] xen/grants: prevent integer overflow in gnttab_dma_alloc_pages() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 063/107] mm: pagewalk: Fix race between unmap and page walker Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 064/107] xen-blkback: Advertise feature-persistent as user requested Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 065/107] xen-blkfront: " Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 066/107] xen-blkfront: Cache feature_persistent value before advertisement Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 067/107] thunderbolt: Use the actual buffer in tb_async_error() Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 068/107] usb: dwc3: pci: Add support for Intel Raptor Lake Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 069/107] media: mceusb: Use new usb_control_msg_*() routines Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 070/107] xhci: Add grace period after xHC start to prevent premature runtime suspend Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 071/107] USB: serial: cp210x: add Decagon UCA device id Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 072/107] USB: serial: option: add support for OPPO R11 diag port Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 073/107] USB: serial: option: add Quectel EM060K modem Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 074/107] USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 075/107] usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 076/107] usb: typec: intel_pmc_mux: Add new ACPI ID for Meteor Lake IOM device Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 077/107] usb: typec: tcpm: Return ENOTSUPP for power supply prop writes Greg Kroah-Hartman
2022-09-06 13:30 ` [PATCH 5.15 078/107] usb: dwc2: fix wrong order of phy_power_on and phy_init Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 079/107] usb: cdns3: fix issue with rearming ISO OUT endpoint Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 080/107] usb: cdns3: fix incorrect handling TRB_SMM flag for ISOC transfer Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 081/107] USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020) Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 082/107] usb-storage: Add ignore-residue quirk for NXP PN7462AU Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 083/107] s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 084/107] s390: fix nospec table alignments Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 085/107] USB: core: Prevent nested device-reset calls Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 086/107] usb: xhci-mtk: relax TT periodic bandwidth allocation Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 087/107] usb: xhci-mtk: fix bandwidth release issue Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 088/107] usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 089/107] driver core: Dont probe devices after bus_type.match() probe deferral Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 090/107] wifi: mac80211: Dont finalize CSA in IBSS mode if state is disconnected Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 091/107] wifi: mac80211: Fix UAF in ieee80211_scan_rx() Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 092/107] ip: fix triggering of icmp redirect Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 093/107] net: Use u64_stats_fetch_begin_irq() for stats fetch Greg Kroah-Hartman
2022-09-06 13:31   ` Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 094/107] net: mac802154: Fix a condition in the receive path Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 095/107] ALSA: hda/realtek: Add speaker AMP init for Samsung laptops with ALC298 Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 096/107] ALSA: seq: oss: Fix data-race for max_midi_devs access Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 097/107] ALSA: seq: Fix data-race at module auto-loading Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 098/107] drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 099/107] drm/i915: Skip wm/ddb readout for disabled pipes Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 100/107] tty: n_gsm: add sanity check for gsm->receive in gsm_receive_buf() Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 101/107] kbuild: Unify options for BTF generation for vmlinux and modules Greg Kroah-Hartman
2022-09-06 18:45   ` Florian Fainelli
2022-09-07  5:40     ` Greg Kroah-Hartman
2022-09-07  7:02       ` Jiri Olsa
2022-09-07  8:13       ` Ron Economos
2022-09-06 13:31 ` [PATCH 5.15 102/107] kbuild: Add skip_encoding_btf_enum64 option to pahole Greg Kroah-Hartman
2022-09-16 10:21   ` Thorsten Leemhuis
2022-09-16 13:01     ` Jiri Olsa
2022-09-16 16:25     ` Martin Rodriguez Reboredo
2022-09-06 13:31 ` [PATCH 5.15 103/107] usb: dwc3: fix PHY disable sequence Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 104/107] usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 105/107] usb: dwc3: disable USB core PHY management Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 106/107] USB: serial: ch341: fix lost character on LCR updates Greg Kroah-Hartman
2022-09-06 13:31 ` [PATCH 5.15 107/107] USB: serial: ch341: fix disabled rx timer on older devices Greg Kroah-Hartman
2022-09-06 18:33 ` [PATCH 5.15 000/107] 5.15.66-rc1 review Florian Fainelli
2022-09-06 18:42   ` Florian Fainelli
2022-09-06 20:20 ` Naresh Kamboju
2022-09-06 20:46 ` Sudip Mukherjee
2022-09-07  5:49   ` Greg Kroah-Hartman
2022-09-07  9:27     ` Sudip Mukherjee (Codethink)
2022-09-06 21:48 ` Shuah Khan
2022-09-07  4:44 ` Guenter Roeck
2022-09-07  9:40 ` Sudip Mukherjee (Codethink)
2022-09-07 11:30   ` Sudip Mukherjee
2022-09-07 11:45     ` Greg Kroah-Hartman
2022-09-07  9:52 ` Bagas Sanjaya
2022-09-07 12:48 ` Ron Economos
2022-09-08 10:50 ` Jon Hunter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.