Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'edac_for_3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

Pull EDAC updates from Borislav Petkov:
"Following up on last week's discussion, here's my part of the EDAC
pile, highlights in the signed tag.

The last two patches have a date from just now because I've just
applied them to the tree after Johannes sent them to me earlier. I
decided to forward them now because they're trivial.

There's a third one for MPC85xx which adds PCIe error interrupt
support but since it is not so trivial and hasn't seen any linux-next
time, I'm deferring it to 3.14

EDAC update highlights:
- Support for Calxeda ECX-2000 memory controller, from Robert Richter
- Misc Calxeda Highbank drivers and EDAC core cleanups, from Rob
Herring and Robert Richter
- New maintainer for Freescale's MPC85xx EDAC driver: Johannes
Thumshirn"

* tag 'edac_for_3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
edac/85xx: Remove mpc85xx_pci_err_remove
EDAC: Add edac-mpc85xx driver to MAINTAINERS
edac, highbank: Moving error injection to sysfs for edac
edac, highbank: Add MAINTAINERS entry
edac: Unify reporting of device info for device, mc and pci
edac, highbank: Improve and unify naming
edac, highbank: Add Calxeda ECX-2000 support
ARM: dts: calxeda: move memory-controller node out of ecx-common.dtsi
edac, highbank: Fix interrupt setup of mem and l2 controller

