~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to arch/arm/mach-omap2/omap_l3_noc.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
  * OMAP4XXX L3 Interconnect error handling driver
3
 
  *
4
 
  * Copyright (C) 2011 Texas Corporation
5
 
  *     Santosh Shilimkar <santosh.shilimkar@ti.com>
6
 
  *     Sricharan <r.sricharan@ti.com>
7
 
  *
8
 
  * This program is free software; you can redistribute it and/or modify
9
 
  * it under the terms of the GNU General Public License as published by
10
 
  * the Free Software Foundation; either version 2 of the License, or
11
 
  * (at your option) any later version.
12
 
  *
13
 
  * This program is distributed in the hope that it will be useful,
14
 
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
  * GNU General Public License for more details.
17
 
  *
18
 
  * You should have received a copy of the GNU General Public License
19
 
  * along with this program; if not, write to the Free Software
20
 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21
 
  * USA
22
 
  */
 
2
 * OMAP4XXX L3 Interconnect error handling driver
 
3
 *
 
4
 * Copyright (C) 2011 Texas Corporation
 
5
 *      Santosh Shilimkar <santosh.shilimkar@ti.com>
 
6
 *      Sricharan <r.sricharan@ti.com>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
21
 * USA
 
22
 */
 
23
#include <linux/module.h>
23
24
#include <linux/init.h>
24
25
#include <linux/io.h>
25
26
#include <linux/platform_device.h>
55
56
static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
56
57
{
57
58
 
58
 
        struct omap4_l3         *l3 = _l3;
59
 
        int inttype, i, j;
 
59
        struct omap4_l3 *l3 = _l3;
 
60
        int inttype, i, k;
60
61
        int err_src = 0;
61
 
        u32 std_err_main_addr, std_err_main, err_reg;
62
 
        u32 base, slave_addr, clear;
63
 
        char *source_name;
 
62
        u32 std_err_main, err_reg, clear, masterid;
 
63
        void __iomem *base, *l3_targ_base;
 
64
        char *target_name, *master_name = "UN IDENTIFIED";
64
65
 
65
66
        /* Get the Type of interrupt */
66
67
        inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
70
71
                 * Read the regerr register of the clock domain
71
72
                 * to determine the source
72
73
                 */
73
 
                base = (u32)l3->l3_base[i];
74
 
                err_reg =  readl(base + l3_flagmux[i] + (inttype << 3));
 
74
                base = l3->l3_base[i];
 
75
                err_reg = __raw_readl(base + l3_flagmux[i] +
 
76
                                        + L3_FLAGMUX_REGERR0 + (inttype << 3));
75
77
 
76
78
                /* Get the corresponding error and analyse */
77
79
                if (err_reg) {
78
80
                        /* Identify the source from control status register */
79
 
                        for (j = 0; !(err_reg & (1 << j)); j++)
80
 
                                                                        ;
 
81
                        err_src = __ffs(err_reg);
81
82
 
82
 
                        err_src = j;
83
83
                        /* Read the stderrlog_main_source from clk domain */
84
 
                        std_err_main_addr = base + *(l3_targ[i] + err_src);
85
 
                        std_err_main = readl(std_err_main_addr);
 
84
                        l3_targ_base = base + *(l3_targ[i] + err_src);
 
85
                        std_err_main =  __raw_readl(l3_targ_base +
 
86
                                        L3_TARG_STDERRLOG_MAIN);
 
87
                        masterid = __raw_readl(l3_targ_base +
 
88
                                        L3_TARG_STDERRLOG_MSTADDR);
86
89
 
87
90
                        switch (std_err_main & CUSTOM_ERROR) {
88
91
                        case STANDARD_ERROR:
89
 
                                source_name =
90
 
                                l3_targ_stderrlog_main_name[i][err_src];
91
 
 
92
 
                                slave_addr = std_err_main_addr +
93
 
                                                L3_SLAVE_ADDRESS_OFFSET;
94
 
                                WARN(true, "L3 standard error: SOURCE:%s at address 0x%x\n",
95
 
                                        source_name, readl(slave_addr));
 
92
                                target_name =
 
93
                                        l3_targ_inst_name[i][err_src];
 
94
                                WARN(true, "L3 standard error: TARGET:%s at address 0x%x\n",
 
95
                                        target_name,
 
96
                                        __raw_readl(l3_targ_base +
 
97
                                                L3_TARG_STDERRLOG_SLVOFSLSB));
96
98
                                /* clear the std error log*/
97
99
                                clear = std_err_main | CLEAR_STDERR_LOG;
98
 
                                writel(clear, std_err_main_addr);
 
100
                                writel(clear, l3_targ_base +
 
101
                                        L3_TARG_STDERRLOG_MAIN);
99
102
                                break;
100
103
 
101
104
                        case CUSTOM_ERROR:
102
 
                                source_name =
103
 
                                l3_targ_stderrlog_main_name[i][err_src];
104
 
 
105
 
                                WARN(true, "CUSTOM SRESP error with SOURCE:%s\n",
106
 
                                                        source_name);
 
105
                                target_name =
 
106
                                        l3_targ_inst_name[i][err_src];
 
107
                                for (k = 0; k < NUM_OF_L3_MASTERS; k++) {
 
108
                                        if (masterid == l3_masters[k].id)
 
109
                                                master_name =
 
110
                                                        l3_masters[k].name;
 
111
                                }
 
112
                                WARN(true, "L3 custom error: MASTER:%s TARGET:%s\n",
 
113
                                        master_name, target_name);
107
114
                                /* clear the std error log*/
108
115
                                clear = std_err_main | CLEAR_STDERR_LOG;
109
 
                                writel(clear, std_err_main_addr);
 
116
                                writel(clear, l3_targ_base +
 
117
                                        L3_TARG_STDERRLOG_MAIN);
110
118
                                break;
111
119
 
112
120
                        default:
120
128
        return IRQ_HANDLED;
121
129
}
122
130
 
123
 
static int __init omap4_l3_probe(struct platform_device *pdev)
 
131
static int __devinit omap4_l3_probe(struct platform_device *pdev)
124
132
{
125
 
        static struct omap4_l3          *l3;
126
 
        struct resource         *res;
127
 
        int                     ret;
128
 
        int                     irq;
 
133
        static struct omap4_l3 *l3;
 
134
        struct resource *res;
 
135
        int ret;
129
136
 
130
137
        l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
131
138
        if (!l3)
177
184
        /*
178
185
         * Setup interrupt Handlers
179
186
         */
180
 
        irq = platform_get_irq(pdev, 0);
181
 
        ret = request_irq(irq,
 
187
        l3->debug_irq = platform_get_irq(pdev, 0);
 
188
        ret = request_irq(l3->debug_irq,
182
189
                        l3_interrupt_handler,
183
190
                        IRQF_DISABLED, "l3-dbg-irq", l3);
184
191
        if (ret) {
185
192
                pr_crit("L3: request_irq failed to register for 0x%x\n",
186
 
                                         OMAP44XX_IRQ_L3_DBG);
 
193
                                                OMAP44XX_IRQ_L3_DBG);
187
194
                goto err3;
188
195
        }
189
 
        l3->debug_irq = irq;
190
196
 
191
 
        irq = platform_get_irq(pdev, 1);
192
 
        ret = request_irq(irq,
 
197
        l3->app_irq = platform_get_irq(pdev, 1);
 
198
        ret = request_irq(l3->app_irq,
193
199
                        l3_interrupt_handler,
194
200
                        IRQF_DISABLED, "l3-app-irq", l3);
195
201
        if (ret) {
196
202
                pr_crit("L3: request_irq failed to register for 0x%x\n",
197
 
                                         OMAP44XX_IRQ_L3_APP);
 
203
                                                OMAP44XX_IRQ_L3_APP);
198
204
                goto err4;
199
205
        }
200
 
        l3->app_irq = irq;
201
206
 
202
207
        return 0;
203
208
 
214
219
        return ret;
215
220
}
216
221
 
217
 
static int __exit omap4_l3_remove(struct platform_device *pdev)
 
222
static int __devexit omap4_l3_remove(struct platform_device *pdev)
218
223
{
219
 
        struct omap4_l3         *l3 = platform_get_drvdata(pdev);
 
224
        struct omap4_l3 *l3 = platform_get_drvdata(pdev);
220
225
 
221
226
        free_irq(l3->app_irq, l3);
222
227
        free_irq(l3->debug_irq, l3);
228
233
        return 0;
229
234
}
230
235
 
 
236
#if defined(CONFIG_OF)
 
237
static const struct of_device_id l3_noc_match[] = {
 
238
        {.compatible = "ti,omap4-l3-noc", },
 
239
        {},
 
240
};
 
241
MODULE_DEVICE_TABLE(of, l3_noc_match);
 
242
#else
 
243
#define l3_noc_match NULL
 
244
#endif
 
245
 
231
246
static struct platform_driver omap4_l3_driver = {
232
 
        .remove         = __exit_p(omap4_l3_remove),
 
247
        .probe          = omap4_l3_probe,
 
248
        .remove         = __devexit_p(omap4_l3_remove),
233
249
        .driver         = {
234
 
        .name           = "omap_l3_noc",
 
250
                .name           = "omap_l3_noc",
 
251
                .owner          = THIS_MODULE,
 
252
                .of_match_table = l3_noc_match,
235
253
        },
236
254
};
237
255
 
238
256
static int __init omap4_l3_init(void)
239
257
{
240
 
        return platform_driver_probe(&omap4_l3_driver, omap4_l3_probe);
 
258
        return platform_driver_register(&omap4_l3_driver);
241
259
}
242
260
postcore_initcall_sync(omap4_l3_init);
243
261