129310e5eSGavin Shan /* 229310e5eSGavin Shan * The file intends to implement the platform dependent EEH operations on 329310e5eSGavin Shan * powernv platform. Actually, the powernv was created in order to fully 429310e5eSGavin Shan * hypervisor support. 529310e5eSGavin Shan * 629310e5eSGavin Shan * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013. 729310e5eSGavin Shan * 829310e5eSGavin Shan * This program is free software; you can redistribute it and/or modify 929310e5eSGavin Shan * it under the terms of the GNU General Public License as published by 1029310e5eSGavin Shan * the Free Software Foundation; either version 2 of the License, or 1129310e5eSGavin Shan * (at your option) any later version. 1229310e5eSGavin Shan */ 1329310e5eSGavin Shan 1429310e5eSGavin Shan #include <linux/atomic.h> 1529310e5eSGavin Shan #include <linux/delay.h> 1629310e5eSGavin Shan #include <linux/export.h> 1729310e5eSGavin Shan #include <linux/init.h> 1829310e5eSGavin Shan #include <linux/list.h> 1929310e5eSGavin Shan #include <linux/msi.h> 2029310e5eSGavin Shan #include <linux/of.h> 2129310e5eSGavin Shan #include <linux/pci.h> 2229310e5eSGavin Shan #include <linux/proc_fs.h> 2329310e5eSGavin Shan #include <linux/rbtree.h> 2429310e5eSGavin Shan #include <linux/sched.h> 2529310e5eSGavin Shan #include <linux/seq_file.h> 2629310e5eSGavin Shan #include <linux/spinlock.h> 2729310e5eSGavin Shan 2829310e5eSGavin Shan #include <asm/eeh.h> 2929310e5eSGavin Shan #include <asm/eeh_event.h> 3029310e5eSGavin Shan #include <asm/firmware.h> 3129310e5eSGavin Shan #include <asm/io.h> 3229310e5eSGavin Shan #include <asm/iommu.h> 3329310e5eSGavin Shan #include <asm/machdep.h> 3429310e5eSGavin Shan #include <asm/msi_bitmap.h> 3529310e5eSGavin Shan #include <asm/opal.h> 3629310e5eSGavin Shan #include <asm/ppc-pci.h> 3729310e5eSGavin Shan 3829310e5eSGavin Shan #include "powernv.h" 3929310e5eSGavin Shan #include "pci.h" 4029310e5eSGavin Shan 4129310e5eSGavin Shan /** 4229310e5eSGavin Shan * powernv_eeh_init - EEH platform dependent initialization 4329310e5eSGavin Shan * 4429310e5eSGavin Shan * EEH platform dependent initialization on powernv 4529310e5eSGavin Shan */ 4629310e5eSGavin Shan static int powernv_eeh_init(void) 4729310e5eSGavin Shan { 4829310e5eSGavin Shan /* We require OPALv3 */ 4929310e5eSGavin Shan if (!firmware_has_feature(FW_FEATURE_OPALv3)) { 5029310e5eSGavin Shan pr_warning("%s: OPALv3 is required !\n", __func__); 5129310e5eSGavin Shan return -EINVAL; 5229310e5eSGavin Shan } 5329310e5eSGavin Shan 5429310e5eSGavin Shan /* Set EEH probe mode */ 5529310e5eSGavin Shan eeh_probe_mode_set(EEH_PROBE_MODE_DEV); 5629310e5eSGavin Shan 5729310e5eSGavin Shan return 0; 5829310e5eSGavin Shan } 5929310e5eSGavin Shan 6029310e5eSGavin Shan /** 6129310e5eSGavin Shan * powernv_eeh_post_init - EEH platform dependent post initialization 6229310e5eSGavin Shan * 6329310e5eSGavin Shan * EEH platform dependent post initialization on powernv. When 6429310e5eSGavin Shan * the function is called, the EEH PEs and devices should have 6529310e5eSGavin Shan * been built. If the I/O cache staff has been built, EEH is 6629310e5eSGavin Shan * ready to supply service. 6729310e5eSGavin Shan */ 6829310e5eSGavin Shan static int powernv_eeh_post_init(void) 6929310e5eSGavin Shan { 7029310e5eSGavin Shan struct pci_controller *hose; 7129310e5eSGavin Shan struct pnv_phb *phb; 7229310e5eSGavin Shan int ret = 0; 7329310e5eSGavin Shan 7429310e5eSGavin Shan list_for_each_entry(hose, &hose_list, list_node) { 7529310e5eSGavin Shan phb = hose->private_data; 7629310e5eSGavin Shan 7729310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->post_init) { 7829310e5eSGavin Shan ret = phb->eeh_ops->post_init(hose); 7929310e5eSGavin Shan if (ret) 8029310e5eSGavin Shan break; 8129310e5eSGavin Shan } 8229310e5eSGavin Shan } 8329310e5eSGavin Shan 8429310e5eSGavin Shan return ret; 8529310e5eSGavin Shan } 8629310e5eSGavin Shan 8729310e5eSGavin Shan /** 8829310e5eSGavin Shan * powernv_eeh_dev_probe - Do probe on PCI device 8929310e5eSGavin Shan * @dev: PCI device 9029310e5eSGavin Shan * @flag: unused 9129310e5eSGavin Shan * 9229310e5eSGavin Shan * When EEH module is installed during system boot, all PCI devices 9329310e5eSGavin Shan * are checked one by one to see if it supports EEH. The function 9429310e5eSGavin Shan * is introduced for the purpose. By default, EEH has been enabled 9529310e5eSGavin Shan * on all PCI devices. That's to say, we only need do necessary 9629310e5eSGavin Shan * initialization on the corresponding eeh device and create PE 9729310e5eSGavin Shan * accordingly. 9829310e5eSGavin Shan * 9929310e5eSGavin Shan * It's notable that's unsafe to retrieve the EEH device through 10029310e5eSGavin Shan * the corresponding PCI device. During the PCI device hotplug, which 10129310e5eSGavin Shan * was possiblly triggered by EEH core, the binding between EEH device 10229310e5eSGavin Shan * and the PCI device isn't built yet. 10329310e5eSGavin Shan */ 10429310e5eSGavin Shan static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) 10529310e5eSGavin Shan { 10629310e5eSGavin Shan struct pci_controller *hose = pci_bus_to_host(dev->bus); 10729310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 10829310e5eSGavin Shan struct device_node *dn = pci_device_to_OF_node(dev); 10929310e5eSGavin Shan struct eeh_dev *edev = of_node_to_eeh_dev(dn); 11029310e5eSGavin Shan 11129310e5eSGavin Shan /* 11229310e5eSGavin Shan * When probing the root bridge, which doesn't have any 11329310e5eSGavin Shan * subordinate PCI devices. We don't have OF node for 11429310e5eSGavin Shan * the root bridge. So it's not reasonable to continue 11529310e5eSGavin Shan * the probing. 11629310e5eSGavin Shan */ 11729310e5eSGavin Shan if (!dn || !edev) 11829310e5eSGavin Shan return 0; 11929310e5eSGavin Shan 12029310e5eSGavin Shan /* Skip for PCI-ISA bridge */ 12129310e5eSGavin Shan if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA) 12229310e5eSGavin Shan return 0; 12329310e5eSGavin Shan 12429310e5eSGavin Shan /* Initialize eeh device */ 12529310e5eSGavin Shan edev->class_code = dev->class; 12629310e5eSGavin Shan edev->mode = 0; 12729310e5eSGavin Shan edev->config_addr = ((dev->bus->number << 8) | dev->devfn); 12829310e5eSGavin Shan edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff); 12929310e5eSGavin Shan 13029310e5eSGavin Shan /* Create PE */ 13129310e5eSGavin Shan eeh_add_to_parent_pe(edev); 13229310e5eSGavin Shan 13329310e5eSGavin Shan /* 13429310e5eSGavin Shan * Enable EEH explicitly so that we will do EEH check 13529310e5eSGavin Shan * while accessing I/O stuff 13629310e5eSGavin Shan * 13729310e5eSGavin Shan * FIXME: Enable that for PHB3 later 13829310e5eSGavin Shan */ 13929310e5eSGavin Shan if (phb->type == PNV_PHB_IODA1) 14029310e5eSGavin Shan eeh_subsystem_enabled = 1; 14129310e5eSGavin Shan 14229310e5eSGavin Shan /* Save memory bars */ 14329310e5eSGavin Shan eeh_save_bars(edev); 14429310e5eSGavin Shan 14529310e5eSGavin Shan return 0; 14629310e5eSGavin Shan } 14729310e5eSGavin Shan 14829310e5eSGavin Shan /** 14929310e5eSGavin Shan * powernv_eeh_set_option - Initialize EEH or MMIO/DMA reenable 15029310e5eSGavin Shan * @pe: EEH PE 15129310e5eSGavin Shan * @option: operation to be issued 15229310e5eSGavin Shan * 15329310e5eSGavin Shan * The function is used to control the EEH functionality globally. 15429310e5eSGavin Shan * Currently, following options are support according to PAPR: 15529310e5eSGavin Shan * Enable EEH, Disable EEH, Enable MMIO and Enable DMA 15629310e5eSGavin Shan */ 15729310e5eSGavin Shan static int powernv_eeh_set_option(struct eeh_pe *pe, int option) 15829310e5eSGavin Shan { 15929310e5eSGavin Shan struct pci_controller *hose = pe->phb; 16029310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 16129310e5eSGavin Shan int ret = -EEXIST; 16229310e5eSGavin Shan 16329310e5eSGavin Shan /* 16429310e5eSGavin Shan * What we need do is pass it down for hardware 16529310e5eSGavin Shan * implementation to handle it. 16629310e5eSGavin Shan */ 16729310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->set_option) 16829310e5eSGavin Shan ret = phb->eeh_ops->set_option(pe, option); 16929310e5eSGavin Shan 17029310e5eSGavin Shan return ret; 17129310e5eSGavin Shan } 17229310e5eSGavin Shan 17329310e5eSGavin Shan /** 17429310e5eSGavin Shan * powernv_eeh_get_pe_addr - Retrieve PE address 17529310e5eSGavin Shan * @pe: EEH PE 17629310e5eSGavin Shan * 17729310e5eSGavin Shan * Retrieve the PE address according to the given tranditional 17829310e5eSGavin Shan * PCI BDF (Bus/Device/Function) address. 17929310e5eSGavin Shan */ 18029310e5eSGavin Shan static int powernv_eeh_get_pe_addr(struct eeh_pe *pe) 18129310e5eSGavin Shan { 18229310e5eSGavin Shan return pe->addr; 18329310e5eSGavin Shan } 18429310e5eSGavin Shan 18529310e5eSGavin Shan /** 18629310e5eSGavin Shan * powernv_eeh_get_state - Retrieve PE state 18729310e5eSGavin Shan * @pe: EEH PE 18829310e5eSGavin Shan * @delay: delay while PE state is temporarily unavailable 18929310e5eSGavin Shan * 19029310e5eSGavin Shan * Retrieve the state of the specified PE. For IODA-compitable 19129310e5eSGavin Shan * platform, it should be retrieved from IODA table. Therefore, 19229310e5eSGavin Shan * we prefer passing down to hardware implementation to handle 19329310e5eSGavin Shan * it. 19429310e5eSGavin Shan */ 19529310e5eSGavin Shan static int powernv_eeh_get_state(struct eeh_pe *pe, int *delay) 19629310e5eSGavin Shan { 19729310e5eSGavin Shan struct pci_controller *hose = pe->phb; 19829310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 19929310e5eSGavin Shan int ret = EEH_STATE_NOT_SUPPORT; 20029310e5eSGavin Shan 20129310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->get_state) { 20229310e5eSGavin Shan ret = phb->eeh_ops->get_state(pe); 20329310e5eSGavin Shan 20429310e5eSGavin Shan /* 20529310e5eSGavin Shan * If the PE state is temporarily unavailable, 20629310e5eSGavin Shan * to inform the EEH core delay for default 20729310e5eSGavin Shan * period (1 second) 20829310e5eSGavin Shan */ 20929310e5eSGavin Shan if (delay) { 21029310e5eSGavin Shan *delay = 0; 21129310e5eSGavin Shan if (ret & EEH_STATE_UNAVAILABLE) 21229310e5eSGavin Shan *delay = 1000; 21329310e5eSGavin Shan } 21429310e5eSGavin Shan } 21529310e5eSGavin Shan 21629310e5eSGavin Shan return ret; 21729310e5eSGavin Shan } 21829310e5eSGavin Shan 21929310e5eSGavin Shan /** 22029310e5eSGavin Shan * powernv_eeh_reset - Reset the specified PE 22129310e5eSGavin Shan * @pe: EEH PE 22229310e5eSGavin Shan * @option: reset option 22329310e5eSGavin Shan * 22429310e5eSGavin Shan * Reset the specified PE 22529310e5eSGavin Shan */ 22629310e5eSGavin Shan static int powernv_eeh_reset(struct eeh_pe *pe, int option) 22729310e5eSGavin Shan { 22829310e5eSGavin Shan struct pci_controller *hose = pe->phb; 22929310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 23029310e5eSGavin Shan int ret = -EEXIST; 23129310e5eSGavin Shan 23229310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->reset) 23329310e5eSGavin Shan ret = phb->eeh_ops->reset(pe, option); 23429310e5eSGavin Shan 23529310e5eSGavin Shan return ret; 23629310e5eSGavin Shan } 23729310e5eSGavin Shan 23829310e5eSGavin Shan /** 23929310e5eSGavin Shan * powernv_eeh_wait_state - Wait for PE state 24029310e5eSGavin Shan * @pe: EEH PE 24129310e5eSGavin Shan * @max_wait: maximal period in microsecond 24229310e5eSGavin Shan * 24329310e5eSGavin Shan * Wait for the state of associated PE. It might take some time 24429310e5eSGavin Shan * to retrieve the PE's state. 24529310e5eSGavin Shan */ 24629310e5eSGavin Shan static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait) 24729310e5eSGavin Shan { 24829310e5eSGavin Shan int ret; 24929310e5eSGavin Shan int mwait; 25029310e5eSGavin Shan 25129310e5eSGavin Shan while (1) { 25229310e5eSGavin Shan ret = powernv_eeh_get_state(pe, &mwait); 25329310e5eSGavin Shan 25429310e5eSGavin Shan /* 25529310e5eSGavin Shan * If the PE's state is temporarily unavailable, 25629310e5eSGavin Shan * we have to wait for the specified time. Otherwise, 25729310e5eSGavin Shan * the PE's state will be returned immediately. 25829310e5eSGavin Shan */ 25929310e5eSGavin Shan if (ret != EEH_STATE_UNAVAILABLE) 26029310e5eSGavin Shan return ret; 26129310e5eSGavin Shan 26229310e5eSGavin Shan max_wait -= mwait; 26329310e5eSGavin Shan if (max_wait <= 0) { 26429310e5eSGavin Shan pr_warning("%s: Timeout getting PE#%x's state (%d)\n", 26529310e5eSGavin Shan __func__, pe->addr, max_wait); 26629310e5eSGavin Shan return EEH_STATE_NOT_SUPPORT; 26729310e5eSGavin Shan } 26829310e5eSGavin Shan 26929310e5eSGavin Shan msleep(mwait); 27029310e5eSGavin Shan } 27129310e5eSGavin Shan 27229310e5eSGavin Shan return EEH_STATE_NOT_SUPPORT; 27329310e5eSGavin Shan } 27429310e5eSGavin Shan 27529310e5eSGavin Shan /** 27629310e5eSGavin Shan * powernv_eeh_get_log - Retrieve error log 27729310e5eSGavin Shan * @pe: EEH PE 27829310e5eSGavin Shan * @severity: temporary or permanent error log 27929310e5eSGavin Shan * @drv_log: driver log to be combined with retrieved error log 28029310e5eSGavin Shan * @len: length of driver log 28129310e5eSGavin Shan * 28229310e5eSGavin Shan * Retrieve the temporary or permanent error from the PE. 28329310e5eSGavin Shan */ 28429310e5eSGavin Shan static int powernv_eeh_get_log(struct eeh_pe *pe, int severity, 28529310e5eSGavin Shan char *drv_log, unsigned long len) 28629310e5eSGavin Shan { 28729310e5eSGavin Shan struct pci_controller *hose = pe->phb; 28829310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 28929310e5eSGavin Shan int ret = -EEXIST; 29029310e5eSGavin Shan 29129310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->get_log) 29229310e5eSGavin Shan ret = phb->eeh_ops->get_log(pe, severity, drv_log, len); 29329310e5eSGavin Shan 29429310e5eSGavin Shan return ret; 29529310e5eSGavin Shan } 29629310e5eSGavin Shan 29729310e5eSGavin Shan /** 29829310e5eSGavin Shan * powernv_eeh_configure_bridge - Configure PCI bridges in the indicated PE 29929310e5eSGavin Shan * @pe: EEH PE 30029310e5eSGavin Shan * 30129310e5eSGavin Shan * The function will be called to reconfigure the bridges included 30229310e5eSGavin Shan * in the specified PE so that the mulfunctional PE would be recovered 30329310e5eSGavin Shan * again. 30429310e5eSGavin Shan */ 30529310e5eSGavin Shan static int powernv_eeh_configure_bridge(struct eeh_pe *pe) 30629310e5eSGavin Shan { 30729310e5eSGavin Shan struct pci_controller *hose = pe->phb; 30829310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 30929310e5eSGavin Shan int ret = 0; 31029310e5eSGavin Shan 31129310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->configure_bridge) 31229310e5eSGavin Shan ret = phb->eeh_ops->configure_bridge(pe); 31329310e5eSGavin Shan 31429310e5eSGavin Shan return ret; 31529310e5eSGavin Shan } 31629310e5eSGavin Shan 31729310e5eSGavin Shan /** 31829310e5eSGavin Shan * powernv_eeh_read_config - Read PCI config space 31929310e5eSGavin Shan * @dn: device node 32029310e5eSGavin Shan * @where: PCI address 32129310e5eSGavin Shan * @size: size to read 32229310e5eSGavin Shan * @val: return value 32329310e5eSGavin Shan * 32429310e5eSGavin Shan * Read config space from the speicifed device 32529310e5eSGavin Shan */ 32629310e5eSGavin Shan static int powernv_eeh_read_config(struct device_node *dn, int where, 32729310e5eSGavin Shan int size, u32 *val) 32829310e5eSGavin Shan { 32929310e5eSGavin Shan struct eeh_dev *edev = of_node_to_eeh_dev(dn); 33029310e5eSGavin Shan struct pci_dev *dev = eeh_dev_to_pci_dev(edev); 33129310e5eSGavin Shan struct pci_controller *hose = edev->phb; 33229310e5eSGavin Shan 33329310e5eSGavin Shan return hose->ops->read(dev->bus, dev->devfn, where, size, val); 33429310e5eSGavin Shan } 33529310e5eSGavin Shan 33629310e5eSGavin Shan /** 33729310e5eSGavin Shan * powernv_eeh_write_config - Write PCI config space 33829310e5eSGavin Shan * @dn: device node 33929310e5eSGavin Shan * @where: PCI address 34029310e5eSGavin Shan * @size: size to write 34129310e5eSGavin Shan * @val: value to be written 34229310e5eSGavin Shan * 34329310e5eSGavin Shan * Write config space to the specified device 34429310e5eSGavin Shan */ 34529310e5eSGavin Shan static int powernv_eeh_write_config(struct device_node *dn, int where, 34629310e5eSGavin Shan int size, u32 val) 34729310e5eSGavin Shan { 34829310e5eSGavin Shan struct eeh_dev *edev = of_node_to_eeh_dev(dn); 34929310e5eSGavin Shan struct pci_dev *dev = eeh_dev_to_pci_dev(edev); 35029310e5eSGavin Shan struct pci_controller *hose = edev->phb; 35129310e5eSGavin Shan 35229310e5eSGavin Shan hose = pci_bus_to_host(dev->bus); 35329310e5eSGavin Shan 35429310e5eSGavin Shan return hose->ops->write(dev->bus, dev->devfn, where, size, val); 35529310e5eSGavin Shan } 35629310e5eSGavin Shan 35729310e5eSGavin Shan /** 35829310e5eSGavin Shan * powernv_eeh_next_error - Retrieve next EEH error to handle 35929310e5eSGavin Shan * @pe: Affected PE 36029310e5eSGavin Shan * 36129310e5eSGavin Shan * Using OPAL API, to retrieve next EEH error for EEH core to handle 36229310e5eSGavin Shan */ 36329310e5eSGavin Shan static int powernv_eeh_next_error(struct eeh_pe **pe) 36429310e5eSGavin Shan { 36529310e5eSGavin Shan struct pci_controller *hose; 36629310e5eSGavin Shan struct pnv_phb *phb = NULL; 36729310e5eSGavin Shan 36829310e5eSGavin Shan list_for_each_entry(hose, &hose_list, list_node) { 36929310e5eSGavin Shan phb = hose->private_data; 37029310e5eSGavin Shan break; 37129310e5eSGavin Shan } 37229310e5eSGavin Shan 37329310e5eSGavin Shan if (phb && phb->eeh_ops->next_error) 37429310e5eSGavin Shan return phb->eeh_ops->next_error(pe); 37529310e5eSGavin Shan 37629310e5eSGavin Shan return -EEXIST; 37729310e5eSGavin Shan } 37829310e5eSGavin Shan 37929310e5eSGavin Shan static struct eeh_ops powernv_eeh_ops = { 38029310e5eSGavin Shan .name = "powernv", 38129310e5eSGavin Shan .init = powernv_eeh_init, 38229310e5eSGavin Shan .post_init = powernv_eeh_post_init, 38329310e5eSGavin Shan .of_probe = NULL, 38429310e5eSGavin Shan .dev_probe = powernv_eeh_dev_probe, 38529310e5eSGavin Shan .set_option = powernv_eeh_set_option, 38629310e5eSGavin Shan .get_pe_addr = powernv_eeh_get_pe_addr, 38729310e5eSGavin Shan .get_state = powernv_eeh_get_state, 38829310e5eSGavin Shan .reset = powernv_eeh_reset, 38929310e5eSGavin Shan .wait_state = powernv_eeh_wait_state, 39029310e5eSGavin Shan .get_log = powernv_eeh_get_log, 39129310e5eSGavin Shan .configure_bridge = powernv_eeh_configure_bridge, 39229310e5eSGavin Shan .read_config = powernv_eeh_read_config, 39329310e5eSGavin Shan .write_config = powernv_eeh_write_config, 39429310e5eSGavin Shan .next_error = powernv_eeh_next_error 39529310e5eSGavin Shan }; 39629310e5eSGavin Shan 39729310e5eSGavin Shan /** 39829310e5eSGavin Shan * eeh_powernv_init - Register platform dependent EEH operations 39929310e5eSGavin Shan * 40029310e5eSGavin Shan * EEH initialization on powernv platform. This function should be 40129310e5eSGavin Shan * called before any EEH related functions. 40229310e5eSGavin Shan */ 40329310e5eSGavin Shan static int __init eeh_powernv_init(void) 40429310e5eSGavin Shan { 40529310e5eSGavin Shan int ret = -EINVAL; 40629310e5eSGavin Shan 40729310e5eSGavin Shan if (!machine_is(powernv)) 40829310e5eSGavin Shan return ret; 40929310e5eSGavin Shan 41029310e5eSGavin Shan ret = eeh_ops_register(&powernv_eeh_ops); 41129310e5eSGavin Shan if (!ret) 41229310e5eSGavin Shan pr_info("EEH: PowerNV platform initialized\n"); 41329310e5eSGavin Shan else 41429310e5eSGavin Shan pr_info("EEH: Failed to initialize PowerNV platform (%d)\n", ret); 41529310e5eSGavin Shan 41629310e5eSGavin Shan return ret; 41729310e5eSGavin Shan } 41829310e5eSGavin Shan 41929310e5eSGavin Shan early_initcall(eeh_powernv_init); 420