+158 -132
+3 -1
Documentation/devicetree/bindings/arm/calxeda/mem-ctrlr.txt
··· 1 1 Calxeda DDR memory controller 2 2 3 3 Properties: 4 - - compatible : Should be "calxeda,hb-ddr-ctrl" 4 + - compatible : Should be: 5 + - "calxeda,hb-ddr-ctrl" for ECX-1000 6 + - "calxeda,ecx-2000-ddr-ctrl" for ECX-2000 5 7 - reg : Address and size for DDR controller registers. 6 8 - interrupts : Interrupt for DDR controller. 7 9
+15
MAINTAINERS
··· 3063 3063 S: Maintained 3064 3064 F: drivers/edac/amd64_edac* 3065 3065 3066 + EDAC-CALXEDA 3067 + M: Doug Thompson <dougthompson@xmission.com> 3068 + M: Robert Richter <rric@kernel.org> 3069 + L: linux-edac@vger.kernel.org 3070 + W: bluesmoke.sourceforge.net 3071 + S: Maintained 3072 + F: drivers/edac/highbank* 3073 + 3066 3074 EDAC-CAVIUM 3067 3075 M: Ralf Baechle <ralf@linux-mips.org> 3068 3076 M: David Daney <david.daney@cavium.com> ··· 3151 3143 W: bluesmoke.sourceforge.net 3152 3144 S: Maintained 3153 3145 F: drivers/edac/i82975x_edac.c 3146 + 3147 + EDAC-MPC85XX 3148 + M: Johannes Thumshirn <johannes.thumshirn@men.de> 3149 + L: linux-edac@vger.kernel.org 3150 + W: bluesmoke.sourceforge.net 3151 + S: Maintained 3152 + F: drivers/edac/mpc85xx_edac.[ch] 3154 3153 3155 3154 EDAC-PASEMI 3156 3155 M: Egor Martovetsky <egor@pasemi.com>
+6
arch/arm/boot/dts/ecx-2000.dts
··· 85 85 <1 10 0xf08>; 86 86 }; 87 87 88 + memory-controller@fff00000 { 89 + compatible = "calxeda,ecx-2000-ddr-ctrl"; 90 + reg = <0xfff00000 0x1000>; 91 + interrupts = <0 91 4>; 92 + }; 93 + 88 94 intc: interrupt-controller@fff11000 { 89 95 compatible = "arm,cortex-a15-gic"; 90 96 #interrupt-cells = <3>;
-6
arch/arm/boot/dts/ecx-common.dtsi
··· 53 53 status = "disabled"; 54 54 }; 55 55 56 - memory-controller@fff00000 { 57 - compatible = "calxeda,hb-ddr-ctrl"; 58 - reg = <0xfff00000 0x1000>; 59 - interrupts = <0 91 4>; 60 - }; 61 - 62 56 ipc@fff20000 { 63 57 compatible = "arm,pl320", "arm,primecell"; 64 58 reg = <0xfff20000 0x1000>;
+6
arch/arm/boot/dts/highbank.dts
··· 86 86 soc { 87 87 ranges = <0x00000000 0x00000000 0xffffffff>; 88 88 89 + memory-controller@fff00000 { 90 + compatible = "calxeda,hb-ddr-ctrl"; 91 + reg = <0xfff00000 0x1000>; 92 + interrupts = <0 91 4>; 93 + }; 94 + 89 95 timer@fff10600 { 90 96 compatible = "arm,cortex-a9-twd-timer"; 91 97 reg = <0xfff10600 0x20>;
+3 -6
drivers/edac/edac_device.c
··· 530 530 531 531 /* Report action taken */ 532 532 edac_device_printk(edac_dev, KERN_INFO, 533 - "Giving out device to module '%s' controller " 534 - "'%s': DEV '%s' (%s)\n", 535 - edac_dev->mod_name, 536 - edac_dev->ctl_name, 537 - edac_dev_name(edac_dev), 538 - edac_op_state_to_string(edac_dev->op_state)); 533 + "Giving out device to module %s controller %s: DEV %s (%s)\n", 534 + edac_dev->mod_name, edac_dev->ctl_name, edac_dev->dev_name, 535 + edac_op_state_to_string(edac_dev->op_state)); 539 536 540 537 mutex_unlock(&device_ctls_mutex); 541 538 return 0;
+4 -2
drivers/edac/edac_mc.c
··· 788 788 } 789 789 790 790 /* Report action taken */ 791 - edac_mc_printk(mci, KERN_INFO, "Giving out device to '%s' '%s':" 792 - " DEV %s\n", mci->mod_name, mci->ctl_name, edac_dev_name(mci)); 791 + edac_mc_printk(mci, KERN_INFO, 792 + "Giving out device to module %s controller %s: DEV %s (%s)\n", 793 + mci->mod_name, mci->ctl_name, mci->dev_name, 794 + edac_op_state_to_string(mci->op_state)); 793 795 794 796 edac_mc_owner = mci->mod_name; 795 797
+3 -5
drivers/edac/edac_pci.c
··· 358 358 } 359 359 360 360 edac_pci_printk(pci, KERN_INFO, 361 - "Giving out device to module '%s' controller '%s':" 362 - " DEV '%s' (%s)\n", 363 - pci->mod_name, 364 - pci->ctl_name, 365 - edac_dev_name(pci), edac_op_state_to_string(pci->op_state)); 361 + "Giving out device to module %s controller %s: DEV %s (%s)\n", 362 + pci->mod_name, pci->ctl_name, pci->dev_name, 363 + edac_op_state_to_string(pci->op_state)); 366 364 367 365 mutex_unlock(&edac_pci_ctls_mutex); 368 366 return 0;
+19 -14
drivers/edac/highbank_l2_edac.c
··· 50 50 return IRQ_HANDLED; 51 51 } 52 52 53 + static const struct of_device_id hb_l2_err_of_match[] = { 54 + { .compatible = "calxeda,hb-sregs-l2-ecc", }, 55 + {}, 56 + }; 57 + MODULE_DEVICE_TABLE(of, hb_l2_err_of_match); 58 + 53 59 static int highbank_l2_err_probe(struct platform_device *pdev) 54 60 { 61 + const struct of_device_id *id; 55 62 struct edac_device_ctl_info *dci; 56 63 struct hb_l2_drvdata *drvdata; 57 64 struct resource *r; ··· 97 90 goto err; 98 91 } 99 92 93 + id = of_match_device(hb_l2_err_of_match, &pdev->dev); 94 + dci->mod_name = pdev->dev.driver->name; 95 + dci->ctl_name = id ? id->compatible : "unknown"; 96 + dci->dev_name = dev_name(&pdev->dev); 97 + 98 + if (edac_device_add_device(dci)) 99 + goto err; 100 + 100 101 drvdata->db_irq = platform_get_irq(pdev, 0); 101 102 res = devm_request_irq(&pdev->dev, drvdata->db_irq, 102 103 highbank_l2_err_handler, 103 104 0, dev_name(&pdev->dev), dci); 104 105 if (res < 0) 105 - goto err; 106 + goto err2; 106 107 107 108 drvdata->sb_irq = platform_get_irq(pdev, 1); 108 109 res = devm_request_irq(&pdev->dev, drvdata->sb_irq, 109 110 highbank_l2_err_handler, 110 111 0, dev_name(&pdev->dev), dci); 111 112 if (res < 0) 112 - goto err; 113 - 114 - dci->mod_name = dev_name(&pdev->dev); 115 - dci->dev_name = dev_name(&pdev->dev); 116 - 117 - if (edac_device_add_device(dci)) 118 - goto err; 113 + goto err2; 119 114 120 115 devres_close_group(&pdev->dev, NULL); 121 116 return 0; 117 + err2: 118 + edac_device_del_device(&pdev->dev); 122 119 err: 123 120 devres_release_group(&pdev->dev, NULL); 124 121 edac_device_free_ctl_info(dci); ··· 137 126 edac_device_free_ctl_info(dci); 138 127 return 0; 139 128 } 140 - 141 - static const struct of_device_id hb_l2_err_of_match[] = { 142 - { .compatible = "calxeda,hb-sregs-l2-ecc", }, 143 - {}, 144 - }; 145 - MODULE_DEVICE_TABLE(of, hb_l2_err_of_match); 146 129 147 130 static struct platform_driver highbank_l2_edac_driver = { 148 131 .probe = highbank_l2_err_probe,
+99 -76
drivers/edac/highbank_mc_edac.c
··· 26 26 #include "edac_module.h" 27 27 28 28 /* DDR Ctrlr Error Registers */ 29 - #define HB_DDR_ECC_OPT 0x128 30 - #define HB_DDR_ECC_U_ERR_ADDR 0x130 31 - #define HB_DDR_ECC_U_ERR_STAT 0x134 32 - #define HB_DDR_ECC_U_ERR_DATAL 0x138 33 - #define HB_DDR_ECC_U_ERR_DATAH 0x13c 34 - #define HB_DDR_ECC_C_ERR_ADDR 0x140 35 - #define HB_DDR_ECC_C_ERR_STAT 0x144 36 - #define HB_DDR_ECC_C_ERR_DATAL 0x148 37 - #define HB_DDR_ECC_C_ERR_DATAH 0x14c 38 - #define HB_DDR_ECC_INT_STATUS 0x180 39 - #define HB_DDR_ECC_INT_ACK 0x184 40 - #define HB_DDR_ECC_U_ERR_ID 0x424 41 - #define HB_DDR_ECC_C_ERR_ID 0x428 29 + 30 + #define HB_DDR_ECC_ERR_BASE 0x128 31 + #define MW_DDR_ECC_ERR_BASE 0x1b4 32 + 33 + #define HB_DDR_ECC_OPT 0x00 34 + #define HB_DDR_ECC_U_ERR_ADDR 0x08 35 + #define HB_DDR_ECC_U_ERR_STAT 0x0c 36 + #define HB_DDR_ECC_U_ERR_DATAL 0x10 37 + #define HB_DDR_ECC_U_ERR_DATAH 0x14 38 + #define HB_DDR_ECC_C_ERR_ADDR 0x18 39 + #define HB_DDR_ECC_C_ERR_STAT 0x1c 40 + #define HB_DDR_ECC_C_ERR_DATAL 0x20 41 + #define HB_DDR_ECC_C_ERR_DATAH 0x24 42 + 43 + #define HB_DDR_ECC_OPT_MODE_MASK 0x3 44 + #define HB_DDR_ECC_OPT_FWC 0x100 45 + #define HB_DDR_ECC_OPT_XOR_SHIFT 16 46 + 47 + /* DDR Ctrlr Interrupt Registers */ 48 + 49 + #define HB_DDR_ECC_INT_BASE 0x180 50 + #define MW_DDR_ECC_INT_BASE 0x218 51 + 52 + #define HB_DDR_ECC_INT_STATUS 0x00 53 + #define HB_DDR_ECC_INT_ACK 0x04 42 54 43 55 #define HB_DDR_ECC_INT_STAT_CE 0x8 44 56 #define HB_DDR_ECC_INT_STAT_DOUBLE_CE 0x10 45 57 #define HB_DDR_ECC_INT_STAT_UE 0x20 46 58 #define HB_DDR_ECC_INT_STAT_DOUBLE_UE 0x40 47 59 48 - #define HB_DDR_ECC_OPT_MODE_MASK 0x3 49 - #define HB_DDR_ECC_OPT_FWC 0x100 50 - #define HB_DDR_ECC_OPT_XOR_SHIFT 16 51 - 52 60 struct hb_mc_drvdata { 53 - void __iomem *mc_vbase; 61 + void __iomem *mc_err_base; 62 + void __iomem *mc_int_base; 54 63 }; 55 64 56 65 static irqreturn_t highbank_mc_err_handler(int irq, void *dev_id) ··· 69 60 u32 status, err_addr; 70 61 71 62 /* Read the interrupt status register */ 72 - status = readl(drvdata->mc_vbase + HB_DDR_ECC_INT_STATUS); 63 + status = readl(drvdata->mc_int_base + HB_DDR_ECC_INT_STATUS); 73 64 74 65 if (status & HB_DDR_ECC_INT_STAT_UE) { 75 - err_addr = readl(drvdata->mc_vbase + HB_DDR_ECC_U_ERR_ADDR); 66 + err_addr = readl(drvdata->mc_err_base + HB_DDR_ECC_U_ERR_ADDR); 76 67 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 77 68 err_addr >> PAGE_SHIFT, 78 69 err_addr & ~PAGE_MASK, 0, ··· 80 71 mci->ctl_name, ""); 81 72 } 82 73 if (status & HB_DDR_ECC_INT_STAT_CE) { 83 - u32 syndrome = readl(drvdata->mc_vbase + HB_DDR_ECC_C_ERR_STAT); 74 + u32 syndrome = readl(drvdata->mc_err_base + HB_DDR_ECC_C_ERR_STAT); 84 75 syndrome = (syndrome >> 8) & 0xff; 85 - err_addr = readl(drvdata->mc_vbase + HB_DDR_ECC_C_ERR_ADDR); 76 + err_addr = readl(drvdata->mc_err_base + HB_DDR_ECC_C_ERR_ADDR); 86 77 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 87 78 err_addr >> PAGE_SHIFT, 88 79 err_addr & ~PAGE_MASK, syndrome, ··· 91 82 } 92 83 93 84 /* clear the error, clears the interrupt */ 94 - writel(status, drvdata->mc_vbase + HB_DDR_ECC_INT_ACK); 85 + writel(status, drvdata->mc_int_base + HB_DDR_ECC_INT_ACK); 95 86 return IRQ_HANDLED; 96 87 } 97 88 98 - #ifdef CONFIG_EDAC_DEBUG 99 - static ssize_t highbank_mc_err_inject_write(struct file *file, 100 - const char __user *data, 101 - size_t count, loff_t *ppos) 89 + static void highbank_mc_err_inject(struct mem_ctl_info *mci, u8 synd) 102 90 { 103 - struct mem_ctl_info *mci = file->private_data; 104 91 struct hb_mc_drvdata *pdata = mci->pvt_info; 105 - char buf[32]; 106 - size_t buf_size; 107 92 u32 reg; 93 + 94 + reg = readl(pdata->mc_err_base + HB_DDR_ECC_OPT); 95 + reg &= HB_DDR_ECC_OPT_MODE_MASK; 96 + reg |= (synd << HB_DDR_ECC_OPT_XOR_SHIFT) | HB_DDR_ECC_OPT_FWC; 97 + writel(reg, pdata->mc_err_base + HB_DDR_ECC_OPT); 98 + } 99 + 100 + #define to_mci(k) container_of(k, struct mem_ctl_info, dev) 101 + 102 + static ssize_t highbank_mc_inject_ctrl(struct device *dev, 103 + struct device_attribute *attr, const char *buf, size_t count) 104 + { 105 + struct mem_ctl_info *mci = to_mci(dev); 108 106 u8 synd; 109 107 110 - buf_size = min(count, (sizeof(buf)-1)); 111 - if (copy_from_user(buf, data, buf_size)) 112 - return -EFAULT; 113 - buf[buf_size] = 0; 108 + if (kstrtou8(buf, 16, &synd)) 109 + return -EINVAL; 114 110 115 - if (!kstrtou8(buf, 16, &synd)) { 116 - reg = readl(pdata->mc_vbase + HB_DDR_ECC_OPT); 117 - reg &= HB_DDR_ECC_OPT_MODE_MASK; 118 - reg |= (synd << HB_DDR_ECC_OPT_XOR_SHIFT) | HB_DDR_ECC_OPT_FWC; 119 - writel(reg, pdata->mc_vbase + HB_DDR_ECC_OPT); 120 - } 111 + highbank_mc_err_inject(mci, synd); 121 112 122 113 return count; 123 114 } 124 115 125 - static const struct file_operations highbank_mc_debug_inject_fops = { 126 - .open = simple_open, 127 - .write = highbank_mc_err_inject_write, 128 - .llseek = generic_file_llseek, 116 + static DEVICE_ATTR(inject_ctrl, S_IWUSR, NULL, highbank_mc_inject_ctrl); 117 + 118 + struct hb_mc_settings { 119 + int err_offset; 120 + int int_offset; 129 121 }; 130 122 131 - static void highbank_mc_create_debugfs_nodes(struct mem_ctl_info *mci) 132 - { 133 - if (mci->debugfs) 134 - debugfs_create_file("inject_ctrl", S_IWUSR, mci->debugfs, mci, 135 - &highbank_mc_debug_inject_fops); 136 - ; 137 - } 138 - #else 139 - static void highbank_mc_create_debugfs_nodes(struct mem_ctl_info *mci) 140 - {} 141 - #endif 123 + static struct hb_mc_settings hb_settings = { 124 + .err_offset = HB_DDR_ECC_ERR_BASE, 125 + .int_offset = HB_DDR_ECC_INT_BASE, 126 + }; 127 + 128 + static struct hb_mc_settings mw_settings = { 129 + .err_offset = MW_DDR_ECC_ERR_BASE, 130 + .int_offset = MW_DDR_ECC_INT_BASE, 131 + }; 132 + 133 + static struct of_device_id hb_ddr_ctrl_of_match[] = { 134 + { .compatible = "calxeda,hb-ddr-ctrl", .data = &hb_settings }, 135 + { .compatible = "calxeda,ecx-2000-ddr-ctrl", .data = &mw_settings }, 136 + {}, 137 + }; 138 + MODULE_DEVICE_TABLE(of, hb_ddr_ctrl_of_match); 142 139 143 140 static int highbank_mc_probe(struct platform_device *pdev) 144 141 { 142 + const struct of_device_id *id; 143 + const struct hb_mc_settings *settings; 145 144 struct edac_mc_layer layers[2]; 146 145 struct mem_ctl_info *mci; 147 146 struct hb_mc_drvdata *drvdata; 148 147 struct dimm_info *dimm; 149 148 struct resource *r; 149 + void __iomem *base; 150 150 u32 control; 151 151 int irq; 152 152 int res = 0; 153 + 154 + id = of_match_device(hb_ddr_ctrl_of_match, &pdev->dev); 155 + if (!id) 156 + return -ENODEV; 153 157 154 158 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; 155 159 layers[0].size = 1; ··· 196 174 goto err; 197 175 } 198 176 199 - drvdata->mc_vbase = devm_ioremap(&pdev->dev, 200 - r->start, resource_size(r)); 201 - if (!drvdata->mc_vbase) { 177 + base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); 178 + if (!base) { 202 179 dev_err(&pdev->dev, "Unable to map regs\n"); 203 180 res = -ENOMEM; 204 181 goto err; 205 182 } 206 183 207 - control = readl(drvdata->mc_vbase + HB_DDR_ECC_OPT) & 0x3; 184 + settings = id->data; 185 + drvdata->mc_err_base = base + settings->err_offset; 186 + drvdata->mc_int_base = base + settings->int_offset; 187 + 188 + control = readl(drvdata->mc_err_base + HB_DDR_ECC_OPT) & 0x3; 208 189 if (!control || (control == 0x2)) { 209 190 dev_err(&pdev->dev, "No ECC present, or ECC disabled\n"); 210 191 res = -ENODEV; 211 192 goto err; 212 193 } 213 194 214 - irq = platform_get_irq(pdev, 0); 215 - res = devm_request_irq(&pdev->dev, irq, highbank_mc_err_handler, 216 - 0, dev_name(&pdev->dev), mci); 217 - if (res < 0) { 218 - dev_err(&pdev->dev, "Unable to request irq %d\n", irq); 219 - goto err; 220 - } 221 - 222 195 mci->mtype_cap = MEM_FLAG_DDR3; 223 196 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; 224 197 mci->edac_cap = EDAC_FLAG_SECDED; 225 - mci->mod_name = dev_name(&pdev->dev); 198 + mci->mod_name = pdev->dev.driver->name; 226 199 mci->mod_ver = "1"; 227 - mci->ctl_name = dev_name(&pdev->dev); 200 + mci->ctl_name = id->compatible; 201 + mci->dev_name = dev_name(&pdev->dev); 228 202 mci->scrub_mode = SCRUB_SW_SRC; 229 203 230 204 /* Only a single 4GB DIMM is supported */ ··· 235 217 if (res < 0) 236 218 goto err; 237 219 238 - highbank_mc_create_debugfs_nodes(mci); 220 + irq = platform_get_irq(pdev, 0); 221 + res = devm_request_irq(&pdev->dev, irq, highbank_mc_err_handler, 222 + 0, dev_name(&pdev->dev), mci); 223 + if (res < 0) { 224 + dev_err(&pdev->dev, "Unable to request irq %d\n", irq); 225 + goto err2; 226 + } 227 + 228 + device_create_file(&mci->dev, &dev_attr_inject_ctrl); 239 229 240 230 devres_close_group(&pdev->dev, NULL); 241 231 return 0; 232 + err2: 233 + edac_mc_del_mc(&pdev->dev); 242 234 err: 243 235 devres_release_group(&pdev->dev, NULL); 244 236 edac_mc_free(mci); ··· 259 231 { 260 232 struct mem_ctl_info *mci = platform_get_drvdata(pdev); 261 233 234 + device_remove_file(&mci->dev, &dev_attr_inject_ctrl); 262 235 edac_mc_del_mc(&pdev->dev); 263 236 edac_mc_free(mci); 264 237 return 0; 265 238 } 266 - 267 - static const struct of_device_id hb_ddr_ctrl_of_match[] = { 268 - { .compatible = "calxeda,hb-ddr-ctrl", }, 269 - {}, 270 - }; 271 - MODULE_DEVICE_TABLE(of, hb_ddr_ctrl_of_match); 272 239 273 240 static struct platform_driver highbank_mc_edac_driver = { 274 241 .probe = highbank_mc_probe,
-22
drivers/edac/mpc85xx_edac.c
··· 327 327 } 328 328 EXPORT_SYMBOL(mpc85xx_pci_err_probe); 329 329 330 - static int mpc85xx_pci_err_remove(struct platform_device *op) 331 - { 332 - struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev); 333 - struct mpc85xx_pci_pdata *pdata = pci->pvt_info; 334 - 335 - edac_dbg(0, "\n"); 336 - 337 - out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 338 - orig_pci_err_cap_dr); 339 - 340 - out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en); 341 - 342 - edac_pci_del_device(pci->dev); 343 - 344 - if (edac_op_state == EDAC_OPSTATE_INT) 345 - irq_dispose_mapping(pdata->irq); 346 - 347 - edac_pci_free_ctl_info(pci); 348 - 349 - return 0; 350 - } 351 - 352 330 #endif /* CONFIG_PCI */ 353 331 354 332 /**************************** L2 Err device ***************************/