diff options
author | 2023-11-02 14:05:18 -1000 | |
---|---|---|
committer | 2023-11-02 14:05:18 -1000 | |
commit | 27beb3ca347fa29fef5c23b351120239b8cf0612 (patch) | |
tree | cf92e40319e07a459710d2819c430ab5ee358c88 /drivers/pci/hotplug/acpiphp_ampere_altra.c | |
parent | Merge tag '6.7-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd (diff) | |
parent | Merge branch 'pci/misc' (diff) | |
download | linux-27beb3ca347fa29fef5c23b351120239b8cf0612.tar.gz linux-27beb3ca347fa29fef5c23b351120239b8cf0612.tar.bz2 linux-27beb3ca347fa29fef5c23b351120239b8cf0612.zip |
Merge tag 'pci-v6.7-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci updates from Bjorn Helgaas:
"Enumeration:
- Use acpi_evaluate_dsm_typed() instead of open-coding _DSM
evaluation to learn device characteristics (Andy Shevchenko)
- Tidy multi-function header checks using new PCI_HEADER_TYPE_MASK
definition (Ilpo Järvinen)
- Simplify config access error checking in various drivers (Ilpo
Järvinen)
- Use pcie_capability_clear_word() (not
pcie_capability_clear_and_set_word()) when only clearing (Ilpo
Järvinen)
- Add pci_get_base_class() to simplify finding devices using base
class only (ignoring subclass and programming interface) (Sui
Jingfeng)
- Add pci_is_vga(), which includes ancient PCI_CLASS_NOT_DEFINED_VGA
devices from before the Class Code was added to PCI (Sui Jingfeng)
- Use pci_is_vga() for vgaarb, sysfs "boot_vga", virtio, qxl to
include ancient VGA devices (Sui Jingfeng)
Resource management:
- Make pci_assign_unassigned_resources() non-init because sparc uses
it after init (Randy Dunlap)
Driver binding:
- Retain .remove() and .probe() callbacks (previously __init) because
sysfs may cause them to be called later (Uwe Kleine-König)
- Prevent xHCI driver from claiming AMD VanGogh USB3 DRD device, so
it can be claimed by dwc3 instead (Vicki Pfau)
PCI device hotplug:
- Add Ampere Altra Attention Indicator extension driver for acpiphp
(D Scott Phillips)
Power management:
- Quirk VideoPropulsion Torrent QN16e with longer delay after reset
(Lukas Wunner)
- Prevent users from overriding drivers that say we shouldn't use
D3cold (Lukas Wunner)
- Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4
because wakeup interrupts from those states don't work if amd-pmc
has put the platform in a hardware sleep state (Mario Limonciello)
IOMMU:
- Disable ATS for Intel IPU E2000 devices with invalidation message
endianness erratum (Bartosz Pawlowski)
Error handling:
- Factor out interrupt enable/disable into helpers (Kai-Heng Feng)
Peer-to-peer DMA:
- Fix flexible-array usage in struct pci_p2pdma_pagemap in case we
ever use pagemaps with multiple entries (Gustavo A. R. Silva)
ASPM:
- Revert a change that broke when drivers disabled L1 and users later
enabled an L1.x substate via sysfs, and fix a similar issue when
users disabled L1 via sysfs (Heiner Kallweit)
Endpoint framework:
- Fix double free in __pci_epc_create() (Dan Carpenter)
- Use IS_ERR_OR_NULL() to simplify endpoint core (Ruan Jinjie)
Cadence PCIe controller driver:
- Drop unused "is_rc" member (Li Chen)
Freescale Layerscape PCIe controller driver:
- Enable 64-bit addressing in endpoint mode (Guanhua Gao)
Intel VMD host bridge driver:
- Fix multi-function header check (Ilpo Järvinen)
Microsoft Hyper-V host bridge driver:
- Annotate struct hv_dr_state with __counted_by (Kees Cook)
NVIDIA Tegra194 PCIe controller driver:
- Drop setting of LNKCAP_MLW (max link width) since dw_pcie_setup()
already does this via dw_pcie_link_set_max_link_width() (Yoshihiro
Shimoda)
Qualcomm PCIe controller driver:
- Use PCIE_SPEED2MBS_ENC() to simplify encoding of link speed
(Manivannan Sadhasivam)
- Add a .write_dbi2() callback so DBI2 register writes, e.g., for
setting the BAR size, work correctly (Manivannan Sadhasivam)
- Enable ASPM for platforms that use 1.9.0 ops, because the PCI core
doesn't enable ASPM states that haven't been enabled by the
firmware (Manivannan Sadhasivam)
Renesas R-Car Gen4 PCIe controller driver:
- Add DesignWare core support (set max link width, EDMA_UNROLL flag,
.pre_init(), .deinit(), etc) for use by R-Car Gen4 driver
(Yoshihiro Shimoda)
- Add driver and DT schema for DesignWare-based Renesas R-Car Gen4
controller in both host and endpoint mode (Yoshihiro Shimoda)
Xilinx NWL PCIe controller driver:
- Update ECAM size to support 256 buses (Thippeswamy Havalige)
- Stop setting bridge primary/secondary/subordinate bus numbers,
since PCI core does this (Thippeswamy Havalige)
Xilinx XDMA controller driver:
- Add driver and DT schema for Zynq UltraScale+ MPSoCs devices with
Xilinx XDMA Soft IP (Thippeswamy Havalige)
Miscellaneous:
- Use FIELD_GET()/FIELD_PREP() to simplify and reduce use of _SHIFT
macros (Ilpo Järvinen, Bjorn Helgaas)
- Remove logic_outb(), _outw(), outl() duplicate declarations (John
Sanpe)
- Replace unnecessary UTF-8 in Kconfig help text because menuconfig
doesn't render it correctly (Liu Song)"
* tag 'pci-v6.7-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: (102 commits)
PCI: qcom-ep: Add dedicated callback for writing to DBI2 registers
PCI: Simplify pcie_capability_clear_and_set_word() to ..._clear_word()
PCI: endpoint: Fix double free in __pci_epc_create()
PCI: xilinx-xdma: Add Xilinx XDMA Root Port driver
dt-bindings: PCI: xilinx-xdma: Add schemas for Xilinx XDMA PCIe Root Port Bridge
PCI: xilinx-cpm: Move IRQ definitions to a common header
PCI: xilinx-nwl: Modify ECAM size to enable support for 256 buses
PCI: xilinx-nwl: Rename the NWL_ECAM_VALUE_DEFAULT macro
dt-bindings: PCI: xilinx-nwl: Modify ECAM size in the DT example
PCI: xilinx-nwl: Remove redundant code that sets Type 1 header fields
PCI: hotplug: Add Ampere Altra Attention Indicator extension driver
PCI/AER: Factor out interrupt toggling into helpers
PCI: acpiphp: Allow built-in drivers for Attention Indicators
PCI/portdrv: Use FIELD_GET()
PCI/VC: Use FIELD_GET()
PCI/PTM: Use FIELD_GET()
PCI/PME: Use FIELD_GET()
PCI/ATS: Use FIELD_GET()
PCI/ATS: Show PASID Capability register width in bitmasks
PCI/ASPM: Fix L1 substate handling in aspm_attr_store_common()
...
Diffstat (limited to 'drivers/pci/hotplug/acpiphp_ampere_altra.c')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_ampere_altra.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/acpiphp_ampere_altra.c b/drivers/pci/hotplug/acpiphp_ampere_altra.c new file mode 100644 index 000000000000..3fddd04851b6 --- /dev/null +++ b/drivers/pci/hotplug/acpiphp_ampere_altra.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ACPI PCI Hot Plug Extension for Ampere Altra. Allows control of + * attention LEDs via requests to system firmware. + * + * Copyright (C) 2023 Ampere Computing LLC + */ + +#define pr_fmt(fmt) "acpiphp_ampere_altra: " fmt + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/pci_hotplug.h> +#include <linux/platform_device.h> + +#include "acpiphp.h" + +#define HANDLE_OPEN 0xb0200000 +#define HANDLE_CLOSE 0xb0300000 +#define REQUEST 0xf0700000 +#define LED_CMD 0x00000004 +#define LED_ATTENTION 0x00000002 +#define LED_SET_ON 0x00000001 +#define LED_SET_OFF 0x00000002 +#define LED_SET_BLINK 0x00000003 + +static u32 led_service_id[4]; + +static int led_status(u8 status) +{ + switch (status) { + case 1: return LED_SET_ON; + case 2: return LED_SET_BLINK; + default: return LED_SET_OFF; + } +} + +static int set_attention_status(struct hotplug_slot *slot, u8 status) +{ + struct arm_smccc_res res; + struct pci_bus *bus; + struct pci_dev *root_port; + unsigned long flags; + u32 handle; + int ret = 0; + + bus = slot->pci_slot->bus; + root_port = pcie_find_root_port(bus->self); + if (!root_port) + return -ENODEV; + + local_irq_save(flags); + arm_smccc_smc(HANDLE_OPEN, led_service_id[0], led_service_id[1], + led_service_id[2], led_service_id[3], 0, 0, 0, &res); + if (res.a0) { + ret = -ENODEV; + goto out; + } + handle = res.a1 & 0xffff0000; + + arm_smccc_smc(REQUEST, LED_CMD, led_status(status), LED_ATTENTION, + (PCI_SLOT(root_port->devfn) << 4) | (pci_domain_nr(bus) & 0xf), + 0, 0, handle, &res); + if (res.a0) + ret = -ENODEV; + + arm_smccc_smc(HANDLE_CLOSE, handle, 0, 0, 0, 0, 0, 0, &res); + + out: + local_irq_restore(flags); + return ret; +} + +static int get_attention_status(struct hotplug_slot *slot, u8 *status) +{ + return -EINVAL; +} + +static struct acpiphp_attention_info ampere_altra_attn = { + .set_attn = set_attention_status, + .get_attn = get_attention_status, + .owner = THIS_MODULE, +}; + +static int altra_led_probe(struct platform_device *pdev) +{ + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev); + int ret; + + ret = fwnode_property_read_u32_array(fwnode, "uuid", led_service_id, 4); + if (ret) { + dev_err(&pdev->dev, "can't find uuid\n"); + return ret; + } + + ret = acpiphp_register_attention(&ere_altra_attn); + if (ret) { + dev_err(&pdev->dev, "can't register driver\n"); + return ret; + } + return 0; +} + +static void altra_led_remove(struct platform_device *pdev) +{ + acpiphp_unregister_attention(&ere_altra_attn); +} + +static const struct acpi_device_id altra_led_ids[] = { + { "AMPC0008", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, altra_led_ids); + +static struct platform_driver altra_led_driver = { + .driver = { + .name = "ampere-altra-leds", + .acpi_match_table = altra_led_ids, + }, + .probe = altra_led_probe, + .remove_new = altra_led_remove, +}; +module_platform_driver(altra_led_driver); + +MODULE_AUTHOR("D Scott Phillips <scott@os.amperecomputing.com>"); +MODULE_LICENSE("GPL"); |