From patchwork Thu Jan 21 17:34:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tthayer@opensource.altera.com X-Patchwork-Id: 8083681 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D16269F440 for ; Thu, 21 Jan 2016 17:35:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2DD50202FF for ; Thu, 21 Jan 2016 17:35:16 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7A69120398 for ; Thu, 21 Jan 2016 17:35:14 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aMJ6Z-0007Om-1y; Thu, 21 Jan 2016 17:33:07 +0000 Received: from mail-bl2on0067.outbound.protection.outlook.com ([65.55.169.67] helo=na01-bl2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aMJ6U-0007M4-7X for linux-arm-kernel@lists.infradead.org; Thu, 21 Jan 2016 17:33:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altera.onmicrosoft.com; s=selector1-opensource-altera-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Hh2qATi/uBXYtM2a1YN09NPZchrTi4nXMrWNfpvkTzg=; b=IvfhrojVVdaYXx3mZowI/OrLdsBuhHUHdfgC2lqxKxfX1sRBVWpinRWbezF5d/wIIqsh6AbPpuhXHZbbdr7nPPcXNx6WDx2jGvX6IQLQ+WUDGl9+Uv+GHUscKe3c889Sgjbm26E2Iuej9a309djcnUSqsTII/q0Fak0gb5WxhPM= Received: from CH1PR03CA003.namprd03.prod.outlook.com (10.255.156.148) by BN3PR0301MB1300.namprd03.prod.outlook.com (10.161.210.155) with Microsoft SMTP Server (TLS) id 15.1.365.19; Thu, 21 Jan 2016 17:32:27 +0000 Received: from BL2FFO11FD051.protection.gbl (10.255.156.132) by CH1PR03CA003.outlook.office365.com (10.255.156.148) with Microsoft SMTP Server (TLS) id 15.1.390.13 via Frontend Transport; Thu, 21 Jan 2016 17:32:27 +0000 Authentication-Results: spf=fail (sender IP is 66.35.236.236) smtp.mailfrom=opensource.altera.com; vger.kernel.org; dkim=pass (signature was verified) header.d=altera.onmicrosoft.com; vger.kernel.org; dmarc=none action=none header.from=opensource.altera.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.altera.com does not designate 66.35.236.236 as permitted sender) receiver=protection.outlook.com; client-ip=66.35.236.236; helo=sj-itexedge04.altera.priv.altera.com; Received: from sj-itexedge04.altera.priv.altera.com (66.35.236.236) by BL2FFO11FD051.mail.protection.outlook.com (10.173.161.213) with Microsoft SMTP Server (TLS) id 15.1.355.15 via Frontend Transport; Thu, 21 Jan 2016 17:32:26 +0000 Received: from na01-bl2-obe.outbound.protection.outlook.com (207.46.163.211) by webmail.altera.com (66.35.236.236) with Microsoft SMTP Server (TLS) id 14.3.174.1; Thu, 21 Jan 2016 09:31:37 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altera.onmicrosoft.com; s=selector1-opensource-altera-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Hh2qATi/uBXYtM2a1YN09NPZchrTi4nXMrWNfpvkTzg=; b=IvfhrojVVdaYXx3mZowI/OrLdsBuhHUHdfgC2lqxKxfX1sRBVWpinRWbezF5d/wIIqsh6AbPpuhXHZbbdr7nPPcXNx6WDx2jGvX6IQLQ+WUDGl9+Uv+GHUscKe3c889Sgjbm26E2Iuej9a309djcnUSqsTII/q0Fak0gb5WxhPM= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=tthayer@opensource.altera.com; Received: from tthayer-HP-Z620-Ubuntu.altera.com (64.129.157.38) by BY1PR03MB1482.namprd03.prod.outlook.com (10.162.210.140) with Microsoft SMTP Server (TLS) id 15.1.365.19; Thu, 21 Jan 2016 17:32:16 +0000 From: To: , , , , , , , , , , Subject: [PATCHv8 1/4] EDAC, altera: Add Altera L2 Cache and OCRAM EDAC Support Date: Thu, 21 Jan 2016 11:34:25 -0600 Message-ID: <1453397668-32094-1-git-send-email-tthayer@opensource.altera.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-Originating-IP: [64.129.157.38] X-ClientProxiedBy: CY1PR08CA0036.namprd08.prod.outlook.com (25.163.94.174) To BY1PR03MB1482.namprd03.prod.outlook.com (25.162.210.140) X-MS-Office365-Filtering-Correlation-Id: 5c03fb51-ec63-42ea-bd5f-08d32288d4d3 X-Microsoft-Exchange-Diagnostics-untrusted: 1; BY1PR03MB1482; 2:PSDjNnGr/h3NWlhWh0QqXUgDY4w9RsiOodjdPvVPrbUstNUsADEgo45hKJ2Pf2XpNeACTBtCvzXnO6fJhwEgE6UfBG8WX7/dB/edJnKJFAxw6Eju14OU5aSuV8kWh+/S5dfv3qo/5tdaEkap307bahAmJm70VoDPCVJ2qjKWPxhAhhm8C+tG+ETuSpEg8YAB; 3:vpaG5gtx89dIHcvK0vOpm4Q9yIHL5qPi8MZYz/tHRYmmVi1c4FjwC6G4NzxicIZZjoyTyP5Nxh83Jmnj+3D0syey4im1RIxLdnCmMXVMbV30HGehQ9iGL1ERqgxiklOH; 25:EID9gIOTftFqYzHQthFR85Xx3yNqe8B5xS6j3b4uUzh+zs22cO8n1z96fq4ltXZqMOqcL79/dLoiz4machC6TpY2w+zxB8+vgiTGOVS5DDPjj6NCBshfNWHsQtv5qKa3IdeJZ3GnCKdbREziZSd6ZypNoxgZR1wwaeCmzf+XC1vclK5mB/fgSVgt1891+eQxrHRXY0cs2dsc5IKG/Q4TRbdEUl+9m0dRDeNIFqAYd5cNMBtqaXuCBftJ3CMJuxhB; 20:k7JdfMxQzJn+QiYMVeKmzHRsuQjFSlSpaLJGGDB7oXA7MaYtgiwPjnPp6rDmZFyxmW64uBDe5f/imxkwcollZ5hUC+6RZnQu/pAueKhIyS30rD1VYYHe/qFV0RXt7B0PhKepv2vhrhgwqQJcHfC+XEnAZGCqp8xeHxQbvjzKZJs= X-Exchange-Antispam-Report-Test: UriScan:; BCL:0; PCL:0; RULEID:; SRVR:BY1PR03MB1482; UriScan:(80048183373757)(204874498639787); UriScan:; BCL:0; PCL:0; RULEID:(3001016); SRVR:BN3PR0301MB1300; UriScan:(80048183373757)(204874498639787); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(520078)(5005006)(3002001)(10201501046); SRVR:BY1PR03MB1482; BCL:0; PCL:0; RULEID:; SRVR:BY1PR03MB1482; BCL:0; PCL:0; RULEID:(601004)(2401047)(520078)(5005006)(8121501046)(13023025)(13017025)(13024025)(13018025)(13015025)(10201501046)(3002001); SRVR:BN3PR0301MB1300; BCL:0; PCL:0; RULEID:; SRVR:BN3PR0301MB1300; X-Microsoft-Exchange-Diagnostics-untrusted: 1; BY1PR03MB1482; 4:llDV+P0ktYu/xZu4bgP4L2MRpt9/euwHyAjCy3rFYiIF9X9z2fEBs0pNkMAAjvGVdaImoE1EP47WhEDZjTxzIVF7zmxpdXU1+qdPG6+K4Vl3nhnSzybagGC+q866qQYNbnfG9JaklwQz/hF9f5pwFUC9LMWqPAtd6gEQ6Tzug9KmH4JUYUWmLFnL3RRYqf1BZdPSuYs8OeijWqrIvgs7FSveUcb1CBLCreFye9g8wYWWF66muS51Fx7w1Ynn1qWacnhdgO103F8IvBq/7tzHOmipNcMDC05TlOpsru71f3nLu/4t4NqtDPXwnrGUbY9maw/9plogwSOkrGDhPTVfRBTk99ohb/T6XrYLmk5o6TVkuVeHLgdzp1e9bJH/DI9pb9pg4Wo9vDjIeHbQQl/4N8nVrkBJGQmKubu7pOXyaXIF1czhB0cojz0+QRzTo9JxuyGv/U2fqj4wtHR0RegzAg== X-Forefront-PRVS: 08286A0BE2 X-Forefront-Antispam-Report-Untrusted: SFV:NSPM; SFS:(10009020)(6009001)(199003)(189002)(586003)(47776003)(92566002)(4001430100002)(1096002)(5004730100002)(42186005)(3846002)(86362001)(4326007)(6116002)(106356001)(2906002)(77096005)(105586002)(189998001)(19580405001)(50226001)(5008740100001)(122386002)(229853001)(53416004)(33646002)(5001770100001)(50986999)(97736004)(86152002)(19580395003)(107886002)(87976001)(2201001)(5001960100002)(40100003)(5003940100001)(101416001)(66066001)(50466002)(81156007)(2876002)(48376002)(69596002)(921003)(2004002)(1121003)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:BY1PR03MB1482; H:tthayer-HP-Z620-Ubuntu.altera.com; FPR:; SPF:None; PTR:InfoNoRecords; A:0; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: opensource.altera.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics-untrusted: =?us-ascii?Q?1; BY1PR03MB1482; 23:UdQ+mellwLJBCax69AJSwX9m3qVQevdGN+DqTwZAQ?= =?us-ascii?Q?E3wSGO72TN6nngSrjcB93unZVr7WN9pgA3nCVDjtIWT2DeRy/vzTpZ7e3p59?= =?us-ascii?Q?8cRK7yJsdA4ugwVjR7GHg0o5v654VP8RRYW+bNXuUZksBKxaLtCv+jIcPacZ?= =?us-ascii?Q?TREs2jE0Ng42fkemiTcc83ecnn403Vb/exzdz+m6PSPcDt84qyDpVas/L4BT?= =?us-ascii?Q?+3DqVm5kDcWyOzbQrH0Cq9jLqCmyKm2mIRBXfiblF0YKdDuokYiu5HW3hOmM?= =?us-ascii?Q?/y1WIYMm7BkdDkd5IC/5DZjeYHSriCc5gbfp9RB3aogjrklP/vXJUGFeJOwt?= =?us-ascii?Q?2perzQFn3Bn9Zok2FXpvRj6JfYatFcsucE9Zr1jQSWNqvo9T8SJZjW+mmHV8?= =?us-ascii?Q?PMmD2hg4lMO0jzl0elHvJSjq1qcmyFq8DLLoJGdvSx5L+EOHtnf8EfK8JzEZ?= =?us-ascii?Q?aUnZBssZL9W24lfzz0+nOObh0QK0Hx3PRTC9Xb+X0OFm0bigPFI+rU4CoBxr?= =?us-ascii?Q?IlstU2N6FohlIOmeAfTyaeiGrediUMMPdhZZRnP1Wh2f5KRy3Dkcapejs3ly?= =?us-ascii?Q?4jFkS9+BOAJl5u7cL1mhMgapbr5IVZ28ImAuozL0KmSNw5A2DowFNa61EWsq?= =?us-ascii?Q?twGc08h6mYF6N0l+cB6h7RGfwPLQat/74+Ih+KQNu9GyUyfB+U7s87/HpyF6?= =?us-ascii?Q?0g9KsDvI3105Nd/84iynhVegXKbLL6byypq1IhVsxMly/Ct6S0H7bBq1ehfs?= =?us-ascii?Q?MTHJZOXA/3jsya+N6PK3Bs0319u91SY/Y9szcxpbzwnLSYjWb8ynYsR7XbDJ?= =?us-ascii?Q?qZ/7Zrkg6g/QmP63y38m6iYXwqj6MKw5O6nw+nRZZm6mlkTtqOMI9jfRlda0?= =?us-ascii?Q?7g4jDsQFe6iy9VQUKbq9t3uAuKRzvLf5XlyNFbHqWZIT+jEfodubZepNfhTx?= =?us-ascii?Q?U/JzkeuDEyuEgF2ik+Ehwmg4jI7XKC2iWbBFxz0ie7GXWbSxPggpNfJpMrWD?= =?us-ascii?Q?Ch1jNkF0ZA3eq/ToU20nRCBqMb5LW/CnGmNnD3cLO+Bu8LomaNORiiSrlk1Y?= =?us-ascii?Q?RguS9ez/H2SE1lDR2yfSJU5DADKQq+i7q5FVuUPwHTgO/dm9/uRxIW8hvDwL?= =?us-ascii?Q?8RdpH9D+tWTjcGa8Fr6jFq1yzQdEAlVthxK4AdB8T87nU0bIeVmVEvHev0St?= =?us-ascii?Q?bpAbfzyxOYIFMkFHgLOIPVkKLFCC2qxPaPtyAeLFGkmIEMkZ/3z92PjLA=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics-untrusted: 1; BY1PR03MB1482; 5:WgXstbmcZsPqA2IUA6GHfbb8PcvqyILTLVPVulDQ+tHxa8lNUi7dsIZ9xgR5ZAXxrppdpPoctZSreUdFsMGnYVwUe5546F33+RjkIoiLmtXyxEeb7//DVr2GkuihehHHr8T4qH3hT5v1qU/T7kwQoA==; 24:PTuong59K8bVPAiyPyl7cJtu6R5tdy5b2yoHQh0DzfFYP4Q35lduPiNxc9178OgVdmx3aiUGn5FELY+QpYRN6c3TM0ZhwBpQ9rIUhZJmVQk=; 20:B/od6Eju7IGwWI8+jS8tZxSnBw+Sd+sK6U7gQ6rFf4r8MBb4Kpr6SoaS2sQ6pCtyeoRgNaV00qugD5wsqwe2ITQsD+Z+IjOUh2fUCLv66tLybwimRP9UlRKKrjN+3nsrQkTYVT8jis/xakmnmHeMeLMBJVLj1kPMY+9hhVglKVU= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR03MB1482 X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: BL2FFO11FD051.protection.gbl X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD051; 1:9MLPKFwf8GAP/hf4oFDYJoOTRddCkRT2916c+hhd00/bjtPzCK9FPKyqz9rXAFV5I4JH0SccpwJsxPfoe6/5WT/1hvlldrEFUC2WupotKYpxHdhR7Bc8HuqIeSHK4WfGaCk3VeibK1K4RvBa7DGHa6Prsh8ZTEnV8G/h9X3pZ1NgO4hon+MTSz+5Q3xBK+vc0WFrg4Ms1bWAF3+fi5nRLr8PdxpEFr3YR8oQscba27TquXLG1oVS/lJVWYCYtAXwEZvLhQia9S8T4DFLLTsqXguX4Ih0isKvJRO+1nuMwPMw0FK3T2sLvce7IwHpIPRU6AVyNabDYQzYCIyINdTboevSDpf4aR8DsCyf3bIgYeMZ5E3aqz5hYEltUIPCUv6+tH/rTMVCe29+bGyEJh9hmlsTlxmD2lFZW2DzIExKPc+CVfv8MyVM5TcHewk5ZRo9AoyiKNuN8AqAHCOONZbwJA== X-Forefront-Antispam-Report: CIP:66.35.236.236; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(5003940100001)(5001960100002)(106466001)(11100500001)(189998001)(6070500001)(3846002)(50226001)(66066001)(97736004)(21840400001)(4326007)(47776003)(5001770100001)(1220700001)(1096002)(77096005)(16796002)(81156007)(85426001)(86152002)(105606002)(5004730100002)(2906002)(33646002)(122386002)(50466002)(40100003)(87936001)(586003)(53416004)(6116002)(4001430100002)(48376002)(107886002)(229853001)(2876002)(50986999)(19580405001)(6806005)(92566002)(2201001)(86362001)(19580395003)(956001)(5008740100001)(7099028)(2004002)(921003)(1121003)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:BN3PR0301MB1300; H:sj-itexedge04.altera.priv.altera.com; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:0; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN3PR0301MB1300; 2:nmlJZosZOgb+JcgDrz/kGD3tg7iCxplzn50y7M3TOOlwYTKCDa7786JslktXEqbMzLo9rt5yvWai6oLIv0yvnmWWop93lqVreR6tiG4T/ISnzPlVbhqYdWunLwlaBZ0p1UMjaLMfnBVyx8Oe3dRk/IaQZwLVSdA1aHYy19bNW45MtjYDrvpzRtdR49Ig46ET; 3:G59y1adk8vnCckrPVhBs4CDn1J+IJ7iFAzgn5RisOJNjXXDkc2TGC2pTR5QrCAJgEqwdvSZTKgtS7o1XOvZlsqgZpD18b7NYBBV55zRaJ8kw8ItMI5cjSJ1J00JCWkzXwf5ZwNw5c0f61aPlqmebT3rBNv9nZz64PBzXw4mB3aX1XHe342y4kuhjlkw1JKsO5pgblxPcl17bzvQMTDW1Hea0Y73rwpmMGrVIn4I883Tv6R941EtVZWRbucRaYmK1; 25:TiNYAn+sN8/N6jGjSs3MkzlCTLTfhRbvRLlUgnvTaUOGImSdZVr00jZHVZfl2kVsrRb83dlVne5ZSBKBRm0a0jqcLuNcknkyRaxd6savSHHOFQ5h4Hjw1gN+aPKo2A734fjiMkYemeN3PDCNJtgPXT8Gp5IDPoXm1wl4am2odfl+Vo1Q0O8wfsNGs1jQEh4ekbsyh7ItktXHS/Ou9KMHifL74/+g3igbwUPEicx36bOg/xAKxNmlxYTAJPzRTkRt; 20:u4rRcn+H7LctR0dwJW7I/rjx+g7yx+nsnC9oNRCDhWxnvIuNo0sVXD7lLFG9Gbem9E+YdkolicppKUKmejxHMs/Xg4c8zzpaPA36F+HtIPkwPNeeChxeuKaaUCPw0MOPgk9G+ByZIqtojKuT5oC5GUjKcekPHVDqORaa5yoSyJ8= X-DkimResult-Test: Passed X-Microsoft-Exchange-Diagnostics: 1; BN3PR0301MB1300; 4:P0Sfcj9lBaqloQkcVIOUocMN0tLQI3Dj2YGV6W+/1nlFZnIhoUmmgDcJZOOQ26SsvZwtQtGI8HKJTCE9ED35/U9xiaYm/wfI+MdYBfm03zwF/x5gO6LUbYDNkQFatiwNfrPeN7I6iidWC2AD4i/km+tWZJZ/4oHUGKXKRwAlPD9JnQPVMw77bFe7dGYxWMV34nE0HOmdGDtBj4T2jeQEdfuLy02NSDUdZviPPjmsfe4XH9/xYjKwushI8BQbuDhYfGWoz5jc46POh/sWYc3DhJBKsxW/WT6RwyRnW56e8j3q8Lm44ozWygMg/sIqbpybR0UDdUa0vtS85ebmdCjNFIjyIfvSV/fZAfNoOrLr1jQXBy/V5BnJTWfT3zYNpu8g6LGLCb7Ta8lglAMlKOevNYj+q8XGq28EU+/zDBvLkG42yl7zZ2izpXwzuisnbdsD1OuwBy+22cy8p58VDkjT6ONFctNzwQU9um1rMIbnAwMvQamTxxCB0R5PXRZ6/lQo8dxVe1ehohbmKnbdJvvUoPTlDio04DtqA0abv+ddsN8= X-Forefront-PRVS: 08286A0BE2 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN3PR0301MB1300; 23:NKHtmK5zCe/QVW+7B/13Uze4olwrc17lgyS71ow?= =?us-ascii?Q?93RRIVAv3b8GU4bXrmhXwC44EbUQVNTA+OayHyD83nKzPJdQI4noFjH06Sht?= =?us-ascii?Q?c3lEis+WLyp3hLFGIbdwMtqv9NuMTp4zlBpY/48XbOjlLhhfgh//oLtAa22o?= =?us-ascii?Q?eFuycw1OKnGfwQ7b/gw9SzcvG8Nq0Qlyvg0zjDZvRVBHNv9d1yLNk8/YJxau?= =?us-ascii?Q?wnNi2STKscescp2k6TwmNAjJXEp/xa0yMKkK0WEUic8z+u/xJTbP3bVvCaHF?= =?us-ascii?Q?AY1EBxq2FbKGWUJUCUlimFu7p5GUKEW1jyJuj7WdL4Qgrll5AVFHVCHLIqHr?= =?us-ascii?Q?7uZmhOM+uUhgcW7i5oygVMYCfva9qtMF5TNqRr9Hr5JCv9Ymyzs2WVbdCVbr?= =?us-ascii?Q?gWftcBV6cUsLhZoQLtD+1HW8F74IzXcy94PQuk5geasdN49+v1CBKTAUpNPp?= =?us-ascii?Q?TEPzFsW5/RjidSDtlXzLWB62QO7MdZB6ARjILDtDSpzkgh+ZC28gMdTfAHQh?= =?us-ascii?Q?VzWBJ1RNa5YfQxEp2uZG9oDqIgktRF5pvMfNTQqixE7aQvvfI/GFkOT/Lp+H?= =?us-ascii?Q?C8zOWuRgaxjrrmo49McXX94MKnFyQDBtZD/8VfmQ8TsP1wHaFRc74fsIbetj?= =?us-ascii?Q?9N+qsjV5ztLjw11O5VJ6PDxlgm1t2wjaIys9bK8FgsYyenwib3gs+RemjT6t?= =?us-ascii?Q?ow3fZ3khzmqUbxzKEyXZkwgI3cCYWtH72tORwHBu0pAhY9u6KwZMb7vkvqwR?= =?us-ascii?Q?OQnamDQDqurrVlq70K9rQHA4YHkTS8kdys2WrUsB9VhHmC0wIO0d+SJ5BmrR?= =?us-ascii?Q?WLM40lp0sz6zaIl00n6OtGnXfPquM1D/+rmsQqVyEuaZuy0zJjghbotDG7Z/?= =?us-ascii?Q?JZsEVFZcw1wDIfWJcE4f6JgKvUmBJaZRv8X1oOqJfD6JJ/lVzdf2G34P1Kgu?= =?us-ascii?Q?4LWDYKIbhRxs998ruYiEyVsjFz5MQDfShFljcwFZl7S8Pmh29eF9yDXn7Qks?= =?us-ascii?Q?lcvuyMkTVvSqYtUoSwTevrfy8yKpnK3zmJefo/Cp2tEWbQDapIxpkkbi2gwk?= =?us-ascii?Q?m9S0vE5S2Cqz2SLazN+5a6w07Tz6+vkaByei9vTQrZee0uAGr8tcsOy3SEpA?= =?us-ascii?Q?qHBdsf9+zyfByxJembPN1f/Rl7aZKa4+JnjxyNmNEmWPZF8Q3gRFcORG9OK/?= =?us-ascii?Q?jo7fkvSlMWCghNf6TBGMNgNxq+hKNILbKKUwyFZiDEmUVa9tOc1xtZkhnFAG?= =?us-ascii?Q?nodNPn2D4oZ3DRjH3g5xKpMCWyz7iRihFH8rCQl9we8tkJ/M9WrgEmj3rGsB?= =?us-ascii?Q?49cKBudnBZMqYSjcdX4vaggcqn9wtC0C2JQwA4LwfVTh2jL3ii2Koz1Q91yX?= =?us-ascii?Q?bLL/kbSbOJmE13CFAOtpFgBpnVDSoav9vDfYYkLE/38htB1c0Z3++NTw8pre?= =?us-ascii?Q?+D2Ach6mtGEB5XLxwjzxr+jUlSNLjMjuLPbAjtPaOlz9McrHm8QxJ?= X-Microsoft-Exchange-Diagnostics: 1; BN3PR0301MB1300; 5:gZrX8E31yD4ATrTPx3Uy7i7niWxj8X5AYpHy91my0GIbOdSWBTbnmEbRM/k+dEenfkoMy7m+oaKvHAXSaIRU98z40/Bqr/hBK/NhCjjpmUSVyCSJKfK2oEyao2uGZ30OBMCg/OfPJDtXJonbyoFa6Q==; 24:HOL41gms2m/PDU/h6qdRYWBbGj5mO29MOuUcG/v3ygSFttpInwZ/sHmmzao8b/8EH+c/Pup1UCPuCN53U55eoVCc5xyuok5QerHXlb9nork=; 20:3lnc5TwagXVDNNgrhYJQhxhfZYMuqtjNW9fxTL9Njdci7w4DtnYAVt9K87sJqV9VhJDiRXjLH8QtyE3IcmHKGWwnUVQtc8xGOxYrHrukveoKrggvRU6iN5vjWEDtpv1y9+DgTy09mVQMOr8O+/gkDBAlLfLWhwq6/MfFR8DUtig= X-OriginatorOrg: opensource.altera.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jan 2016 17:32:26.7171 (UTC) X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fbd72e03-d4a5-4110-adce-614d51f2077a; Ip=[66.35.236.236]; Helo=[sj-itexedge04.altera.priv.altera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR0301MB1300 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160121_093302_616695_92964C18 X-CRM114-Status: UNSURE ( 6.04 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, tthayer.linux@gmail.com, tthayer@opensource.altera.com, linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thor Thayer Adding L2 Cache and On-Chip RAM EDAC support for the Altera SoCs using the EDAC device model. The SDRAM controller is using the Memory Controller model. Each type of ECC is individually configurable. Signed-off-by: Thor Thayer Signed-off-by: Dinh Nguyen --- v8: Remove MASK from single bit mask names. s/altr,edac/altr,socfpga-ecc-manager Use debugfs instead of sysfs. Add chip family name to match string. Fix header year. Fix build dependencies & change commit accordingly. s/CONFIG_EDAC_ALTERA_MC/CONFIG_EDAC_ALTERA v7: s/of_get_named_gen_pool/of_gen_pool_get Remove #ifdef for EDAC_DEBUG Use -ENODEV instead of EPROBE_DEFER v6: Convert to nested EDAC in device tree. Force L2 cache on for L2Cache ECC & remove L2 cache syscon for checking enable bit. Update year in header. v5: No change. v4: Change mask defines to use BIT(). Fix comment style to agree with kernel coding style. Better printk description for read != write in trigger. Remove SysFS debugging message. Better dci->mod_name Move gen_pool pointer assignment to end of function. Invert logic to reduce indent in ocram depenency check. Change from dev_err() to edac_printk() Replace magic numbers with defines & comments. Improve error injection test. Change Makefile intermediary name to altr (from alt) v3: Move OCRAM and L2 cache EDAC functions into altera_edac.c instead of separate files. v2: Fix L2 dependency comments. --- drivers/edac/Kconfig | 26 ++- drivers/edac/Makefile | 2 +- drivers/edac/altera_edac.c | 484 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 504 insertions(+), 8 deletions(-) diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index ef25000..15a6df4 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -367,14 +367,30 @@ config EDAC_OCTEON_PCI Support for error detection and correction on the Cavium Octeon family of SOCs. -config EDAC_ALTERA_MC - bool "Altera SDRAM Memory Controller EDAC" +config EDAC_ALTERA + bool "Altera SOCFPGA ECC" depends on EDAC_MM_EDAC=y && ARCH_SOCFPGA help Support for error detection and correction on the - Altera SDRAM memory controller. Note that the - preloader must initialize the SDRAM before loading - the kernel. + Altera SOCs. This must be selected for SDRAM ECC. + Note that the preloader must initialize the SDRAM + before loading the kernel. + +config EDAC_ALTERA_L2C + bool "Altera L2 Cache ECC" + depends on EDAC_ALTERA=y + select CACHE_L2X0 + help + Support for error detection and correction on the + Altera L2 cache Memory for Altera SoCs. This option + requires L2 cache so it will force that selection. + +config EDAC_ALTERA_OCRAM + bool "Altera On-Chip RAM ECC" + depends on EDAC_ALTERA=y && SRAM && GENERIC_ALLOCATOR + help + Support for error detection and correction on the + Altera On-Chip RAM Memory for Altera SoCs. config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index be163e2..f9e4a3e 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -67,6 +67,6 @@ obj-$(CONFIG_EDAC_OCTEON_L2C) += octeon_edac-l2c.o obj-$(CONFIG_EDAC_OCTEON_LMC) += octeon_edac-lmc.o obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o -obj-$(CONFIG_EDAC_ALTERA_MC) += altera_edac.o +obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o obj-$(CONFIG_EDAC_SYNOPSYS) += synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 9296409..728e736 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1,5 +1,5 @@ /* - * Copyright Altera Corporation (C) 2014-2015. All rights reserved. + * Copyright Altera Corporation (C) 2014-2016. All rights reserved. * Copyright 2011-2012 Calxeda, Inc. * * This program is free software; you can redistribute it and/or modify it @@ -17,8 +17,10 @@ * Adapted from the highbank_mc_edac driver. */ +#include #include #include +#include #include #include #include @@ -34,6 +36,7 @@ #define EDAC_MOD_STR "altera_edac" #define EDAC_VERSION "1" +#define EDAC_DEVICE "Altera" static const struct altr_sdram_prv_data c5_data = { .ecc_ctrl_offset = CV_CTLCFG_OFST, @@ -75,6 +78,31 @@ static const struct altr_sdram_prv_data a10_data = { .ue_set_mask = A10_DIAGINT_TDERRA_MASK, }; +/************************** EDAC Device Defines **************************/ + +/* OCRAM ECC Management Group Defines */ +#define ALTR_MAN_GRP_OCRAM_ECC_OFFSET 0x04 +#define ALTR_OCR_ECC_EN BIT(0) +#define ALTR_OCR_ECC_INJS BIT(1) +#define ALTR_OCR_ECC_INJD BIT(2) +#define ALTR_OCR_ECC_SERR BIT(3) +#define ALTR_OCR_ECC_DERR BIT(4) + +/* L2 ECC Management Group Defines */ +#define ALTR_MAN_GRP_L2_ECC_OFFSET 0x00 +#define ALTR_L2_ECC_EN BIT(0) +#define ALTR_L2_ECC_INJS BIT(1) +#define ALTR_L2_ECC_INJD BIT(2) + +#define ALTR_UE_TRIGGER_CHAR 'U' /* Trigger for UE */ +#define ALTR_TRIGGER_READ_WRD_CNT 32 /* Line size x 4 */ +#define ALTR_TRIG_OCRAM_BYTE_SIZE 128 /* Line size x 4 */ +#define ALTR_TRIG_L2C_BYTE_SIZE 4096 /* Full Page */ + +/*********************** EDAC Memory Controller Functions ****************/ + +/* The SDRAM controller uses the EDAC Memory Controller framework. */ + static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id) { struct mem_ctl_info *mci = dev_id; @@ -504,6 +532,458 @@ static struct platform_driver altr_sdram_edac_driver = { module_platform_driver(altr_sdram_edac_driver); +/************************* EDAC Parent Probe *************************/ + +static const struct of_device_id altr_edac_device_of_match[]; + +static const struct of_device_id altr_edac_of_match[] = { + { .compatible = "altr,socfpga-ecc-manager" }, + {}, +}; +MODULE_DEVICE_TABLE(of, altr_edac_of_match); + +static int altr_edac_probe(struct platform_device *pdev) +{ + of_platform_populate(pdev->dev.of_node, altr_edac_device_of_match, + NULL, &pdev->dev); + return 0; +} + +static struct platform_driver altr_edac_driver = { + .probe = altr_edac_probe, + .driver = { + .name = "socfpga_ecc_manager", + .of_match_table = altr_edac_of_match, + }, +}; +module_platform_driver(altr_edac_driver); + +/************************* EDAC Device Functions *************************/ + +/* + * EDAC Device Functions (shared between various IPs). + * The discrete memories use the EDAC Device framework. The probe + * and error handling functions are very similar between memories + * so they are shared. The memory allocation and freeing for EDAC + * trigger testing are different for each memory. + */ + +const struct edac_device_prv_data ocramecc_data; +const struct edac_device_prv_data l2ecc_data; + +struct edac_device_prv_data { + int (*setup)(struct platform_device *pdev, void __iomem *base); + int ce_clear_mask; + int ue_clear_mask; + struct edac_dev_sysfs_attribute *eccmgr_sysfs_attr; + char dbgfs_name[20]; + void * (*alloc_mem)(size_t size, void **other); + void (*free_mem)(void *p, size_t size, void *other); + int ecc_enable_mask; + int ce_set_mask; + int ue_set_mask; + int trig_alloc_sz; +}; + +struct altr_edac_device_dev { + void __iomem *base; + int sb_irq; + int db_irq; + const struct edac_device_prv_data *data; + char *edac_dev_name; +}; + +static irqreturn_t altr_edac_device_handler(int irq, void *dev_id) +{ + struct edac_device_ctl_info *dci = dev_id; + struct altr_edac_device_dev *drvdata = dci->pvt_info; + const struct edac_device_prv_data *priv = drvdata->data; + + if (irq == drvdata->sb_irq) { + if (priv->ce_clear_mask) + writel(priv->ce_clear_mask, drvdata->base); + edac_device_handle_ce(dci, 0, 0, drvdata->edac_dev_name); + } + if (irq == drvdata->db_irq) { + if (priv->ue_clear_mask) + writel(priv->ue_clear_mask, drvdata->base); + edac_device_handle_ue(dci, 0, 0, drvdata->edac_dev_name); + panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n"); + } + + return IRQ_HANDLED; +} + +static ssize_t altr_edac_device_trig(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) + +{ + u32 *ptemp, i, error_mask; + int result = 0; + u8 trig_type; + unsigned long flags; + struct edac_device_ctl_info *edac_dci = file->private_data; + struct altr_edac_device_dev *drvdata = edac_dci->pvt_info; + const struct edac_device_prv_data *priv = drvdata->data; + void *generic_ptr = edac_dci->dev; + + if (!user_buf || get_user(trig_type, user_buf)) + return -EFAULT; + + if (!priv->alloc_mem) + return -ENOMEM; + + /* + * Note that generic_ptr is initialized to the device * but in + * some alloc_functions, this is overridden and returns data. + */ + ptemp = priv->alloc_mem(priv->trig_alloc_sz, &generic_ptr); + if (!ptemp) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "Inject: Buffer Allocation error\n"); + return -ENOMEM; + } + + if (trig_type == ALTR_UE_TRIGGER_CHAR) + error_mask = priv->ue_set_mask; + else + error_mask = priv->ce_set_mask; + + edac_printk(KERN_ALERT, EDAC_DEVICE, + "Trigger Error Mask (0x%X)\n", error_mask); + + local_irq_save(flags); + /* write ECC corrupted data out. */ + for (i = 0; i < (priv->trig_alloc_sz / sizeof(*ptemp)); i++) { + /* Read data so we're in the correct state */ + rmb(); + if (ACCESS_ONCE(ptemp[i])) + result = -1; + /* Toggle Error bit (it is latched), leave ECC enabled */ + writel(error_mask, drvdata->base); + writel(priv->ecc_enable_mask, drvdata->base); + ptemp[i] = i; + } + /* Ensure it has been written out */ + wmb(); + local_irq_restore(flags); + + if (result) + edac_printk(KERN_ERR, EDAC_DEVICE, "Mem Not Cleared\n"); + + /* Read out written data. ECC error caused here */ + for (i = 0; i < ALTR_TRIGGER_READ_WRD_CNT; i++) + if (ACCESS_ONCE(ptemp[i]) != i) + edac_printk(KERN_ERR, EDAC_DEVICE, + "Read doesn't match written data\n"); + + if (priv->free_mem) + priv->free_mem(ptemp, priv->trig_alloc_sz, generic_ptr); + + return count; +} + +static const struct file_operations altr_edac_device_inject_fops = { + .open = simple_open, + .write = altr_edac_device_trig, + .llseek = generic_file_llseek, +}; + +static void altr_create_edacdev_dbgfs(struct edac_device_ctl_info *edac_dci, + const struct edac_device_prv_data *priv, + struct dentry *debugfs) +{ + if (!IS_ENABLED(CONFIG_EDAC_DEBUG)) + return; + + edac_debugfs_create_file(priv->dbgfs_name, S_IWUSR, + debugfs, edac_dci, + &altr_edac_device_inject_fops); +} + +static const struct of_device_id altr_edac_device_of_match[] = { +#ifdef CONFIG_EDAC_ALTERA_L2C + { .compatible = "altr,socfpga-l2-ecc", .data = (void *)&l2ecc_data }, +#endif +#ifdef CONFIG_EDAC_ALTERA_OCRAM + { .compatible = "altr,socfpga-ocram-ecc", + .data = (void *)&ocramecc_data }, +#endif + {}, +}; +MODULE_DEVICE_TABLE(of, altr_edac_device_of_match); + +/* + * altr_edac_device_probe() + * This is a generic EDAC device driver that will support + * various Altera memory devices such as the L2 cache ECC and + * OCRAM ECC as well as the memories for other peripherals. + * Module specific initialization is done by passing the + * function index in the device tree. + */ +static int altr_edac_device_probe(struct platform_device *pdev) +{ + struct edac_device_ctl_info *dci; + struct altr_edac_device_dev *drvdata; + struct resource *r; + int res = 0; + struct device_node *np = pdev->dev.of_node; + char *ecc_name = (char *)np->name; + static int dev_instance; + struct dentry *debugfs; + + if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "Unable to open devm\n"); + return -ENOMEM; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "Unable to get mem resource\n"); + return -ENODEV; + } + + if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), + dev_name(&pdev->dev))) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "%s:Error requesting mem region\n", ecc_name); + return -EBUSY; + } + + dci = edac_device_alloc_ctl_info(sizeof(*drvdata), ecc_name, + 1, ecc_name, 1, 0, NULL, 0, + dev_instance++); + + if (!dci) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "%s: Unable to allocate EDAC device\n", ecc_name); + return -ENOMEM; + } + + drvdata = dci->pvt_info; + dci->dev = &pdev->dev; + platform_set_drvdata(pdev, dci); + drvdata->edac_dev_name = ecc_name; + + drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); + if (!drvdata->base) + goto err; + + /* Get driver specific data for this EDAC device */ + drvdata->data = of_match_node(altr_edac_device_of_match, np)->data; + + /* Check specific dependencies for the module */ + if (drvdata->data->setup) { + res = drvdata->data->setup(pdev, drvdata->base); + if (res < 0) + goto err; + } + + drvdata->sb_irq = platform_get_irq(pdev, 0); + res = devm_request_irq(&pdev->dev, drvdata->sb_irq, + altr_edac_device_handler, + 0, dev_name(&pdev->dev), dci); + if (res < 0) + goto err; + + drvdata->db_irq = platform_get_irq(pdev, 1); + res = devm_request_irq(&pdev->dev, drvdata->db_irq, + altr_edac_device_handler, + 0, dev_name(&pdev->dev), dci); + if (res < 0) + goto err; + + dci->mod_name = "Altera ECC Manager"; + dci->dev_name = drvdata->edac_dev_name; + + debugfs = edac_debugfs_create_dir(ecc_name); + if (debugfs) + altr_create_edacdev_dbgfs(dci, drvdata->data, debugfs); + + if (edac_device_add_device(dci)) + goto err; + + devres_close_group(&pdev->dev, NULL); + + return 0; +err: + edac_printk(KERN_ERR, EDAC_DEVICE, + "%s:Error setting up EDAC device: %d\n", ecc_name, res); + devres_release_group(&pdev->dev, NULL); + edac_device_free_ctl_info(dci); + + return res; +} + +static int altr_edac_device_remove(struct platform_device *pdev) +{ + struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); + + edac_device_del_device(&pdev->dev); + edac_device_free_ctl_info(dci); + + return 0; +} + +static struct platform_driver altr_edac_device_driver = { + .probe = altr_edac_device_probe, + .remove = altr_edac_device_remove, + .driver = { + .name = "altr_edac_device", + .of_match_table = altr_edac_device_of_match, + }, +}; +module_platform_driver(altr_edac_device_driver); + +/*********************** OCRAM EDAC Device Functions *********************/ + +#ifdef CONFIG_EDAC_ALTERA_OCRAM + +static void *ocram_alloc_mem(size_t size, void **other) +{ + struct device_node *np; + struct gen_pool *gp; + void *sram_addr; + + np = of_find_compatible_node(NULL, NULL, "altr,socfpga-ocram-ecc"); + if (!np) + return NULL; + + gp = of_gen_pool_get(np, "iram", 0); + if (!gp) { + of_node_put(np); + return NULL; + } + of_node_put(np); + + sram_addr = (void *)gen_pool_alloc(gp, size / sizeof(size_t)); + if (!sram_addr) + return NULL; + + memset(sram_addr, 0, size); + wmb(); /* Ensure data is written out */ + + *other = gp; /* Remember this handle for freeing later */ + + return sram_addr; +} + +static void ocram_free_mem(void *p, size_t size, void *other) +{ + gen_pool_free((struct gen_pool *)other, (u32)p, size / sizeof(size_t)); +} + +/* + * altr_ocram_dependencies() + * Test for OCRAM cache ECC dependencies upon entry because + * platform specific startup should have initialized the + * On-Chip RAM memory and enabled the ECC. + * Can't turn on ECC here because accessing un-initialized + * memory will cause CE/UE errors possibly causing an ABORT. + */ +static int altr_ocram_dependencies(struct platform_device *pdev, + void __iomem *base) +{ + u32 control; + + control = readl(base) & ALTR_OCR_ECC_EN; + if (control) + return 0; + + edac_printk(KERN_ERR, EDAC_DEVICE, + "OCRAM: No ECC present or ECC disabled.\n"); + return -ENODEV; +} + +const struct edac_device_prv_data ocramecc_data = { + .setup = altr_ocram_dependencies, + .ce_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_SERR), + .ue_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_DERR), + .dbgfs_name = "altr_ocram_trigger", + .alloc_mem = ocram_alloc_mem, + .free_mem = ocram_free_mem, + .ecc_enable_mask = ALTR_OCR_ECC_EN, + .ce_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJS), + .ue_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJD), + .trig_alloc_sz = ALTR_TRIG_OCRAM_BYTE_SIZE, +}; + +#endif /* CONFIG_EDAC_ALTERA_OCRAM */ + +/********************* L2 Cache EDAC Device Functions ********************/ + +#ifdef CONFIG_EDAC_ALTERA_L2C + +static void *l2_alloc_mem(size_t size, void **other) +{ + struct device *dev = *other; + void *ptemp = devm_kzalloc(dev, size, GFP_KERNEL); + + if (!ptemp) + return NULL; + + /* Make sure everything is written out */ + wmb(); + + /* + * Clean all cache levels up to LoC (includes L2) + * This ensures the corrupted data is written into + * L2 cache for readback test (which causes ECC error). + */ + flush_cache_all(); + + return ptemp; +} + +static void l2_free_mem(void *p, size_t size, void *other) +{ + struct device *dev = other; + + if (dev && p) + devm_kfree(dev, p); +} + +/* + * altr_l2_dependencies() + * Test for L2 cache ECC dependencies upon entry because + * platform specific startup should have initialized the L2 + * memory and enabled the ECC. + * Bail if ECC is not enabled. + * Note that L2 Cache Enable is forced at build time. + */ +static int altr_l2_dependencies(struct platform_device *pdev, + void __iomem *base) +{ + u32 control; + + control = readl(base) & ALTR_L2_ECC_EN; + if (!control) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "L2: No ECC present, or ECC disabled\n"); + return -ENODEV; + } + + return 0; +} + +const struct edac_device_prv_data l2ecc_data = { + .setup = altr_l2_dependencies, + .ce_clear_mask = 0, + .ue_clear_mask = 0, + .dbgfs_name = "altr_l2_trigger", + .alloc_mem = l2_alloc_mem, + .free_mem = l2_free_mem, + .ecc_enable_mask = ALTR_L2_ECC_EN, + .ce_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJS), + .ue_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJD), + .trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE, +}; + +#endif /* CONFIG_EDAC_ALTERA_L2C */ + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Thor Thayer"); -MODULE_DESCRIPTION("EDAC Driver for Altera SDRAM Controller"); +MODULE_DESCRIPTION("EDAC Driver for Altera Memories");