/drivers/auxdisplay/

x/kernel-qcow2-linux.git
In-kernel qcow2 (Kernel part)OpenSLX
summaryrefslogblamecommitdiffstats
path: root/drivers/edac/mv64x60_edac.c
blob: 3c68bb525d5da3aa9c41c512e14fde1acf7cf0cd (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14













                                                                        


                            
                      
 














                                                                           
                                                                  





                                                                        
                                                                    
                                                 
                                                                    
                                              
                                                                 
                                            

                                                                   













                                                         
                                                                







                                


















                                                                            
                                                       


                               
                                                 




                          
                                                              















                                                                              
                                        

                                        
                                             

















                                                                 
                                                      








                                                                          
                                                          





                                                                                





                                                                    



                                                              

                                                            
                                                              







                                                       
                                         














                                                                               
                                 














                                                                   
                          









                                                        
                                         












                                                                            
                                                                  





                                                           
                                                                    
                                                 
                                                                    
                                             
                                                                    
                                              
                                                                    
                                           

                                                                   









                                                                  
                                                                  







                                     
                                                               


















                                                                               

                                             
                                                  










                                                                 
                                                      








                                                                       
                                                           







                                                                      
                                                              









                                                          
                                                                 







                                                        
                                         
















                                                                                
                                 














                                                                           
                          




















                                                                           
                                                                    






                                                           
                                                                     
                                                 
                                                                     
                                             
                                                                     
                                              
                                                                     
                                           

                                                                    









                                                                  
                                                                    








                                    
                                                              


















                                                                              

                                             
                                                  










                                                                 
                                                      








                                                                          
                                                             















                                                                                
                                                      








                                                                          
                                                             






                                                                                


                                                                       








                                                         
                                                                 







                                                       
                                         
















                                                                          
                                 














                                                                           
                          
























                                                                            
                                                              



                              

                                                                        



                                                                            
                                                                    


                                                                    
                                                        
                                     
                                                                      


                                                             
                                                        

                             
                                                            







                                                        
                                                              

















                                                                          
                                               







                                                               

                               




                             
                                                            
 

                                        

                                                        
                        
 
                                                                            



                                    
                                      

                                                                         
                                      

                      
                                     

                      
                                          


                      
                                      

 
                                                             

                                 
                                       







                                                                             





                                                   
                                                                    
                                                             






                                                                         
                               

                                        
                                             











                                                                 
                                                      








                                                                          
                                                         





                                                                               
                                                            



                                                                               
                         

         
                                  



                                                              











                                                   

                                                                  
                                           
                                                                  
 

                                  
                                                         








                                                           
                                         













                                                                              
                                 














                                                               
                          













                                                       








                                                   

                                         


                                                                               
 









                                                      
                                                                       




                                          
                                                                  







                                                                    
/*
 * Marvell MV64x60 Memory Controller kernel module for PPC platforms
 *
 * Author: Dave Jiang <djiang@mvista.com>
 *
 * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/edac.h>
#include <linux/gfp.h>

#include "edac_module.h"
#include "mv64x60_edac.h"

static const char *mv64x60_ctl_name = "MV64x60";
static int edac_dev_idx;
static int edac_pci_idx;
static int edac_mc_idx;

/*********************** PCI err device **********************************/
#ifdef CONFIG_PCI
static void mv64x60_pci_check(struct edac_pci_ctl_info *pci)
{
	struct mv64x60_pci_pdata *pdata = pci->pvt_info;
	u32 cause;

	cause = readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
	if (!cause)
		return;

	printk(KERN_ERR "Error in PCI %d Interface\n", pdata->pci_hose);
	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
	printk(KERN_ERR "Address Low: 0x%08x\n",
	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_LO));
	printk(KERN_ERR "Address High: 0x%08x\n",
	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_HI));
	printk(KERN_ERR "Attribute: 0x%08x\n",
	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ATTR));
	printk(KERN_ERR "Command: 0x%08x\n",
	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CMD));
	writel(~cause, pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);

	if (cause & MV64X60_PCI_PE_MASK)
		edac_pci_handle_pe(pci, pci->ctl_name);

	if (!(cause & MV64X60_PCI_PE_MASK))
		edac_pci_handle_npe(pci, pci->ctl_name);
}

