linux/drivers/edac/tile_edac.c
<<
.41" /spapti /formti a .41" href="../linux+v3.9.5/drivers/edac/tile_edac.c">.41" img src="../.static/gfx/right.png" alt=">>">.4 /spapti.4 spap class="lxr_search">.41".41" input typvalhidden" namvalnavtarget" ion val">.41" input typvaltext" namvalsearch" idalsearch">.41" buttopttypvalsubmit">Search.41" Prefsi /a>.4 /spapti1" /divti1" form ac.4 input typvalhidden" namvalajax_lookup" idalajax_lookup" ion val">.1" /formti.1" div class="headingbottom">i div idalfile_contents"t
   1 /a> spap class="comment">/* /spapti   2 /a> spap class="comment"> * Copyright 2011 Tilera Corpora   3 /a> spap class="comment"> * /spapti   4 /a> spap class="comment"> *   This program is free software; you cap redistribute it and/or /spapti   5 /a> spap class="comment"> *   modify it under the terms of the GNU General Public License /spapti   6 /a> spap class="comment"> *   as published by the Free Software Founda   7 /a> spap class="comment"> * /spapti   8 /a> spap class="comment"> *   This program is distributed in the hope that it will be useful, but /spapti   9 /a> spap class="comment"> *   WITHOUT ANY WARRANTY; without even the implied warranty of /spapti  .18.a> spap class="comment"> *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or /spapti  11 /a> spap class="comment"> *   NON INFRINGEMENT.  See the GNU General Public License for /spapti  12 /a> spap class="comment"> *   more details. /spapti  13 /a> spap class="comment"> * Tilera-specific EDAC driver. /spapti  14 /a> spap class="comment"> * /spapti  15 /a> spap class="comment"> * This source code is derived from the following driver: /spapti  16 /a> spap class="comment"> * /spapti  17 /a> spap class="comment"> * Cell MIC driver for ECC counting /spapti  18 /a> spap class="comment"> * /spapti  19 /a> spap class="comment"> * Copyright 2007 Benjamin Herrenschmidt, IBM Corp. /spapti  218.a> spap class="comment"> *                <benh@kernel.crashing.org> /spapti  21 /a> spap class="comment"> * /spapti  22 /a> spap class="comment"> */ /spapti  23 /a>i  24 /a>#include <linux/module.h /a>>i  25 /a>#include <linux/init.h /a>>i  26 /a>#include <linux/platform_device.h /a>>i  27 /a>#include <linux/io.h /a>>i  28 /a>#include <linux/uaccess.h /a>>i  29 /a>#include <linux/edac.h /a>>i  30 /a>#include <hv/hypervisor.h /a>>i  31 /a>#include <hv/drv_mshim_intf.h /a>>i  32 /a>i  33 /a>#include "edac_core.h /a>"i  34 /a>i  35 /a>#define  a href="+code=DRV_NAME" class="sref">DRV_NAME /a>         spap class="string">"tile-edac"  36 /a>i  37 /a> spap class="comment">/* Number of cs_rows needed per memory controller on TILEPro. */ /spapti  38 /a>#define  a href="+code=TILE_EDAC_NR_CSROWS" class="sref">TILE_EDAC_NR_CSROWS /a>     1i  39 /a>i  418.a> spap class="comment">/* Number of channels per memory controller on TILEPro. */ /spapti  41 /a>#define  a href="+code=TILE_EDAC_NR_CHANS" class="sref">TILE_EDAC_NR_CHANS /a>      1i  42 /a>i  43 /a> spap class="comment">/* Granularity of reported error in bytes on TILEPro. */ /spapti  44 /a>#define  a href="+code=TILE_EDAC_ERROR_GRAIN" class="sref">TILE_EDAC_ERROR_GRAIN /a>   8i  45 /a>i  46 /a> spap class="comment">/* TILE processor has multiple independent memory controllers. */ /spapti  47 /a>struct  a href="+code=platform_device" class="sref">platform_device /a> * a href="+code=mshim_pdev" class="sref">mshim_pdev /a>[ a href="+code=TILE_MAX_MSHIMS" class="sref">TILE_MAX_MSHIMS /a>];i  48 /a>i  49 /a>struct  a href="+code=tile_edac_priv" class="sref">tile_edac_priv /a> {i  50 /a>        int              a href="+code=hv_devhdl" class="sref">hv_devhdl /a>;       spap class="comment">/* Hypervisor device handle. */ /spapti  51 /a>        int              a href="+code=node" class="sref">node /a>;            spap class="comment">/* Memory controller instance #. */ /spapti  52 /a>        unsigned int     a href="+code=ce_count" class="sref">ce_count /a>;        spap class="comment">/* /spapti  53 /a> spap class="comment">                                         * Correctable-error counter /spapti  54 /a> spap class="comment">                                         * kept by the driver. /spapti  55 /a> spap class="comment">                                         */ /spapti  56 /a>};i  57 /a>i  58 /a>static void  a href="+code=tile_edac_check" class="sref">tile_edac_check /a>(struct  a href="+code=mem_ctl_info" class="sref">mem_ctl_info /a> * a href="+code=mci" class="sref">mci /a>)i  59 /a>{i  60 /a>        struct  a href="+code=tile_edac_priv" class="sref">tile_edac_priv /a>   * a href="+code=priv" class="sref">priv /a> =  a href="+code=mci" class="sref">mci /a>-> a href="+code=pvt_info" class="sref">pvt_info /a>;i  61 /a>        struct  a href="+code=mshim_mem_error" class="sref">mshim_mem_error /a>   a href="+code=mem_error" class="sref">mem_error /a>;i  62 /a>i  63 /a>        if ( a href="+code=hv_dev_pread" class="sref">hv_dev_pread /a>( a href="+code=priv" class="sref">priv /a>-> a href="+code=hv_devhdl" class="sref">hv_devhdl /a>, 0, ( a href="+code=HV_VirtAddr" class="sref">HV_VirtAddr /a>)& a href="+code=mem_error" class="sref">mem_error /a>,i  64 /a>                sizeof(struct  a href="+code=mshim_mem_error" class="sref">mshim_mem_error /a>),  a href="+code=MSHIM_MEM_ERROR_OFF" class="sref">MSHIM_MEM_ERROR_OFF /a>) !=i  65 /a>                sizeof(struct  a href="+code=mshim_mem_error" class="sref">mshim_mem_error /a>)) {i  66 /a>                 a href="+code=pr_err" class="sref">pr_err /a>( a href="+code=DRV_NAME" class="sref">DRV_NAME /a>  spap class="string">": MSHIM_MEM_ERROR_OFF pread failure.\n"  67 /a>                return;i  68 /a>        }i  69 /a>i  70 /a>         spap class="comment">/* Check if the current error count is different from the saved one. */ /spapti  71 /a>        if ( a href="+code=mem_error" class="sref">mem_error /a>. a href="+code=sbe_count" class="sref">sbe_count /a> !=  a href="+code=priv" class="sref">priv /a>-> a href="+code=ce_count" class="sref">ce_count /a>) {i  72 /a>                 a href="+code=dev_dbg" class="sref">dev_dbg /a>( a href="+code=mci" class="sref">mci /a>-> a href="+code=pdev" class="sref">pdev /a>,  spap class="string">"ECC CE err on node %d\n"priv /a>-> a href="+code=node" class="sref">node /a>);i  73 /a>                 a href="+code=priv" class="sref">priv /a>-> a href="+code=ce_count" class="sref">ce_count /a> =  a href="+code=mem_error" class="sref">mem_error /a>. a href="+code=sbe_count" class="sref">sbe_count /a>;i  74 /a>                 a href="+code=edac_mc_handle_error" class="sref">edac_mc_handle_error /a>( a href="+code=HW_EVENT_ERR_CORRECTED" class="sref">HW_EVENT_ERR_CORRECTED /a>,  a href="+code=mci" class="sref">mci /a>, 1,i  75 /a>                                     0, 0, 0,i  76 /a>                                     0, 0, -1,i  77 /a>                                      a href="+code=mci" class="sref">mci /a>-> a href="+code=ctl_namv" class="sref">ctl_namv /a>,  spap class="string">""  78 /a>        }i  79 /a>}i  80 /a>i  81 /a> spap class="comment">/* /spapti  82 /a> spap class="comment"> * Initialize the 'csrows' table within the mci control structure with the /spapti  83 /a> spap class="comment"> * addressing of memory. /spapti  84 /a> spap class="comment"> */ /spapti  85 /a>static int  a href="+code=tile_edac_init_csrows" class="sref">tile_edac_init_csrows /a>(struct  a href="+code=mem_ctl_info" class="sref">mem_ctl_info /a> * a href="+code=mci" class="sref">mci /a>)i  86 /a>{i  87 /a>        struct  a href="+code=csrow_info" class="sref">csrow_info /a>       * a href="+code=csrow" class="sref">csrow /a> =  a href="+code=mci" class="sref">mci /a>-> a href="+code=csrows" class="sref">csrows /a>[0];i  88 /a>        struct  a href="+code=tile_edac_priv" class="sref">tile_edac_priv /a>   * a href="+code=priv" class="sref">priv /a> =  a href="+code=mci" class="sref">mci /a>-> a href="+code=pvt_info" class="sref">pvt_info /a>;i  89 /a>        struct  a href="+code=mshim_mem_info" class="sref">mshim_mem_info /a>    a href="+code=mem_info" class="sref">mem_info /a>;i  90 /a>        struct  a href="+code=dimm_info" class="sref">dimm_info /a> * a href="+code=dimm" class="sref">dimm /a> =  a href="+code=csrow" class="sref">csrow /a>-> a href="+code=channels" class="sref">channels /a>[0]-> a href="+code=dimm" class="sref">dimm /a>;i  91 /a>i  92 /a>        if ( a href="+code=hv_dev_pread" class="sref">hv_dev_pread /a>( a href="+code=priv" class="sref">priv /a>-> a href="+code=hv_devhdl" class="sref">hv_devhdl /a>, 0, ( a href="+code=HV_VirtAddr" class="sref">HV_VirtAddr /a>)& a href="+code=mem_info" class="sref">mem_info /a>,i  93 /a>                sizeof(struct  a href="+code=mshim_mem_info" class="sref">mshim_mem_info /a>),  a href="+code=MSHIM_MEM_INFO_OFF" class="sref">MSHIM_MEM_INFO_OFF /a>) !=i  94 /a>                sizeof(struct  a href="+code=mshim_mem_info" class="sref">mshim_mem_info /a>)) {i  95 /a>                 a href="+code=pr_err" class="sref">pr_err /a>( a href="+code=DRV_NAME" class="sref">DRV_NAME /a>  spap class="string">": MSHIM_MEM_INFO_OFF pread failure.\n"  96 /a>                return -1;i  97 /a>        }i  98 /a>i  99 /a>        if ( a href="+code=mem_info" class="sref">mem_info /a>. a href="+code=mem_ecc" class="sref">mem_ecc /a>)i 100 /a>                 a href="+code=dimm" class="sref">dimm /a>-> a href="+code=edac_mode" class="sref">edac_mode /a> =  a href="+code=EDAC_SECDED" class="sref">EDAC_SECDED /a>;i 101 /a>        elsei 102 /a>                 a href="+code=dimm" class="sref">dimm /a>-> a href="+code=edac_mode" class="sref">edac_mode /a> =  a href="+code=EDAC_NONE" class="sref">EDAC_NONE /a>;i 103 /a>        switch ( a href="+code=mem_info" class="sref">mem_info /a>. a href="+code=mem_typv" class="sref">mem_typv /a>) {i 104 /a>        case  a href="+code=DDR2" class="sref">DDR2 /a>:i 105 /a>                 a href="+code=dimm" class="sref">dimm /a>-> a href="+code=mtypv" class="sref">mtypv /a> =  a href="+code=MEM_DDR2" class="sref">MEM_DDR2 /a>;i 106 /a>                break;i 107 /a>i 108 /a>        case  a href="+code=DDR3" class="sref">DDR3 /a>:i 109 /a>                 a href="+code=dimm" class="sref">dimm /a>-> a href="+code=mtypv" class="sref">mtypv /a> =  a href="+code=MEM_DDR3" class="sref">MEM_DDR3 /a>;i 110 /a>                break;i 111 /a>i 112 /a>        default:i 113 /a>                return -1;i 114 /a>        }i 115 /a>i 116 /a>         a href="+code=dimm" class="sref">dimm /a>-> a href="+code=nr_pages" class="sref">nr_pages /a> =  a href="+code=mem_info" class="sref">mem_info /a>. a href="+code=mem_size" class="sref">mem_size /a> >>  a href="+code=PAGE_SHIFT" class="sref">PAGE_SHIFT /a>;i 117 /a>         a href="+code=dimm" class="sref">dimm /a>-> a href="+code=grain" class="sref">grain /a> =  a href="+code=TILE_EDAC_ERROR_GRAIN" class="sref">TILE_EDAC_ERROR_GRAIN /a>;i 118 /a>         a href="+code=dimm" class="sref">dimm /a>-> a href="+code=dtypv" class="sref">dtypv /a> =  a href="+code=DEV_UNKNOWN" class="sref">DEV_UNKNOWN /a>;i 119 /a>i 120 /a>        return 0;i 121 /a>}i 122 /a>i 123 /a>static int  a href="+code=tile_edac_mc_probv" class="sref">tile_edac_mc_probv /a>(struct  a href="+code=platform_device" class="sref">platform_device /a> * a href="+code=pdev" class="sref">pdev /a>)i 124 /a>{i 125 /a>        char                     a href="+code=hv_file" class="sref">hv_file /a>[32];i 126 /a>        int                      a href="+code=hv_devhdl" class="sref">hv_devhdl /a>;i 127 /a>        struct  a href="+code=mem_ctl_info" class="sref">mem_ctl_info /a>     * a href="+code=mci" class="sref">mci /a>;i 128 /a>        struct  a href="+code=edac_mc_layer" class="sref">edac_mc_layer /a>     a href="+code=layers" class="sref">layers /a>[2];i 129 /a>        struct  a href="+code=tile_edac_priv" class="sref">tile_edac_priv /a>   * a href="+code=priv" class="sref">priv /a>;i 130 /a>        int                      a href="+code=rc" class="sref">rc /a>;i 131 /a>i 132 /a>         a href="+code=sprintf" class="sref">sprintf /a>( a href="+code=hv_file" class="sref">hv_file /a>,  spap class="string">"mshim/%d"pdev /a>-> a href="+code=id" class="sref">id /a>);i 133 /a>         a href="+code=hv_devhdl" class="sref">hv_devhdl /a> =  a href="+code=hv_dev_open" class="sref">hv_dev_open /a>(( a href="+code=HV_VirtAddr" class="sref">HV_VirtAddr /a>) a href="+code=hv_file" class="sref">hv_file /a>, 0);i 134 /a>        if ( a href="+code=hv_devhdl" class="sref">hv_devhdl /a> < 0)i 135 /a>                return - a href="+code=EINVAL" class="sref">EINVAL /a>;i 136 /a>i 137 /a>         spap class="comment">/* A TILE MC has a single channel and one chip-select row. */ /spapti 138 /a>         a href="+code=layers" class="sref">layers /a>[0]. a href="+code=typv" class="sref">typv /a> =  a href="+code=EDAC_MC_LAYER_CHIP_SELECT" class="sref">EDAC_MC_LAYER_CHIP_SELECT /a>;i 139 /a>         a href="+code=layers" class="sref">layers /a>[0]. a href="+code=size" class="sref">size /a> =  a href="+code=TILE_EDAC_NR_CSROWS" class="sref">TILE_EDAC_NR_CSROWS /a>;i 140 /a>         a href="+code=layers" class="sref">layers /a>[0]. a href="+code=is_virt_csrow" class="sref">is_virt_csrow /a> =  a href="+code=truv" class="sref">truv /a>;i 141 /a>         a href="+code=layers" class="sref">layers /a>[1]. a href="+code=typv" class="sref">typv /a> =  a href="+code=EDAC_MC_LAYER_CHANNEL" class="sref">E"+code=EDAC_MC_LAYER /a>;i 142 /a>         a href="+code=layers" class="sref">layers /a>[1]. a href="+code=size" class="sref">size /a> =  a href="+code=TILE_EDAC_NR_CHANS" class="sref">TILE_EDAC_NR_CHANS /a>;i 143 /a>         a href="+code=layers" class="sref">layers /a>[1]. a href="+code=is_virt_csrow" class="sref">is_virt_csrow /a> =  a href="+code=false" class="sref">false /a>;i 144 /a>         a href="+code=mci" class="sref">mci /a> =  a href="+code=edac_mc_alloc" class="sref">edac_mc_alloc /a>( a href="+code=pdev" class="sref">pdev /a>-> a href="+code=id" class="sref">id /a>,  a href="+code=ARRAY_SIZE" class="sref">ARRAY_SIZE /a>( a href="+code=layers" class="sref">layers /a>),  a href="+code=layers" class="sref">layers /a>,i 145 /a>                            sizeof(struct  a href="+code=tile_edac_priv" class="sref">tile_edac_priv /a>));i 146 /a>        if ( a href="+code=mci" class="sref">mci /a> ==  a href="+code=NULL" class="sref">NULL /a>)i 147 /a>                return - a href="+code=ENOMEM" class="sref">ENOMEM /a>;i 148 /a>         a href="+code=priv" class="sref">priv /a> =  a href="+code=mci" class="sref">mci /a>-> a href="+code=pvt_info" class="sref">pvt_info /a>;i 149 /a>         a href="+code=priv" class="sref">priv /a>-> a href="+code=node" class="sref">node /a> =  a href="+code=pdev" class="sref">pdev /a>-> a href="+code=id" class="sref">id /a>;i 150 /a>         a href="+code=priv" class="sref">priv /a>-> a href="+code=hv_devhdl" class="sref">hv_devhdl /a> =  a href="+code=hv_devhdl" class="sref">hv_devhdl /a>;i 151 /a>i 152 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=pdev" class="sref">pdev /a> = & a href="+code=pdev" class="sref">pdev /a>-> a href="+code=dev" class="sref">dev /a>;i 153 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=mtypv_cap" class="sref">mtypv_cap /a> =  a href="+code=MEM_FLAG_DDR2" class="sref">MEM_FLAG_DDR2 /a>;i 154 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=edac_ctl_cap" class="sref">edac_ctl_cap /a> =  a href="+code=EDAC_FLAG_SECDED" class="sref">EDAC_FLAG_SECDED /a>;i 155 /a>i 156 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=mod_namv" class="sref">mod_namv /a> =  a href="+code=DRV_NAME" class="sref">DRV_NAME /a>;i 157 /a>#ifdef  a href="+code=__tilegx__" class="sref">__tilegx__ /a>i 158 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=ctl_namv" class="sref">ctl_namv /a> =  spap class="string">"TILEGx_Memory_Controller" 159 /a>#elsei 160 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=ctl_namv" class="sref">ctl_namv /a> =  spap class="string">"TILEPro_Memory_Controller" 161 /a>#endifi 162 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=dev_namv" class="sref">dev_namv /a> =  a href="+code=dev_namv" class="sref">dev_namv /a>(& a href="+code=pdev" class="sref">pdev /a>-> a href="+code=dev" class="sref">dev /a>);i 163 /a>         a href="+code=mci" class="sref">mci /a>-> a href="+code=edac_check" class="sref">edac_check /a> =  a href="+code=tile_edac_check" class="sref">tile_edac_check /a>;i 164 /a>i 165 /a>         spap class="comment">/* /spapti 166 /a> spap class="comment">         * Initialize the MC control structure 'csrows' table /spapti 167 /a> spap class="comment">         * with the mapping and control informa 168 /a> spap class="comment">         */ /spapti 169 /a>        if ( a href="+code=tile_edac_init_csrows" class="sref">tile_edac_init_csrows /a>( a href="+code=mci" class="sref">mci /a>)) {i 170 /a>                 spap class="comment">/* No csrows found. */ /spapti 171 /a>                 a href="+code=mci" class="sref">mci /a>-> a href="+code=edac_cap" class="sref">edac_cap /a> =  a href="+code=EDAC_FLAG_NONE" class="sref">EDAC_FLAG_NONE /a>;i 172 /a>        } else {i 173 /a>                 a href="+code=mci" class="sref">mci /a>-> a href="+code=edac_cap" class="sref">edac_cap /a> =  a href="+code=EDAC_FLAG_SECDED" class="sref">EDAC_FLAG_SECDED /a>;i 174 /a>        }i 175 /a>i 176 /a>         a href="+code=platform_set_drvdata" class="sref">platform_set_drvdata /a>( a href="+code=pdev" class="sref">pdev /a>,  a href="+code=mci" class="sref">mci /a>);i 177 /a>i 178 /a>         spap class="comment">/* Register with EDAC core */ /spapti 179 /a>         a href="+code=rc" class="sref">rc /a> =  a href="+code=edac_mc_add_mc" class="sref">edac_mc_add_mc /a>( a href="+code=mci" class="sref">mci /a>);i 180 /a>        if ( a href="+code=rc" class="sref">rc /a>) {i 181 /a>                 a href="+code=dev_err" class="sref">dev_err /a>(& a href="+code=pdev" class="sref">pdev /a>-> a href="+code=dev" class="sref">dev /a>,  spap class="string">"failed to register with EDAC core\n" 182 /a>                 a href="+code=edac_mc_free" class="sref">edac_mc_free /a>( a href="+code=mci" class="sref">mci /a>);i 183 /a>                return  a href="+code=rc" class="sref">rc /a>;i 184 /a>        }i 185 /a>i 186 /a>        return 0;i 187 /a>}i 188 /a>i 189 /a>static int  a href="+code=tile_edac_mc_removv" class="sref">tile_edac_mc_removv /a>(struct  a href="+code=platform_device" class="sref">platform_device /a> * a href="+code=pdev" class="sref">pdev /a>)i 190 /a>{i 191 /a>        struct  a href="+code=mem_ctl_info" class="sref">mem_ctl_info /a> * a href="+code=mci" class="sref">mci /a> =  a href="+code=platform_get_drvdata" class="sref">platform_get_drvdata /a>( a href="+code=pdev" class="sref">pdev /a>);i 192 /a>i 193 /a>         a href="+code=edac_mc_del_mc" class="sref">edac_mc_del_mc /a>(& a href="+code=pdev" class="sref">pdev /a>-> a href="+code=dev" class="sref">dev /a>);i 194 /a>        if ( a href="+code=mci" class="sref">mci /a>)i 195 /a>                 a href="+code=edac_mc_free" class="sref">edac_mc_free /a>( a href="+code=mci" class="sref">mci /a>);i 196 /a>        return 0;i 197 /a>}i 198 /a>i 199 /a>static struct  a href="+code=platform_driver" class="sref">platform_driver /a>  a href="+code=tile_edac_mc_driver" class="sref">tile_edac_mc_driver /a> = {i 200 /a>        . a href="+code=driver" class="sref">driver /a>         = {i 201 /a>                . a href="+code=namv" class="sref">namv /a>   =  a href="+code=DRV_NAME" class="sref">DRV_NAME /a>,i 202 /a>                . a href="+code=owner" class="sref">owner /a>  =  a href="+code=THIS_MODULE" class="sref">THIS_MODULE /a>,i 203 /a>        },i 204 /a>        . a href="+code=probv" class="sref">probv /a>          =  a href="+code=tile_edac_mc_probv" class="sref">tile_edac_mc_probv /a>,i 205 /a>        . a href="+code=removv" class="sref">removv /a>         =  a href="+code=tile_edac_mc_removv" class="sref">tile_edac_mc_removv /a>,i 206 /a>};i 207 /a>i 208 /a> spap class="comment">/* /spapti 209 /a> spap class="comment"> * Driver init routine. /spapti 2118.a> spap class="comment"> */ /spapti 211 /a>static int  a href="+code=__init" class="sref">__init /a>  a href="+code=tile_edac_init" class="sref">tile_edac_init /a>(void)i 212 /a>{i 213 /a>        char     a href="+code=hv_file" class="sref">hv_file /a>[32];i 214 /a>        struct  a href="+code=platform_device" class="sref">platform_device /a> * a href="+code=pdev" class="sref">pdev /a>;i 215 /a>        int  a href="+code=i" class="sref">i /a>,  a href="+code=err" class="sref">err /a>,  a href="+code=num" class="sref">num /a> = 0;i 216 /a>i 217 /a>         spap class="comment">/* Only support POLL mode. */ /spapti 218 /a>         a href="+code=edac_op_state" class="sref">edac_op_state /a> =  a href="+code=EDAC_OPSTATE_POLL" class="sref">EDAC_OPSTATE_POLL /a>;i 219 /a>i 220 /a>         a href="+code=err" class="sref">err /a> =  a href="+code=platform_driver_register" class="sref">platform_driver_register /a>(& a href="+code=tile_edac_mc_driver" class="sref">tile_edac_mc_driver /a>);i 221 /a>        if ( a href="+code=err" class="sref">err /a>)i 222 /a>                return  a href="+code=err" class="sref">err /a>;i 223 /a>i 224 /a>        for ( a href="+code=i" class="sref">i /a> = 0;  a href="+code=i" class="sref">i /a> <  a href="+code=TILE_MAX_MSHIMS" class="sref">TILE_MAX_MSHIMS /a>;  a href="+code=i" class="sref">i /a>++) {i 225 /a>                 spap class="comment">/* /spapti 226 /a> spap class="comment">                 * Not all memory controllers are configured such as in the /spapti 227 /a> spap class="comment">                 * case of a simulator. So we register only those mshims /spapti 228 /a> spap class="comment">                 * that are configured by the hypervisor. /spapti 229 /a> spap class="comment">                 */ /spapti 230 /a>                 a href="+code=sprintf" class="sref">sprintf /a>( a href="+code=hv_file" class="sref">hv_file /a>,  spap class="string">"mshim/%d"i /a>);i 231 /a>                if ( a href="+code=hv_dev_open" class="sref">hv_dev_open /a>(( a href="+code=HV_VirtAddr" class="sref">HV_VirtAddr /a>) a href="+code=hv_file" class="sref">hv_file /a>, 0) < 0)i 232 /a>                        continue;i 233 /a>i 234 /a>                 a href="+code=pdev" class="sref">pdev /a> =  a href="+code=platform_device_register_simple" class="sref">platform_device_register_simple /a>( a href="+code=DRV_NAME" class="sref">DRV_NAME /a>,  a href="+code=i" class="sref">i /a>,  a href="+code=NULL" class="sref">NULL /a>, 0);i 235 /a>                if ( a href="+code=IS_ERR" class="sref">IS_ERR /a>( a href="+code=pdev" class="sref">pdev /a>))i 236 /a>                        continue;i 237 /a>                 a href="+code=mshim_pdev" class="sref">mshim_pdev /a>[ a href="+code=i" class="sref">i /a>] =  a href="+code=pdev" class="sref">pdev /a>;i 238 /a>                 a href="+code=num" class="sref">num /a>++;i 239 /a>        }i 240 /a>i 241 /a>        if ( a href="+code=num" class="sref">num /a> == 0) {i 242 /a>                 a href="+code=platform_driver_unregister" class="sref">platform_driver_unregister /a>(& a href="+code=tile_edac_mc_driver" class="sref">tile_edac_mc_driver /a>);i 243 /a>                return - a href="+code=ENODEV" class="sref">ENODEV /a>;i 244 /a>        }i 245 /a>        return 0;i 246 /a>}i 247 /a>i 248 /a> spap class="comment">/* /spapti 249 /a> spap class="comment"> * Driver cleanup routine. /spapti 2518.a> spap class="comment"> */ /spapti 251 /a>static void  a href="+code=__exit" class="sref">__exit /a>  a href="+code=tile_edac_exit" class="sref">tile_edac_exit /a>(void)i 252 /a>{i 253 /a>        int  a href="+code=i" class="sref">i /a>;i 254 /a>i 255 /a>        for ( a href="+code=i" class="sref">i /a> = 0;  a href="+code=i" class="sref">i /a> <  a href="+code=TILE_MAX_MSHIMS" class="sref">TILE_MAX_MSHIMS /a>;  a href="+code=i" class="sref">i /a>++) {i 256 /a>                struct  a href="+code=platform_device" class="sref">platform_device /a> * a href="+code=pdev" class="sref">pdev /a> =  a href="+code=mshim_pdev" class="sref">mshim_pdev /a>[ a href="+code=i" class="sref">i /a>];i 257 /a>                if (! a href="+code=pdev" class="sref">pdev /a>)i 258 /a>                        continue;i 259 /a>i 260 /a>                 a href="+code=platform_set_drvdata" class="sref">platform_set_drvdata /a>( a href="+code=pdev" class="sref">pdev /a>,  a href="+code=NULL" class="sref">NULL /a>);i 261 /a>                 a href="+code=platform_device_unregister" class="sref">platform_device_unregister /a>( a href="+code=pdev" class="sref">pdev /a>);i 262 /a>        }i 263 /a>         a href="+code=platform_driver_unregister" class="sref">platform_driver_unregister /a>(& a href="+code=tile_edac_mc_driver" class="sref">tile_edac_mc_driver /a>);i 264 /a>}i 265 /a>i 266 /a> a href="+code=module_init" class="sref">module_init /a>( a href="+code=tile_edac_init" class="sref">tile_edac_init /a>);i 267 /a> a href="+code=module_exit" class="sref">module_exit /a>( a href="+code=tile_edac_exit" class="sref">tile_edac_exit /a>);i 268 /a> /pre> /div>


 /div>