PCI: pciehp: Add pciehp_set_indicators() to set both indicators
Add pciehp_set_indicators() to set power and attention indicators with a single register write. This is a minor optimization because we frequently set both indicators and this can do it with a single command. It also reduces the number of interfaces related to the indicators and makes them more discoverable because callers use the PCI_EXP_SLTCTL_ATTN_IND_* and PCI_EXP_SLTCTL_PWR_IND_* definitions directly. [bhelgaas: extend commit log, s/PCI_EXP_SLTCTL_.*_IND_NONE/INDICATOR_NOOP/ so they don't look like things defined by the spec, add function doc, mask commands to make it obvious we only send valid commands (pcie_do_write_cmd() does mask it, but requires more effort to verify)] Link: https://lore.kernel.org/r/20190903111021.1559-2-efremov@linux.com Signed-off-by: Denis Efremov <efremov@linux.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
5f9e832c13
commit
688033f52d
@ -167,6 +167,9 @@ int pciehp_power_on_slot(struct controller *ctrl);
|
|||||||
void pciehp_power_off_slot(struct controller *ctrl);
|
void pciehp_power_off_slot(struct controller *ctrl);
|
||||||
void pciehp_get_power_status(struct controller *ctrl, u8 *status);
|
void pciehp_get_power_status(struct controller *ctrl, u8 *status);
|
||||||
|
|
||||||
|
#define INDICATOR_NOOP -1 /* Leave indicator unchanged */
|
||||||
|
void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn);
|
||||||
|
|
||||||
void pciehp_set_attention_status(struct controller *ctrl, u8 status);
|
void pciehp_set_attention_status(struct controller *ctrl, u8 status);
|
||||||
void pciehp_get_latch_status(struct controller *ctrl, u8 *status);
|
void pciehp_get_latch_status(struct controller *ctrl, u8 *status);
|
||||||
int pciehp_query_power_fault(struct controller *ctrl);
|
int pciehp_query_power_fault(struct controller *ctrl);
|
||||||
|
@ -443,6 +443,42 @@ void pciehp_set_attention_status(struct controller *ctrl, u8 value)
|
|||||||
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
|
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pciehp_set_indicators() - set attention indicator, power indicator, or both
|
||||||
|
* @ctrl: PCIe hotplug controller
|
||||||
|
* @pwr: one of:
|
||||||
|
* PCI_EXP_SLTCTL_PWR_IND_ON
|
||||||
|
* PCI_EXP_SLTCTL_PWR_IND_BLINK
|
||||||
|
* PCI_EXP_SLTCTL_PWR_IND_OFF
|
||||||
|
* @attn: one of:
|
||||||
|
* PCI_EXP_SLTCTL_ATTN_IND_ON
|
||||||
|
* PCI_EXP_SLTCTL_ATTN_IND_BLINK
|
||||||
|
* PCI_EXP_SLTCTL_ATTN_IND_OFF
|
||||||
|
*
|
||||||
|
* Either @pwr or @attn can also be INDICATOR_NOOP to leave that indicator
|
||||||
|
* unchanged.
|
||||||
|
*/
|
||||||
|
void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn)
|
||||||
|
{
|
||||||
|
u16 cmd = 0, mask = 0;
|
||||||
|
|
||||||
|
if (PWR_LED(ctrl) && pwr != INDICATOR_NOOP) {
|
||||||
|
cmd |= (pwr & PCI_EXP_SLTCTL_PIC);
|
||||||
|
mask |= PCI_EXP_SLTCTL_PIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ATTN_LED(ctrl) && attn != INDICATOR_NOOP) {
|
||||||
|
cmd |= (attn & PCI_EXP_SLTCTL_AIC);
|
||||||
|
mask |= PCI_EXP_SLTCTL_AIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd) {
|
||||||
|
pcie_write_cmd_nowait(ctrl, cmd, mask);
|
||||||
|
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
|
||||||
|
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pciehp_green_led_on(struct controller *ctrl)
|
void pciehp_green_led_on(struct controller *ctrl)
|
||||||
{
|
{
|
||||||
if (!PWR_LED(ctrl))
|
if (!PWR_LED(ctrl))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user