0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #define dev_fmt(fmt) "pciehp: " fmt
0017
0018 #include <linux/kernel.h>
0019 #include <linux/types.h>
0020 #include <linux/pm_runtime.h>
0021 #include <linux/pci.h>
0022 #include "pciehp.h"
0023
0024
0025
0026
0027
0028 #define SAFE_REMOVAL true
0029 #define SURPRISE_REMOVAL false
0030
0031 static void set_slot_off(struct controller *ctrl)
0032 {
0033
0034
0035
0036
0037 if (POWER_CTRL(ctrl)) {
0038 pciehp_power_off_slot(ctrl);
0039
0040
0041
0042
0043
0044
0045 msleep(1000);
0046 }
0047
0048 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
0049 PCI_EXP_SLTCTL_ATTN_IND_ON);
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059 static int board_added(struct controller *ctrl)
0060 {
0061 int retval = 0;
0062 struct pci_bus *parent = ctrl->pcie->port->subordinate;
0063
0064 if (POWER_CTRL(ctrl)) {
0065
0066 retval = pciehp_power_on_slot(ctrl);
0067 if (retval)
0068 return retval;
0069 }
0070
0071 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
0072 INDICATOR_NOOP);
0073
0074
0075 retval = pciehp_check_link_status(ctrl);
0076 if (retval)
0077 goto err_exit;
0078
0079
0080 if (ctrl->power_fault_detected || pciehp_query_power_fault(ctrl)) {
0081 ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl));
0082 retval = -EIO;
0083 goto err_exit;
0084 }
0085
0086 retval = pciehp_configure_device(ctrl);
0087 if (retval) {
0088 if (retval != -EEXIST) {
0089 ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",
0090 pci_domain_nr(parent), parent->number);
0091 goto err_exit;
0092 }
0093 }
0094
0095 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
0096 PCI_EXP_SLTCTL_ATTN_IND_OFF);
0097 return 0;
0098
0099 err_exit:
0100 set_slot_off(ctrl);
0101 return retval;
0102 }
0103
0104
0105
0106
0107
0108
0109 static void remove_board(struct controller *ctrl, bool safe_removal)
0110 {
0111 pciehp_unconfigure_device(ctrl, safe_removal);
0112
0113 if (POWER_CTRL(ctrl)) {
0114 pciehp_power_off_slot(ctrl);
0115
0116
0117
0118
0119
0120
0121 msleep(1000);
0122
0123
0124 atomic_and(~(PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC),
0125 &ctrl->pending_events);
0126 }
0127
0128 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
0129 INDICATOR_NOOP);
0130 }
0131
0132 static int pciehp_enable_slot(struct controller *ctrl);
0133 static int pciehp_disable_slot(struct controller *ctrl, bool safe_removal);
0134
0135 void pciehp_request(struct controller *ctrl, int action)
0136 {
0137 atomic_or(action, &ctrl->pending_events);
0138 if (!pciehp_poll_mode)
0139 irq_wake_thread(ctrl->pcie->irq, ctrl);
0140 }
0141
0142 void pciehp_queue_pushbutton_work(struct work_struct *work)
0143 {
0144 struct controller *ctrl = container_of(work, struct controller,
0145 button_work.work);
0146
0147 mutex_lock(&ctrl->state_lock);
0148 switch (ctrl->state) {
0149 case BLINKINGOFF_STATE:
0150 pciehp_request(ctrl, DISABLE_SLOT);
0151 break;
0152 case BLINKINGON_STATE:
0153 pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
0154 break;
0155 default:
0156 break;
0157 }
0158 mutex_unlock(&ctrl->state_lock);
0159 }
0160
0161 void pciehp_handle_button_press(struct controller *ctrl)
0162 {
0163 mutex_lock(&ctrl->state_lock);
0164 switch (ctrl->state) {
0165 case OFF_STATE:
0166 case ON_STATE:
0167 if (ctrl->state == ON_STATE) {
0168 ctrl->state = BLINKINGOFF_STATE;
0169 ctrl_info(ctrl, "Slot(%s): Powering off due to button press\n",
0170 slot_name(ctrl));
0171 } else {
0172 ctrl->state = BLINKINGON_STATE;
0173 ctrl_info(ctrl, "Slot(%s) Powering on due to button press\n",
0174 slot_name(ctrl));
0175 }
0176
0177 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
0178 PCI_EXP_SLTCTL_ATTN_IND_OFF);
0179 schedule_delayed_work(&ctrl->button_work, 5 * HZ);
0180 break;
0181 case BLINKINGOFF_STATE:
0182 case BLINKINGON_STATE:
0183
0184
0185
0186
0187
0188 ctrl_info(ctrl, "Slot(%s): Button cancel\n", slot_name(ctrl));
0189 cancel_delayed_work(&ctrl->button_work);
0190 if (ctrl->state == BLINKINGOFF_STATE) {
0191 ctrl->state = ON_STATE;
0192 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
0193 PCI_EXP_SLTCTL_ATTN_IND_OFF);
0194 } else {
0195 ctrl->state = OFF_STATE;
0196 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
0197 PCI_EXP_SLTCTL_ATTN_IND_OFF);
0198 }
0199 ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n",
0200 slot_name(ctrl));
0201 break;
0202 default:
0203 ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n",
0204 slot_name(ctrl), ctrl->state);
0205 break;
0206 }
0207 mutex_unlock(&ctrl->state_lock);
0208 }
0209
0210 void pciehp_handle_disable_request(struct controller *ctrl)
0211 {
0212 mutex_lock(&ctrl->state_lock);
0213 switch (ctrl->state) {
0214 case BLINKINGON_STATE:
0215 case BLINKINGOFF_STATE:
0216 cancel_delayed_work(&ctrl->button_work);
0217 break;
0218 }
0219 ctrl->state = POWEROFF_STATE;
0220 mutex_unlock(&ctrl->state_lock);
0221
0222 ctrl->request_result = pciehp_disable_slot(ctrl, SAFE_REMOVAL);
0223 }
0224
0225 void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
0226 {
0227 int present, link_active;
0228
0229
0230
0231
0232
0233 mutex_lock(&ctrl->state_lock);
0234 switch (ctrl->state) {
0235 case BLINKINGOFF_STATE:
0236 cancel_delayed_work(&ctrl->button_work);
0237 fallthrough;
0238 case ON_STATE:
0239 ctrl->state = POWEROFF_STATE;
0240 mutex_unlock(&ctrl->state_lock);
0241 if (events & PCI_EXP_SLTSTA_DLLSC)
0242 ctrl_info(ctrl, "Slot(%s): Link Down\n",
0243 slot_name(ctrl));
0244 if (events & PCI_EXP_SLTSTA_PDC)
0245 ctrl_info(ctrl, "Slot(%s): Card not present\n",
0246 slot_name(ctrl));
0247 pciehp_disable_slot(ctrl, SURPRISE_REMOVAL);
0248 break;
0249 default:
0250 mutex_unlock(&ctrl->state_lock);
0251 break;
0252 }
0253
0254
0255 mutex_lock(&ctrl->state_lock);
0256 present = pciehp_card_present(ctrl);
0257 link_active = pciehp_check_link_active(ctrl);
0258 if (present <= 0 && link_active <= 0) {
0259 mutex_unlock(&ctrl->state_lock);
0260 return;
0261 }
0262
0263 switch (ctrl->state) {
0264 case BLINKINGON_STATE:
0265 cancel_delayed_work(&ctrl->button_work);
0266 fallthrough;
0267 case OFF_STATE:
0268 ctrl->state = POWERON_STATE;
0269 mutex_unlock(&ctrl->state_lock);
0270 if (present)
0271 ctrl_info(ctrl, "Slot(%s): Card present\n",
0272 slot_name(ctrl));
0273 if (link_active)
0274 ctrl_info(ctrl, "Slot(%s): Link Up\n",
0275 slot_name(ctrl));
0276 ctrl->request_result = pciehp_enable_slot(ctrl);
0277 break;
0278 default:
0279 mutex_unlock(&ctrl->state_lock);
0280 break;
0281 }
0282 }
0283
0284 static int __pciehp_enable_slot(struct controller *ctrl)
0285 {
0286 u8 getstatus = 0;
0287
0288 if (MRL_SENS(ctrl)) {
0289 pciehp_get_latch_status(ctrl, &getstatus);
0290 if (getstatus) {
0291 ctrl_info(ctrl, "Slot(%s): Latch open\n",
0292 slot_name(ctrl));
0293 return -ENODEV;
0294 }
0295 }
0296
0297 if (POWER_CTRL(ctrl)) {
0298 pciehp_get_power_status(ctrl, &getstatus);
0299 if (getstatus) {
0300 ctrl_info(ctrl, "Slot(%s): Already enabled\n",
0301 slot_name(ctrl));
0302 return 0;
0303 }
0304 }
0305
0306 return board_added(ctrl);
0307 }
0308
0309 static int pciehp_enable_slot(struct controller *ctrl)
0310 {
0311 int ret;
0312
0313 pm_runtime_get_sync(&ctrl->pcie->port->dev);
0314 ret = __pciehp_enable_slot(ctrl);
0315 if (ret && ATTN_BUTTN(ctrl))
0316
0317 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
0318 INDICATOR_NOOP);
0319 pm_runtime_put(&ctrl->pcie->port->dev);
0320
0321 mutex_lock(&ctrl->state_lock);
0322 ctrl->state = ret ? OFF_STATE : ON_STATE;
0323 mutex_unlock(&ctrl->state_lock);
0324
0325 return ret;
0326 }
0327
0328 static int __pciehp_disable_slot(struct controller *ctrl, bool safe_removal)
0329 {
0330 u8 getstatus = 0;
0331
0332 if (POWER_CTRL(ctrl)) {
0333 pciehp_get_power_status(ctrl, &getstatus);
0334 if (!getstatus) {
0335 ctrl_info(ctrl, "Slot(%s): Already disabled\n",
0336 slot_name(ctrl));
0337 return -EINVAL;
0338 }
0339 }
0340
0341 remove_board(ctrl, safe_removal);
0342 return 0;
0343 }
0344
0345 static int pciehp_disable_slot(struct controller *ctrl, bool safe_removal)
0346 {
0347 int ret;
0348
0349 pm_runtime_get_sync(&ctrl->pcie->port->dev);
0350 ret = __pciehp_disable_slot(ctrl, safe_removal);
0351 pm_runtime_put(&ctrl->pcie->port->dev);
0352
0353 mutex_lock(&ctrl->state_lock);
0354 ctrl->state = OFF_STATE;
0355 mutex_unlock(&ctrl->state_lock);
0356
0357 return ret;
0358 }
0359
0360 int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot)
0361 {
0362 struct controller *ctrl = to_ctrl(hotplug_slot);
0363
0364 mutex_lock(&ctrl->state_lock);
0365 switch (ctrl->state) {
0366 case BLINKINGON_STATE:
0367 case OFF_STATE:
0368 mutex_unlock(&ctrl->state_lock);
0369
0370
0371
0372
0373 ctrl->request_result = -ENODEV;
0374 pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
0375 wait_event(ctrl->requester,
0376 !atomic_read(&ctrl->pending_events) &&
0377 !ctrl->ist_running);
0378 return ctrl->request_result;
0379 case POWERON_STATE:
0380 ctrl_info(ctrl, "Slot(%s): Already in powering on state\n",
0381 slot_name(ctrl));
0382 break;
0383 case BLINKINGOFF_STATE:
0384 case ON_STATE:
0385 case POWEROFF_STATE:
0386 ctrl_info(ctrl, "Slot(%s): Already enabled\n",
0387 slot_name(ctrl));
0388 break;
0389 default:
0390 ctrl_err(ctrl, "Slot(%s): Invalid state %#x\n",
0391 slot_name(ctrl), ctrl->state);
0392 break;
0393 }
0394 mutex_unlock(&ctrl->state_lock);
0395
0396 return -ENODEV;
0397 }
0398
0399 int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot)
0400 {
0401 struct controller *ctrl = to_ctrl(hotplug_slot);
0402
0403 mutex_lock(&ctrl->state_lock);
0404 switch (ctrl->state) {
0405 case BLINKINGOFF_STATE:
0406 case ON_STATE:
0407 mutex_unlock(&ctrl->state_lock);
0408 pciehp_request(ctrl, DISABLE_SLOT);
0409 wait_event(ctrl->requester,
0410 !atomic_read(&ctrl->pending_events) &&
0411 !ctrl->ist_running);
0412 return ctrl->request_result;
0413 case POWEROFF_STATE:
0414 ctrl_info(ctrl, "Slot(%s): Already in powering off state\n",
0415 slot_name(ctrl));
0416 break;
0417 case BLINKINGON_STATE:
0418 case OFF_STATE:
0419 case POWERON_STATE:
0420 ctrl_info(ctrl, "Slot(%s): Already disabled\n",
0421 slot_name(ctrl));
0422 break;
0423 default:
0424 ctrl_err(ctrl, "Slot(%s): Invalid state %#x\n",
0425 slot_name(ctrl), ctrl->state);
0426 break;
0427 }
0428 mutex_unlock(&ctrl->state_lock);
0429
0430 return -ENODEV;
0431 }