static irqreturn_t mv64x60_pci_isr(int irq, void *dev_id)
{
	struct edac_pci_ctl_info *pci = dev_id;
	struct mv64x60_pci_pdata *pdata = pci->pvt_info;
	u32 val;

	val = readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
	if (!val)
		return IRQ_NONE;

	mv64x60_pci_check(pci);

	return IRQ_HANDLED;
}

/*
 * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of
 * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as
 * well.  IOW, don't set bit 0.
 */

/* Erratum FEr PCI-#16: clear bit 0 of PCI SERRn Mask reg. */
static int __init mv64x60_pci_fixup(struct platform_device *pdev)
{
	struct resource *r;
	void __iomem *pci_serr;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!r) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "PCI err regs\n", __func__);
		return -ENOENT;
	}

	pci_serr = ioremap(r->start, resource_size(r));
	if (!pci_serr)
		return -ENOMEM;

	writel(readl(pci_serr) & ~0x1, pci_serr);
	iounmap(pci_serr);

	return 0;
}

static int mv64x60_pci_err_probe(struct platform_device *pdev)
{
	struct edac_pci_ctl_info *pci;
	struct mv64x60_pci_pdata *pdata;
	struct resource *r;
	int res = 0;

	if (!devres_open_group(&pdev->dev, mv64x60_pci_err_probe, GFP_KERNEL))
		return -ENOMEM;

	pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mv64x60_pci_err");
	if (!pci)
		return -ENOMEM;

	pdata = pci->pvt_info;

	pdata->pci_hose = pdev->id;
	pdata->name = "mv64x60_pci_err";
	platform_set_drvdata(pdev, pci);
	pci->dev = &pdev->dev;
	pci->dev_name = dev_name(&pdev->dev);
	pci->mod_name = EDAC_MOD_STR;
	pci->ctl_name = pdata->name;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		pci->edac_check = mv64x60_pci_check;

	pdata->edac_idx = edac_pci_idx++;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "PCI err regs\n", __func__);
		res = -ENOENT;
		goto err;
	}

	if (!devm_request_mem_region(&pdev->dev,
				     r->start,
				     resource_size(r),
				     pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->pci_vbase = devm_ioremap(&pdev->dev,
					r->start,
					resource_size(r));
	if (!pdata->pci_vbase) {
		printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	res = mv64x60_pci_fixup(pdev);
	if (res < 0) {
		printk(KERN_ERR "%s: PCI fixup failed\n", __func__);
		goto err;
	}

	writel(0, pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
	writel(0, pdata->pci_vbase + MV64X60_PCI_ERROR_MASK);
	writel(MV64X60_PCIx_ERR_MASK_VAL,
		  pdata->pci_vbase + MV64X60_PCI_ERROR_MASK);

	if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
		edac_dbg(3, "failed edac_pci_add_device()\n");
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		pdata->irq = platform_get_irq(pdev, 0);
		res = devm_request_irq(&pdev->dev,
				       pdata->irq,
				       mv64x60_pci_isr,
				       0,
				       "[EDAC] PCI err",
				       pci);
		if (res < 0) {
			printk(KERN_ERR "%s: Unable to request irq %d for "
			       "MV64x60 PCI ERR\n", __func__, pdata->irq);
			res = -ENODEV;
			goto err2;
		}
		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n",
		       pdata->irq);
	}

	devres_remove_group(&pdev->dev, mv64x60_pci_err_probe);

	/* get this far and it's successful */
	edac_dbg(3, "success\n");

	return 0;

err2:
	edac_pci_del_device(&pdev->dev);
err:
	edac_pci_free_ctl_info(pci);
	devres_release_group(&pdev->dev, mv64x60_pci_err_probe);
	return res;
}

static int mv64x60_pci_err_remove(struct platform_device *pdev)
{
	struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev);

	edac_dbg(0, "\n");

	edac_pci_del_device(&pdev->dev);

	edac_pci_free_ctl_info(pci);

	return 0;
}

static struct platform_driver mv64x60_pci_err_driver = {
	.probe = mv64x60_pci_err_probe,
	.remove = mv64x60_pci_err_remove,
	.driver = {
		   .name = "mv64x60_pci_err",
	}
};

#endif /* CONFIG_PCI */

/*********************** SRAM err device **********************************/
static void mv64x60_sram_check(struct edac_device_ctl_info *edac_dev)
{
	struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info;
	u32 cause;