Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * PCI Hotplug Driver for PowerPC PowerNV platform.
  4 *
  5 * Copyright Gavin Shan, IBM Corporation 2016.
  6 */
  7
  8#include <linux/libfdt.h>
  9#include <linux/module.h>
 10#include <linux/pci.h>
 11#include <linux/pci_hotplug.h>
 12
 13#include <asm/opal.h>
 14#include <asm/pnv-pci.h>
 15#include <asm/ppc-pci.h>
 16
 17#define DRIVER_VERSION	"0.1"
 18#define DRIVER_AUTHOR	"Gavin Shan, IBM Corporation"
 19#define DRIVER_DESC	"PowerPC PowerNV PCI Hotplug Driver"
 20
 21struct pnv_php_event {
 22	bool			added;
 23	struct pnv_php_slot	*php_slot;
 24	struct work_struct	work;
 25};
 26
 27static LIST_HEAD(pnv_php_slot_list);
 28static DEFINE_SPINLOCK(pnv_php_lock);
 29
 30static void pnv_php_register(struct device_node *dn);
 31static void pnv_php_unregister_one(struct device_node *dn);
 32static void pnv_php_unregister(struct device_node *dn);
 33
 34static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
 35				bool disable_device)
 36{
 37	struct pci_dev *pdev = php_slot->pdev;
 38	int irq = php_slot->irq;
 39	u16 ctrl;
 40
 41	if (php_slot->irq > 0) {
 42		pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl);
 43		ctrl &= ~(PCI_EXP_SLTCTL_HPIE |
 44			  PCI_EXP_SLTCTL_PDCE |
 45			  PCI_EXP_SLTCTL_DLLSCE);
 46		pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl);
 47
 48		free_irq(php_slot->irq, php_slot);
 49		php_slot->irq = 0;
 50	}
 51
 52	if (php_slot->wq) {
 53		destroy_workqueue(php_slot->wq);
 54		php_slot->wq = NULL;
 55	}
 56
 57	if (disable_device || irq > 0) {
 58		if (pdev->msix_enabled)
 59			pci_disable_msix(pdev);
 60		else if (pdev->msi_enabled)
 61			pci_disable_msi(pdev);
 62
 63		pci_disable_device(pdev);
 64	}
 65}
 66
 67static void pnv_php_free_slot(struct kref *kref)
 68{
 69	struct pnv_php_slot *php_slot = container_of(kref,
 70					struct pnv_php_slot, kref);
 71
 72	WARN_ON(!list_empty(&php_slot->children));
 73	pnv_php_disable_irq(php_slot, false);
 74	kfree(php_slot->name);
 75	kfree(php_slot);
 76}
 77
 78static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot)
 79{
 80
 81	if (!php_slot)
 82		return;
 83
 84	kref_put(&php_slot->kref, pnv_php_free_slot);
 85}
 86
 87static struct pnv_php_slot *pnv_php_match(struct device_node *dn,
 88					  struct pnv_php_slot *php_slot)
 89{
 90	struct pnv_php_slot *target, *tmp;
 91
 92	if (php_slot->dn == dn) {
 93		kref_get(&php_slot->kref);
 94		return php_slot;
 95	}
 96
 97	list_for_each_entry(tmp, &php_slot->children, link) {
 98		target = pnv_php_match(dn, tmp);
 99		if (target)
100			return target;
101	}
102
103	return NULL;
104}
105
106struct pnv_php_slot *pnv_php_find_slot(struct device_node *dn)
107{
108	struct pnv_php_slot *php_slot, *tmp;
109	unsigned long flags;
110
111	spin_lock_irqsave(&pnv_php_lock, flags);
112	list_for_each_entry(tmp, &pnv_php_slot_list, link) {
113		php_slot = pnv_php_match(dn, tmp);
114		if (php_slot) {
115			spin_unlock_irqrestore(&pnv_php_lock, flags);
116			return php_slot;
117		}
118	}
119	spin_unlock_irqrestore(&pnv_php_lock, flags);
120
121	return NULL;
122}
123EXPORT_SYMBOL_GPL(pnv_php_find_slot);
124
125/*
126 * Remove pdn for all children of the indicated device node.
127 * The function should remove pdn in a depth-first manner.
128 */
129static void pnv_php_rmv_pdns(struct device_node *dn)
130{
131	struct device_node *child;
132
133	for_each_child_of_node(dn, child) {
134		pnv_php_rmv_pdns(child);
135
136		pci_remove_device_node_info(child);
137	}
138}
139
140/*
141 * Detach all child nodes of the indicated device nodes. The
142 * function should handle device nodes in depth-first manner.
143 *
144 * We should not invoke of_node_release() as the memory for
145 * individual device node is part of large memory block. The
146 * large block is allocated from memblock (system bootup) or
147 * kmalloc() when unflattening the device tree by OF changeset.
148 * We can not free the large block allocated from memblock. For
149 * later case, it should be released at once.
150 */
151static void pnv_php_detach_device_nodes(struct device_node *parent)
152{
153	struct device_node *dn;
154	int refcount;
155
156	for_each_child_of_node(parent, dn) {
157		pnv_php_detach_device_nodes(dn);
158
159		of_node_put(dn);
160		refcount = kref_read(&dn->kobj.kref);
161		if (refcount != 1)
162			pr_warn("Invalid refcount %d on <%pOF>\n",
163				refcount, dn);
164
165		of_detach_node(dn);
166	}
167}
168
169static void pnv_php_rmv_devtree(struct pnv_php_slot *php_slot)
170{
171	pnv_php_rmv_pdns(php_slot->dn);
172
173	/*
174	 * Decrease the refcount if the device nodes were created
175	 * through OF changeset before detaching them.
176	 */
177	if (php_slot->fdt)
178		of_changeset_destroy(&php_slot->ocs);
179	pnv_php_detach_device_nodes(php_slot->dn);
180
181	if (php_slot->fdt) {
182		kfree(php_slot->dt);
183		kfree(php_slot->fdt);
184		php_slot->dt        = NULL;
185		php_slot->dn->child = NULL;
186		php_slot->fdt       = NULL;
187	}
188}
189
190/*
191 * As the nodes in OF changeset are applied in reverse order, we
192 * need revert the nodes in advance so that we have correct node
193 * order after the changeset is applied.
194 */
195static void pnv_php_reverse_nodes(struct device_node *parent)
196{
197	struct device_node *child, *next;
198
199	/* In-depth first */
200	for_each_child_of_node(parent, child)
201		pnv_php_reverse_nodes(child);
202
203	/* Reverse the nodes in the child list */
204	child = parent->child;
205	parent->child = NULL;
206	while (child) {
207		next = child->sibling;
208
209		child->sibling = parent->child;
210		parent->child = child;
211		child = next;
212	}
213}
214
215static int pnv_php_populate_changeset(struct of_changeset *ocs,
216				      struct device_node *dn)
217{
218	struct device_node *child;
219	int ret = 0;
220
221	for_each_child_of_node(dn, child) {
222		ret = of_changeset_attach_node(ocs, child);
223		if (ret)
224			break;
225
226		ret = pnv_php_populate_changeset(ocs, child);
227		if (ret)
228			break;
229	}
230
231	return ret;
232}
233
234static void *pnv_php_add_one_pdn(struct device_node *dn, void *data)
235{
236	struct pci_controller *hose = (struct pci_controller *)data;
237	struct pci_dn *pdn;
238
239	pdn = pci_add_device_node_info(hose, dn);
240	if (!pdn)
241		return ERR_PTR(-ENOMEM);
242
243	return NULL;
244}
245
246static void pnv_php_add_pdns(struct pnv_php_slot *slot)
247{
248	struct pci_controller *hose = pci_bus_to_host(slot->bus);
249
250	pci_traverse_device_nodes(slot->dn, pnv_php_add_one_pdn, hose);
251}
252
253static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
254{
255	void *fdt, *fdt1, *dt;
256	int ret;
257
258	/* We don't know the FDT blob size. We try to get it through
259	 * maximal memory chunk and then copy it to another chunk that
260	 * fits the real size.
261	 */
262	fdt1 = kzalloc(0x10000, GFP_KERNEL);
263	if (!fdt1) {
264		ret = -ENOMEM;
265		goto out;
266	}
267
268	ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
269	if (ret) {
270		pci_warn(php_slot->pdev, "Error %d getting FDT blob\n", ret);
271		goto free_fdt1;
272	}
273
274	fdt = kzalloc(fdt_totalsize(fdt1), GFP_KERNEL);
275	if (!fdt) {
276		ret = -ENOMEM;
277		goto free_fdt1;
278	}
279
280	/* Unflatten device tree blob */
281	memcpy(fdt, fdt1, fdt_totalsize(fdt1));
282	dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL);
283	if (!dt) {
284		ret = -EINVAL;
285		pci_warn(php_slot->pdev, "Cannot unflatten FDT\n");
286		goto free_fdt;
287	}
288
289	/* Initialize and apply the changeset */
290	of_changeset_init(&php_slot->ocs);
291	pnv_php_reverse_nodes(php_slot->dn);
292	ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn);
293	if (ret) {
294		pnv_php_reverse_nodes(php_slot->dn);
295		pci_warn(php_slot->pdev, "Error %d populating changeset\n",
296			 ret);
297		goto free_dt;
298	}
299
300	php_slot->dn->child = NULL;
301	ret = of_changeset_apply(&php_slot->ocs);
302	if (ret) {
303		pci_warn(php_slot->pdev, "Error %d applying changeset\n", ret);
304		goto destroy_changeset;
305	}
306
307	/* Add device node firmware data */
308	pnv_php_add_pdns(php_slot);
309	php_slot->fdt = fdt;
310	php_slot->dt  = dt;
311	kfree(fdt1);
312	goto out;
313
314destroy_changeset:
315	of_changeset_destroy(&php_slot->ocs);
316free_dt:
317	kfree(dt);
318	php_slot->dn->child = NULL;
319free_fdt:
320	kfree(fdt);
321free_fdt1:
322	kfree(fdt1);
323out:
324	return ret;
325}
326
327int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
328				 uint8_t state)
329{
330	struct pnv_php_slot *php_slot = slot->private;
331	struct opal_msg msg;
332	int ret;
333
334	ret = pnv_pci_set_power_state(php_slot->id, state, &msg);
335	if (ret > 0) {
336		if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle	||
337		    be64_to_cpu(msg.params[2]) != state			||
338		    be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
339			pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n",
340				 be64_to_cpu(msg.params[1]),
341				 be64_to_cpu(msg.params[2]),
342				 be64_to_cpu(msg.params[3]));
343			return -ENOMSG;
344		}
345	} else if (ret < 0) {
346		pci_warn(php_slot->pdev, "Error %d powering %s\n",
347			 ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
348		return ret;
349	}
350
351	if (state == OPAL_PCI_SLOT_POWER_OFF || state == OPAL_PCI_SLOT_OFFLINE)
352		pnv_php_rmv_devtree(php_slot);
353	else
354		ret = pnv_php_add_devtree(php_slot);
355
356	return ret;
357}
358EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state);
359
360static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
361{
362	struct pnv_php_slot *php_slot = slot->private;
363	uint8_t power_state = OPAL_PCI_SLOT_POWER_ON;
364	int ret;
365
366	/*
367	 * Retrieve power status from firmware. If we fail
368	 * getting that, the power status fails back to
369	 * be on.
370	 */
371	ret = pnv_pci_get_power_state(php_slot->id, &power_state);
372	if (ret) {
373		pci_warn(php_slot->pdev, "Error %d getting power status\n",
374			 ret);
375	} else {
376		*state = power_state;
377		slot->info->power_status = power_state;
378	}
379
380	return 0;
381}
382
383static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
384{
385	struct pnv_php_slot *php_slot = slot->private;
386	uint8_t presence = OPAL_PCI_SLOT_EMPTY;
387	int ret;
388
389	/*
390	 * Retrieve presence status from firmware. If we can't
391	 * get that, it will fail back to be empty.
392	 */
393	ret = pnv_pci_get_presence_state(php_slot->id, &presence);
394	if (ret >= 0) {
395		*state = presence;
396		slot->info->adapter_status = presence;
397		ret = 0;
398	} else {
399		pci_warn(php_slot->pdev, "Error %d getting presence\n", ret);
400	}
401
402	return ret;
403}
404
405static int pnv_php_set_attention_state(struct hotplug_slot *slot, u8 state)
406{
407	/* FIXME: Make it real once firmware supports it */
408	slot->info->attention_status = state;
409
410	return 0;
411}
412
413static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan)
414{
415	struct hotplug_slot *slot = &php_slot->slot;
416	uint8_t presence = OPAL_PCI_SLOT_EMPTY;
417	uint8_t power_status = OPAL_PCI_SLOT_POWER_ON;
418	int ret;
419
420	/* Check if the slot has been configured */
421	if (php_slot->state != PNV_PHP_STATE_REGISTERED)
422		return 0;
423
424	/* Retrieve slot presence status */
425	ret = pnv_php_get_adapter_state(slot, &presence);
426	if (ret)
427		return ret;
428
429	/*
430	 * Proceed if there have nothing behind the slot. However,
431	 * we should leave the slot in registered state at the
432	 * beginning. Otherwise, the PCI devices inserted afterwards
433	 * won't be probed and populated.
434	 */
435	if (presence == OPAL_PCI_SLOT_EMPTY) {
436		if (!php_slot->power_state_check) {
437			php_slot->power_state_check = true;
438
439			return 0;
440		}
441
442		goto scan;
443	}
444
445	/*
446	 * If the power supply to the slot is off, we can't detect
447	 * adapter presence state. That means we have to turn the
448	 * slot on before going to probe slot's presence state.
449	 *
450	 * On the first time, we don't change the power status to
451	 * boost system boot with assumption that the firmware
452	 * supplies consistent slot power status: empty slot always
453	 * has its power off and non-empty slot has its power on.
454	 */
455	if (!php_slot->power_state_check) {
456		php_slot->power_state_check = true;
457
458		ret = pnv_php_get_power_state(slot, &power_status);
459		if (ret)
460			return ret;
461
462		if (power_status != OPAL_PCI_SLOT_POWER_ON)
463			return 0;
464	}
465
466	/* Check the power status. Scan the slot if it is already on */
467	ret = pnv_php_get_power_state(slot, &power_status);
468	if (ret)
469		return ret;
470
471	if (power_status == OPAL_PCI_SLOT_POWER_ON)
472		goto scan;
473
474	/* Power is off, turn it on and then scan the slot */
475	ret = pnv_php_set_slot_power_state(slot, OPAL_PCI_SLOT_POWER_ON);
476	if (ret)
477		return ret;
478
479scan:
480	if (presence == OPAL_PCI_SLOT_PRESENT) {
481		if (rescan) {
482			pci_lock_rescan_remove();
483			pci_hp_add_devices(php_slot->bus);
484			pci_unlock_rescan_remove();
485		}
486
487		/* Rescan for child hotpluggable slots */
488		php_slot->state = PNV_PHP_STATE_POPULATED;
489		if (rescan)
490			pnv_php_register(php_slot->dn);
491	} else {
492		php_slot->state = PNV_PHP_STATE_POPULATED;
493	}
494
495	return 0;
496}
497
498static int pnv_php_enable_slot(struct hotplug_slot *slot)
499{
500	struct pnv_php_slot *php_slot = container_of(slot,
501						     struct pnv_php_slot, slot);
502
503	return pnv_php_enable(php_slot, true);
504}
505
506static int pnv_php_disable_slot(struct hotplug_slot *slot)
507{
508	struct pnv_php_slot *php_slot = slot->private;
509	int ret;
510
511	if (php_slot->state != PNV_PHP_STATE_POPULATED)
512		return 0;
513
514	/* Remove all devices behind the slot */
515	pci_lock_rescan_remove();
516	pci_hp_remove_devices(php_slot->bus);
517	pci_unlock_rescan_remove();
518
519	/* Detach the child hotpluggable slots */
520	pnv_php_unregister(php_slot->dn);
521
522	/* Notify firmware and remove device nodes */
523	ret = pnv_php_set_slot_power_state(slot, OPAL_PCI_SLOT_POWER_OFF);
524
525	php_slot->state = PNV_PHP_STATE_REGISTERED;
526	return ret;
527}
528
529static struct hotplug_slot_ops php_slot_ops = {
530	.get_power_status	= pnv_php_get_power_state,
531	.get_adapter_status	= pnv_php_get_adapter_state,
532	.set_attention_status	= pnv_php_set_attention_state,
533	.enable_slot		= pnv_php_enable_slot,
534	.disable_slot		= pnv_php_disable_slot,
535};
536
537static void pnv_php_release(struct hotplug_slot *slot)
538{
539	struct pnv_php_slot *php_slot = slot->private;
540	unsigned long flags;
541
542	/* Remove from global or child list */
543	spin_lock_irqsave(&pnv_php_lock, flags);
544	list_del(&php_slot->link);
545	spin_unlock_irqrestore(&pnv_php_lock, flags);
546
547	/* Detach from parent */
548	pnv_php_put_slot(php_slot);
549	pnv_php_put_slot(php_slot->parent);
550}
551
552static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn)
553{
554	struct pnv_php_slot *php_slot;
555	struct pci_bus *bus;
556	const char *label;
557	uint64_t id;
558	int ret;
559
560	ret = of_property_read_string(dn, "ibm,slot-label", &label);
561	if (ret)
562		return NULL;
563
564	if (pnv_pci_get_slot_id(dn, &id))
565		return NULL;
566
567	bus = pci_find_bus_by_node(dn);
568	if (!bus)
569		return NULL;
570
571	php_slot = kzalloc(sizeof(*php_slot), GFP_KERNEL);
572	if (!php_slot)
573		return NULL;
574
575	php_slot->name = kstrdup(label, GFP_KERNEL);
576	if (!php_slot->name) {
577		kfree(php_slot);
578		return NULL;
579	}
580
581	if (dn->child && PCI_DN(dn->child))
582		php_slot->slot_no = PCI_SLOT(PCI_DN(dn->child)->devfn);
583	else
584		php_slot->slot_no = -1;   /* Placeholder slot */
585
586	kref_init(&php_slot->kref);
587	php_slot->state	                = PNV_PHP_STATE_INITIALIZED;
588	php_slot->dn	                = dn;
589	php_slot->pdev	                = bus->self;
590	php_slot->bus	                = bus;
591	php_slot->id	                = id;
592	php_slot->power_state_check     = false;
593	php_slot->slot.ops              = &php_slot_ops;
594	php_slot->slot.info             = &php_slot->slot_info;
595	php_slot->slot.release          = pnv_php_release;
596	php_slot->slot.private          = php_slot;
597
598	INIT_LIST_HEAD(&php_slot->children);
599	INIT_LIST_HEAD(&php_slot->link);
600
601	return php_slot;
602}
603
604static int pnv_php_register_slot(struct pnv_php_slot *php_slot)
605{
606	struct pnv_php_slot *parent;
607	struct device_node *dn = php_slot->dn;
608	unsigned long flags;
609	int ret;
610
611	/* Check if the slot is registered or not */
612	parent = pnv_php_find_slot(php_slot->dn);
613	if (parent) {
614		pnv_php_put_slot(parent);
615		return -EEXIST;
616	}
617
618	/* Register PCI slot */
619	ret = pci_hp_register(&php_slot->slot, php_slot->bus,
620			      php_slot->slot_no, php_slot->name);
621	if (ret) {
622		pci_warn(php_slot->pdev, "Error %d registering slot\n", ret);
623		return ret;
624	}
625
626	/* Attach to the parent's child list or global list */
627	while ((dn = of_get_parent(dn))) {
628		if (!PCI_DN(dn)) {
629			of_node_put(dn);
630			break;
631		}
632
633		parent = pnv_php_find_slot(dn);
634		if (parent) {
635			of_node_put(dn);
636			break;
637		}
638
639		of_node_put(dn);
640	}
641
642	spin_lock_irqsave(&pnv_php_lock, flags);
643	php_slot->parent = parent;
644	if (parent)
645		list_add_tail(&php_slot->link, &parent->children);
646	else
647		list_add_tail(&php_slot->link, &pnv_php_slot_list);
648	spin_unlock_irqrestore(&pnv_php_lock, flags);
649
650	php_slot->state = PNV_PHP_STATE_REGISTERED;
651	return 0;
652}
653
654static int pnv_php_enable_msix(struct pnv_php_slot *php_slot)
655{
656	struct pci_dev *pdev = php_slot->pdev;
657	struct msix_entry entry;
658	int nr_entries, ret;
659	u16 pcie_flag;
660
661	/* Get total number of MSIx entries */
662	nr_entries = pci_msix_vec_count(pdev);
663	if (nr_entries < 0)
664		return nr_entries;
665
666	/* Check hotplug MSIx entry is in range */
667	pcie_capability_read_word(pdev, PCI_EXP_FLAGS, &pcie_flag);
668	entry.entry = (pcie_flag & PCI_EXP_FLAGS_IRQ) >> 9;
669	if (entry.entry >= nr_entries)
670		return -ERANGE;
671
672	/* Enable MSIx */
673	ret = pci_enable_msix_exact(pdev, &entry, 1);
674	if (ret) {
675		pci_warn(pdev, "Error %d enabling MSIx\n", ret);
676		return ret;
677	}
678
679	return entry.vector;
680}
681
682static void pnv_php_event_handler(struct work_struct *work)
683{
684	struct pnv_php_event *event =
685		container_of(work, struct pnv_php_event, work);
686	struct pnv_php_slot *php_slot = event->php_slot;
687
688	if (event->added)
689		pnv_php_enable_slot(&php_slot->slot);
690	else
691		pnv_php_disable_slot(&php_slot->slot);
692
693	kfree(event);
694}
695
696static irqreturn_t pnv_php_interrupt(int irq, void *data)
697{
698	struct pnv_php_slot *php_slot = data;
699	struct pci_dev *pchild, *pdev = php_slot->pdev;
700	struct eeh_dev *edev;
701	struct eeh_pe *pe;
702	struct pnv_php_event *event;
703	u16 sts, lsts;
704	u8 presence;
705	bool added;
706	unsigned long flags;
707	int ret;
708
709	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
710	sts &= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
711	pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
712	if (sts & PCI_EXP_SLTSTA_DLLSC) {
713		pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lsts);
714		added = !!(lsts & PCI_EXP_LNKSTA_DLLLA);
715	} else if (!(php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) &&
716		   (sts & PCI_EXP_SLTSTA_PDC)) {
717		ret = pnv_pci_get_presence_state(php_slot->id, &presence);
718		if (ret) {
719			pci_warn(pdev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
720				 php_slot->name, ret, sts);
721			return IRQ_HANDLED;
722		}
723
724		added = !!(presence == OPAL_PCI_SLOT_PRESENT);
725	} else {
726		return IRQ_NONE;
727	}
728
729	/* Freeze the removed PE to avoid unexpected error reporting */
730	if (!added) {
731		pchild = list_first_entry_or_null(&php_slot->bus->devices,
732						  struct pci_dev, bus_list);
733		edev = pchild ? pci_dev_to_eeh_dev(pchild) : NULL;
734		pe = edev ? edev->pe : NULL;
735		if (pe) {
736			eeh_serialize_lock(&flags);
737			eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
738			eeh_serialize_unlock(flags);
739			eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE);
740		}
741	}
742
743	/*
744	 * The PE is left in frozen state if the event is missed. It's
745	 * fine as the PCI devices (PE) aren't functional any more.
746	 */
747	event = kzalloc(sizeof(*event), GFP_ATOMIC);
748	if (!event) {
749		pci_warn(pdev, "PCI slot [%s] missed hotplug event 0x%04x\n",
750			 php_slot->name, sts);
751		return IRQ_HANDLED;
752	}
753
754	pci_info(pdev, "PCI slot [%s] %s (IRQ: %d)\n",
755		 php_slot->name, added ? "added" : "removed", irq);
756	INIT_WORK(&event->work, pnv_php_event_handler);
757	event->added = added;
758	event->php_slot = php_slot;
759	queue_work(php_slot->wq, &event->work);
760
761	return IRQ_HANDLED;
762}
763
764static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
765{
766	struct pci_dev *pdev = php_slot->pdev;
767	u32 broken_pdc = 0;
768	u16 sts, ctrl;
769	int ret;
770
771	/* Allocate workqueue */
772	php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
773	if (!php_slot->wq) {
774		pci_warn(pdev, "Cannot alloc workqueue\n");
775		pnv_php_disable_irq(php_slot, true);
776		return;
777	}
778
779	/* Check PDC (Presence Detection Change) is broken or not */
780	ret = of_property_read_u32(php_slot->dn, "ibm,slot-broken-pdc",
781				   &broken_pdc);
782	if (!ret && broken_pdc)
783		php_slot->flags |= PNV_PHP_FLAG_BROKEN_PDC;
784
785	/* Clear pending interrupts */
786	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
787	if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC)
788		sts |= PCI_EXP_SLTSTA_DLLSC;
789	else
790		sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
791	pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
792
793	/* Request the interrupt */
794	ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED,
795			  php_slot->name, php_slot);
796	if (ret) {
797		pnv_php_disable_irq(php_slot, true);
798		pci_warn(pdev, "Error %d enabling IRQ %d\n", ret, irq);
799		return;
800	}
801
802	/* Enable the interrupts */
803	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl);
804	if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) {
805		ctrl &= ~PCI_EXP_SLTCTL_PDCE;
806		ctrl |= (PCI_EXP_SLTCTL_HPIE |
807			 PCI_EXP_SLTCTL_DLLSCE);
808	} else {
809		ctrl |= (PCI_EXP_SLTCTL_HPIE |
810			 PCI_EXP_SLTCTL_PDCE |
811			 PCI_EXP_SLTCTL_DLLSCE);
812	}
813	pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl);
814
815	/* The interrupt is initialized successfully when @irq is valid */
816	php_slot->irq = irq;
817}
818
819static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
820{
821	struct pci_dev *pdev = php_slot->pdev;
822	int irq, ret;
823
824	/*
825	 * The MSI/MSIx interrupt might have been occupied by other
826	 * drivers. Don't populate the surprise hotplug capability
827	 * in that case.
828	 */
829	if (pci_dev_msi_enabled(pdev))
830		return;
831
832	ret = pci_enable_device(pdev);
833	if (ret) {
834		pci_warn(pdev, "Error %d enabling device\n", ret);
835		return;
836	}
837
838	pci_set_master(pdev);
839
840	/* Enable MSIx interrupt */
841	irq = pnv_php_enable_msix(php_slot);
842	if (irq > 0) {
843		pnv_php_init_irq(php_slot, irq);
844		return;
845	}
846
847	/*
848	 * Use MSI if MSIx doesn't work. Fail back to legacy INTx
849	 * if MSI doesn't work either
850	 */
851	ret = pci_enable_msi(pdev);
852	if (!ret || pdev->irq) {
853		irq = pdev->irq;
854		pnv_php_init_irq(php_slot, irq);
855	}
856}
857
858static int pnv_php_register_one(struct device_node *dn)
859{
860	struct pnv_php_slot *php_slot;
861	u32 prop32;
862	int ret;
863
864	/* Check if it's hotpluggable slot */
865	ret = of_property_read_u32(dn, "ibm,slot-pluggable", &prop32);
866	if (ret || !prop32)
867		return -ENXIO;
868
869	ret = of_property_read_u32(dn, "ibm,reset-by-firmware", &prop32);
870	if (ret || !prop32)
871		return -ENXIO;
872
873	php_slot = pnv_php_alloc_slot(dn);
874	if (!php_slot)
875		return -ENODEV;
876
877	ret = pnv_php_register_slot(php_slot);
878	if (ret)
879		goto free_slot;
880
881	ret = pnv_php_enable(php_slot, false);
882	if (ret)
883		goto unregister_slot;
884
885	/* Enable interrupt if the slot supports surprise hotplug */
886	ret = of_property_read_u32(dn, "ibm,slot-surprise-pluggable", &prop32);
887	if (!ret && prop32)
888		pnv_php_enable_irq(php_slot);
889
890	return 0;
891
892unregister_slot:
893	pnv_php_unregister_one(php_slot->dn);
894free_slot:
895	pnv_php_put_slot(php_slot);
896	return ret;
897}
898
899static void pnv_php_register(struct device_node *dn)
900{
901	struct device_node *child;
902
903	/*
904	 * The parent slots should be registered before their
905	 * child slots.
906	 */
907	for_each_child_of_node(dn, child) {
908		pnv_php_register_one(child);
909		pnv_php_register(child);
910	}
911}
912
913static void pnv_php_unregister_one(struct device_node *dn)
914{
915	struct pnv_php_slot *php_slot;
916
917	php_slot = pnv_php_find_slot(dn);
918	if (!php_slot)
919		return;
920
921	php_slot->state = PNV_PHP_STATE_OFFLINE;
922	pci_hp_deregister(&php_slot->slot);
923	pnv_php_put_slot(php_slot);
924}
925
926static void pnv_php_unregister(struct device_node *dn)
927{
928	struct device_node *child;
929
930	/* The child slots should go before their parent slots */
931	for_each_child_of_node(dn, child) {
932		pnv_php_unregister(child);
933		pnv_php_unregister_one(child);
934	}
935}
936
937static int __init pnv_php_init(void)
938{
939	struct device_node *dn;
940
941	pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
942	for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
943		pnv_php_register(dn);
944
945	return 0;
946}
947
948static void __exit pnv_php_exit(void)
949{
950	struct device_node *dn;
951
952	for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
953		pnv_php_unregister(dn);
954}
955
956module_init(pnv_php_init);
957module_exit(pnv_php_exit);
958
959MODULE_VERSION(DRIVER_VERSION);
960MODULE_LICENSE("GPL v2");
961MODULE_AUTHOR(DRIVER_AUTHOR);
962MODULE_DESCRIPTION(DRIVER_DESC);