Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * PCI Express Hot Plug Controller Driver
0004  *
0005  * Copyright (C) 1995,2001 Compaq Computer Corporation
0006  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
0007  * Copyright (C) 2001 IBM Corp.
0008  * Copyright (C) 2003-2004 Intel Corporation
0009  *
0010  * All rights reserved.
0011  *
0012  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
0013  *
0014  * Authors:
0015  *   Dan Zink <dan.zink@compaq.com>
0016  *   Greg Kroah-Hartman <greg@kroah.com>
0017  *   Dely Sy <dely.l.sy@intel.com>"
0018  */
0019 
0020 #define pr_fmt(fmt) "pciehp: " fmt
0021 #define dev_fmt pr_fmt
0022 
0023 #include <linux/moduleparam.h>
0024 #include <linux/kernel.h>
0025 #include <linux/slab.h>
0026 #include <linux/types.h>
0027 #include <linux/pci.h>
0028 #include "pciehp.h"
0029 
0030 #include "../pci.h"
0031 
0032 /* Global variables */
0033 bool pciehp_poll_mode;
0034 int pciehp_poll_time;
0035 
0036 /*
0037  * not really modular, but the easiest way to keep compat with existing
0038  * bootargs behaviour is to continue using module_param here.
0039  */
0040 module_param(pciehp_poll_mode, bool, 0644);
0041 module_param(pciehp_poll_time, int, 0644);
0042 MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
0043 MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
0044 
0045 static int set_attention_status(struct hotplug_slot *slot, u8 value);
0046 static int get_power_status(struct hotplug_slot *slot, u8 *value);
0047 static int get_latch_status(struct hotplug_slot *slot, u8 *value);
0048 static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
0049 
0050 static int init_slot(struct controller *ctrl)
0051 {
0052     struct hotplug_slot_ops *ops;
0053     char name[SLOT_NAME_SIZE];
0054     int retval;
0055 
0056     /* Setup hotplug slot ops */
0057     ops = kzalloc(sizeof(*ops), GFP_KERNEL);
0058     if (!ops)
0059         return -ENOMEM;
0060 
0061     ops->enable_slot = pciehp_sysfs_enable_slot;
0062     ops->disable_slot = pciehp_sysfs_disable_slot;
0063     ops->get_power_status = get_power_status;
0064     ops->get_adapter_status = get_adapter_status;
0065     ops->reset_slot = pciehp_reset_slot;
0066     if (MRL_SENS(ctrl))
0067         ops->get_latch_status = get_latch_status;
0068     if (ATTN_LED(ctrl)) {
0069         ops->get_attention_status = pciehp_get_attention_status;
0070         ops->set_attention_status = set_attention_status;
0071     } else if (ctrl->pcie->port->hotplug_user_indicators) {
0072         ops->get_attention_status = pciehp_get_raw_indicator_status;
0073         ops->set_attention_status = pciehp_set_raw_indicator_status;
0074     }
0075 
0076     /* register this slot with the hotplug pci core */
0077     ctrl->hotplug_slot.ops = ops;
0078     snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl));
0079 
0080     retval = pci_hp_initialize(&ctrl->hotplug_slot,
0081                    ctrl->pcie->port->subordinate, 0, name);
0082     if (retval) {
0083         ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval);
0084         kfree(ops);
0085     }
0086     return retval;
0087 }
0088 
0089 static void cleanup_slot(struct controller *ctrl)
0090 {
0091     struct hotplug_slot *hotplug_slot = &ctrl->hotplug_slot;
0092 
0093     pci_hp_destroy(hotplug_slot);
0094     kfree(hotplug_slot->ops);
0095 }
0096 
0097 /*
0098  * set_attention_status - Turns the Attention Indicator on, off or blinking
0099  */
0100 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
0101 {
0102     struct controller *ctrl = to_ctrl(hotplug_slot);
0103     struct pci_dev *pdev = ctrl->pcie->port;
0104 
0105     if (status)
0106         status <<= PCI_EXP_SLTCTL_ATTN_IND_SHIFT;
0107     else
0108         status = PCI_EXP_SLTCTL_ATTN_IND_OFF;
0109 
0110     pci_config_pm_runtime_get(pdev);
0111     pciehp_set_indicators(ctrl, INDICATOR_NOOP, status);
0112     pci_config_pm_runtime_put(pdev);
0113     return 0;
0114 }
0115 
0116 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
0117 {
0118     struct controller *ctrl = to_ctrl(hotplug_slot);
0119     struct pci_dev *pdev = ctrl->pcie->port;
0120 
0121     pci_config_pm_runtime_get(pdev);
0122     pciehp_get_power_status(ctrl, value);
0123     pci_config_pm_runtime_put(pdev);
0124     return 0;
0125 }
0126 
0127 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
0128 {
0129     struct controller *ctrl = to_ctrl(hotplug_slot);
0130     struct pci_dev *pdev = ctrl->pcie->port;
0131 
0132     pci_config_pm_runtime_get(pdev);
0133     pciehp_get_latch_status(ctrl, value);
0134     pci_config_pm_runtime_put(pdev);
0135     return 0;
0136 }
0137 
0138 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
0139 {
0140     struct controller *ctrl = to_ctrl(hotplug_slot);
0141     struct pci_dev *pdev = ctrl->pcie->port;
0142     int ret;
0143 
0144     pci_config_pm_runtime_get(pdev);
0145     ret = pciehp_card_present_or_link_active(ctrl);
0146     pci_config_pm_runtime_put(pdev);
0147     if (ret < 0)
0148         return ret;
0149 
0150     *value = ret;
0151     return 0;
0152 }
0153 
0154 /**
0155  * pciehp_check_presence() - synthesize event if presence has changed
0156  * @ctrl: controller to check
0157  *
0158  * On probe and resume, an explicit presence check is necessary to bring up an
0159  * occupied slot or bring down an unoccupied slot.  This can't be triggered by
0160  * events in the Slot Status register, they may be stale and are therefore
0161  * cleared.  Secondly, sending an interrupt for "events that occur while
0162  * interrupt generation is disabled [when] interrupt generation is subsequently
0163  * enabled" is optional per PCIe r4.0, sec 6.7.3.4.
0164  */
0165 static void pciehp_check_presence(struct controller *ctrl)
0166 {
0167     int occupied;
0168 
0169     down_read_nested(&ctrl->reset_lock, ctrl->depth);
0170     mutex_lock(&ctrl->state_lock);
0171 
0172     occupied = pciehp_card_present_or_link_active(ctrl);
0173     if ((occupied > 0 && (ctrl->state == OFF_STATE ||
0174               ctrl->state == BLINKINGON_STATE)) ||
0175         (!occupied && (ctrl->state == ON_STATE ||
0176                ctrl->state == BLINKINGOFF_STATE)))
0177         pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
0178 
0179     mutex_unlock(&ctrl->state_lock);
0180     up_read(&ctrl->reset_lock);
0181 }
0182 
0183 static int pciehp_probe(struct pcie_device *dev)
0184 {
0185     int rc;
0186     struct controller *ctrl;
0187 
0188     /* If this is not a "hotplug" service, we have no business here. */
0189     if (dev->service != PCIE_PORT_SERVICE_HP)
0190         return -ENODEV;
0191 
0192     if (!dev->port->subordinate) {
0193         /* Can happen if we run out of bus numbers during probe */
0194         pci_err(dev->port,
0195             "Hotplug bridge without secondary bus, ignoring\n");
0196         return -ENODEV;
0197     }
0198 
0199     ctrl = pcie_init(dev);
0200     if (!ctrl) {
0201         pci_err(dev->port, "Controller initialization failed\n");
0202         return -ENODEV;
0203     }
0204     set_service_data(dev, ctrl);
0205 
0206     /* Setup the slot information structures */
0207     rc = init_slot(ctrl);
0208     if (rc) {
0209         if (rc == -EBUSY)
0210             ctrl_warn(ctrl, "Slot already registered by another hotplug driver\n");
0211         else
0212             ctrl_err(ctrl, "Slot initialization failed (%d)\n", rc);
0213         goto err_out_release_ctlr;
0214     }
0215 
0216     /* Enable events after we have setup the data structures */
0217     rc = pcie_init_notification(ctrl);
0218     if (rc) {
0219         ctrl_err(ctrl, "Notification initialization failed (%d)\n", rc);
0220         goto err_out_free_ctrl_slot;
0221     }
0222 
0223     /* Publish to user space */
0224     rc = pci_hp_add(&ctrl->hotplug_slot);
0225     if (rc) {
0226         ctrl_err(ctrl, "Publication to user space failed (%d)\n", rc);
0227         goto err_out_shutdown_notification;
0228     }
0229 
0230     pciehp_check_presence(ctrl);
0231 
0232     return 0;
0233 
0234 err_out_shutdown_notification:
0235     pcie_shutdown_notification(ctrl);
0236 err_out_free_ctrl_slot:
0237     cleanup_slot(ctrl);
0238 err_out_release_ctlr:
0239     pciehp_release_ctrl(ctrl);
0240     return -ENODEV;
0241 }
0242 
0243 static void pciehp_remove(struct pcie_device *dev)
0244 {
0245     struct controller *ctrl = get_service_data(dev);
0246 
0247     pci_hp_del(&ctrl->hotplug_slot);
0248     pcie_shutdown_notification(ctrl);
0249     cleanup_slot(ctrl);
0250     pciehp_release_ctrl(ctrl);
0251 }
0252 
0253 #ifdef CONFIG_PM
0254 static bool pme_is_native(struct pcie_device *dev)
0255 {
0256     const struct pci_host_bridge *host;
0257 
0258     host = pci_find_host_bridge(dev->port->bus);
0259     return pcie_ports_native || host->native_pme;
0260 }
0261 
0262 static void pciehp_disable_interrupt(struct pcie_device *dev)
0263 {
0264     /*
0265      * Disable hotplug interrupt so that it does not trigger
0266      * immediately when the downstream link goes down.
0267      */
0268     if (pme_is_native(dev))
0269         pcie_disable_interrupt(get_service_data(dev));
0270 }
0271 
0272 #ifdef CONFIG_PM_SLEEP
0273 static int pciehp_suspend(struct pcie_device *dev)
0274 {
0275     /*
0276      * If the port is already runtime suspended we can keep it that
0277      * way.
0278      */
0279     if (dev_pm_skip_suspend(&dev->port->dev))
0280         return 0;
0281 
0282     pciehp_disable_interrupt(dev);
0283     return 0;
0284 }
0285 
0286 static int pciehp_resume_noirq(struct pcie_device *dev)
0287 {
0288     struct controller *ctrl = get_service_data(dev);
0289 
0290     /* pci_restore_state() just wrote to the Slot Control register */
0291     ctrl->cmd_started = jiffies;
0292     ctrl->cmd_busy = true;
0293 
0294     /* clear spurious events from rediscovery of inserted card */
0295     if (ctrl->state == ON_STATE || ctrl->state == BLINKINGOFF_STATE)
0296         pcie_clear_hotplug_events(ctrl);
0297 
0298     return 0;
0299 }
0300 #endif
0301 
0302 static int pciehp_resume(struct pcie_device *dev)
0303 {
0304     struct controller *ctrl = get_service_data(dev);
0305 
0306     if (pme_is_native(dev))
0307         pcie_enable_interrupt(ctrl);
0308 
0309     pciehp_check_presence(ctrl);
0310 
0311     return 0;
0312 }
0313 
0314 static int pciehp_runtime_suspend(struct pcie_device *dev)
0315 {
0316     pciehp_disable_interrupt(dev);
0317     return 0;
0318 }
0319 
0320 static int pciehp_runtime_resume(struct pcie_device *dev)
0321 {
0322     struct controller *ctrl = get_service_data(dev);
0323 
0324     /* pci_restore_state() just wrote to the Slot Control register */
0325     ctrl->cmd_started = jiffies;
0326     ctrl->cmd_busy = true;
0327 
0328     /* clear spurious events from rediscovery of inserted card */
0329     if ((ctrl->state == ON_STATE || ctrl->state == BLINKINGOFF_STATE) &&
0330          pme_is_native(dev))
0331         pcie_clear_hotplug_events(ctrl);
0332 
0333     return pciehp_resume(dev);
0334 }
0335 #endif /* PM */
0336 
0337 static struct pcie_port_service_driver hpdriver_portdrv = {
0338     .name       = "pciehp",
0339     .port_type  = PCIE_ANY_PORT,
0340     .service    = PCIE_PORT_SERVICE_HP,
0341 
0342     .probe      = pciehp_probe,
0343     .remove     = pciehp_remove,
0344 
0345 #ifdef  CONFIG_PM
0346 #ifdef  CONFIG_PM_SLEEP
0347     .suspend    = pciehp_suspend,
0348     .resume_noirq   = pciehp_resume_noirq,
0349     .resume     = pciehp_resume,
0350 #endif
0351     .runtime_suspend = pciehp_runtime_suspend,
0352     .runtime_resume = pciehp_runtime_resume,
0353 #endif  /* PM */
0354 
0355     .slot_reset = pciehp_slot_reset,
0356 };
0357 
0358 int __init pcie_hp_init(void)
0359 {
0360     int retval = 0;
0361 
0362     retval = pcie_port_service_register(&hpdriver_portdrv);
0363     pr_debug("pcie_port_service_register = %d\n", retval);
0364     if (retval)
0365         pr_debug("Failure to register service\n");
0366 
0367     return retval;
0368 }