merge of 425cf1b391611c169a1c3b78f1fe86df088902b9
[vuplus_openembedded] / packages / linux / linux-rp-2.6.18+git / tmio-tc6393-r8.patch
1  arch/arm/common/Kconfig         |    3 
2  arch/arm/common/Makefile        |    1 
3  arch/arm/common/tc6393xb.c      |  668 ++++++++++++++++++++++++++++++++++++++++
4  arch/arm/mach-pxa/Kconfig       |    1 
5  include/asm-arm/arch-pxa/irqs.h |   10 
6  include/asm-arm/hardware/tmio.h |   44 ++
7  6 files changed, 727 insertions(+)
8
9 Index: git/arch/arm/common/tc6393xb.c
10 ===================================================================
11 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
12 +++ git/arch/arm/common/tc6393xb.c      2006-11-07 22:14:49.000000000 +0000
13 @@ -0,0 +1,668 @@
14 +/*
15 + * Toshiba TC6393XB SoC support
16 + *
17 + * Maintainer: Chris Humbert <mahadri-kernel@drigon.com>
18 + *
19 + * Copyright (c) 2005-2006 Chris Humbert
20 + * Copyright (c) 2005 Dirk Opfer
21 + *
22 + * Based on code written by Sharp/Lineo for 2.4 kernels
23 + * Based on locomo.c
24 + *
25 + * This program is free software; you can redistribute it and/or modify
26 + * it under the terms of the GNU General Public License version 2 as
27 + * published by the Free Software Foundation.
28 + */
29 +
30 +#include <linux/module.h>
31 +#include <linux/init.h>
32 +#include <linux/kernel.h>
33 +#include <linux/delay.h>
34 +#include <linux/errno.h>
35 +#include <linux/ioport.h>
36 +#include <linux/device.h>
37 +#include <linux/platform_device.h>
38 +#include <linux/slab.h>
39 +#include <linux/spinlock.h>
40 +#include <linux/fb.h>
41 +
42 +#include <asm/hardware.h>
43 +#include <asm/mach-types.h>
44 +#include <asm/io.h>
45 +#include <asm/irq.h>
46 +#include <asm/mach/irq.h>
47 +#include <asm/arch/irqs.h>
48 +#include <asm/hardware/tmio.h>
49 +
50 +#ifndef TMIO_SOC_TC6393XB
51 +#error "TC6393XB SoC not configured"
52 +#endif
53 +
54 +/*--------------------------------------------------------------------------*/
55 +
56 +/* cell ids must be 0-based because they are used as array indexes. */
57 +#define        TC6393_CELL_NAND        0
58 +#define TC6393_CELL_SD         1
59 +#define        TC6393_CELL_OHCI        2
60 +#define TC6393_CELL_SERIAL     3
61 +#define TC6393_CELL_LCD                4
62 +#define TC6393_NUM_CELLS       5
63 +
64 +#define TC6393_RESOURCE(_name, _start, _end, _flags)   \
65 +       {                                               \
66 +               .name           = _name,                \
67 +               .start          = _start,               \
68 +               .end            = _end,                 \
69 +               .flags          = _flags,               \
70 +       }
71 +
72 +#define TC6393_MEM(name, start, size)  \
73 +       TC6393_RESOURCE(name, start, (start) + (size) - 1, IORESOURCE_MEM)
74 +
75 +#define TC6393_IRQ(name, irq)  \
76 +       TC6393_RESOURCE(name, irq, irq, IORESOURCE_IRQ)
77 +
78 +const static struct resource tc6393_NAND_resource[] = {
79 +       TC6393_MEM (TMIO_NAME_NAND,     0x000100,       0x100),
80 +       TC6393_MEM (TMIO_NAME_NAND,     0x001000,       0x008),
81 +       TC6393_MEM (TMIO_NAME_NAND,     0,              0),
82 +       TC6393_IRQ (TMIO_NAME_NAND,     IRQ_TC6393_NAND),
83 +};
84 +
85 +const static struct resource tc6393_SD_resource[] = {
86 +       TC6393_MEM (TMIO_NAME_SD,       0x000200,       0x100),
87 +       TC6393_MEM (TMIO_NAME_SD,       0x002000,       0x200),
88 +       TC6393_MEM (TMIO_NAME_SD,       0,              0),
89 +       TC6393_IRQ (TMIO_NAME_SD,       IRQ_TC6393_SD),
90 +};
91 +
92 +const static struct resource tc6393_OHCI_resource[] = {
93 +       TC6393_MEM (TMIO_NAME_OHCI,     0x000300,       0x100),
94 +       TC6393_MEM (TMIO_NAME_OHCI,     0x003000,       0x100),
95 +       TC6393_MEM (TMIO_NAME_OHCI,     0x010000,       32 * 1024),
96 +       TC6393_IRQ (TMIO_NAME_OHCI,     IRQ_TC6393_OHCI),
97 +};
98 +
99 +const static struct resource tc6393_SERIAL_resource[] = {
100 +       TC6393_MEM (TMIO_NAME_SERIAL,   0x000400,       0x100),
101 +       TC6393_MEM (TMIO_NAME_SERIAL,   0x004000,       0x100),
102 +       TC6393_MEM (TMIO_NAME_SERIAL,   0,              0),
103 +       TC6393_IRQ (TMIO_NAME_SERIAL,   IRQ_TC6393_SERIAL),
104 +};
105 +
106 +const static struct resource tc6393_LCD_resource[] = {
107 +       TC6393_MEM (TMIO_NAME_LCD,      0x000500,       0x100),
108 +       TC6393_MEM (TMIO_NAME_LCD,      0x005000,       0x200),
109 +       TC6393_MEM (TMIO_NAME_LCD,      0x100000,       1024 * 1024),
110 +       TC6393_IRQ (TMIO_NAME_LCD,      IRQ_TC6393_LCD),
111 +};
112 +
113 +#define TC6393_CELL(_NAME)                                             \
114 +       [TC6393_CELL_##_NAME] = {                                       \
115 +               .name           = TMIO_NAME_##_NAME,                    \
116 +               .id             = TC6393_CELL_##_NAME,                  \
117 +               .resource       = tc6393_##_NAME##_resource,            \
118 +               .num_resources  = ARRAY_SIZE (tc6393_##_NAME##_resource), \
119 +       }
120 +
121 +struct tc6393_cell {
122 +       const char*             name;
123 +       unsigned int            id;
124 +       const struct resource*  resource;
125 +       unsigned int            num_resources;
126 +};
127 +
128 +const static struct tc6393_cell tc6393_cell [TC6393_NUM_CELLS] = {
129 +       TC6393_CELL (NAND       ),
130 +       TC6393_CELL (SD         ),
131 +       TC6393_CELL (OHCI       ),
132 +       TC6393_CELL (SERIAL     ),
133 +       TC6393_CELL (LCD        ),
134 +};
135 +
136 +/*--------------------------------------------------------------------------*/
137 +
138 +/*
139 + * TC6393 System Configuration Register
140 + */
141 +struct tc6393_scr {
142 +       u8 x00[8];
143 +       u8      revid;          /* 0x08 Revision ID                     */
144 +       u8 x01[0x47];
145 +       u8      isr;            /* 0x50 Interrupt Status                */
146 +       u8 x02;
147 +       u8      imr;            /* 0x52 Interrupt Mask                  */
148 +       u8 x03;
149 +       u8      irr;            /* 0x54 Interrupt Routing               */
150 +       u8 x04[0x0b];
151 +       u16     gper;           /* 0x60 GP Enable                       */
152 +       u8 x05[2];
153 +       u16     gpi_sr[2];      /* 0x64 GPI Status                      */
154 +       u16     gpi_imr[2];     /* 0x68 GPI INT Mask                    */
155 +       u16     gpi_eder[2];    /* 0x6c GPI Edge Detect Enable          */
156 +       u16     gpi_lir[4];     /* 0x70 GPI Level Invert                */
157 +       u16     gpo_dsr[2];     /* 0x78 GPO Data Set                    */
158 +       u16     gpo_doecr[2];   /* 0x7c GPO Data OE Control             */
159 +       u16     gp_iarcr[2];    /* 0x80 GP Internal Active Reg Control  */
160 +       u16     gp_iarlcr[2];   /* 0x84 GP Internal Active Reg Level Con*/
161 +       u8      gpi_bcr[4];     /* 0x88 GPI Buffer Control              */
162 +       u16     gpa_iarcr;      /* 0x8c GPa Internal Active Reg Control */
163 +       u8 x06[2];
164 +       u16     gpa_iarlcr;     /* 0x90 GPa Internal Active Reg Level Co*/
165 +       u8 x07[2];
166 +       u16     gpa_bcr;        /* 0x94 GPa Buffer Control              */
167 +       u8 x08[2];
168 +       u16     ccr;            /* 0x98 Clock Control                   */
169 +       u16     pll2cr;         /* 0x9a PLL2 Control                    */
170 +       u16     pll1cr[2];      /* 0x9c PLL1 Control                    */
171 +       u8      diarcr;         /* 0xa0 Device Internal Active Reg Contr*/
172 +       u8      dbocr;          /* 0xa1 Device Buffer Off Control       */
173 +       u8 x09[0x3e];
174 +       u8      fer;            /* 0xe0 Function Enable                 */
175 +       u8 x10[3];
176 +       u16     mcr;            /* 0xe4 Mode Control                    */
177 +       u8 x11[0x14];
178 +       u8      config;         /* 0xfc Configuration Control           */
179 +       u8 x12[2];
180 +       u8      debug;          /* 0xff Debug                           */
181 +} __attribute__ ((packed));
182 +
183 +union tc6393_scr_fer {
184 +       u8              raw;
185 +struct {
186 +       unsigned        usben:1;        /* D0   USB enable              */
187 +       unsigned        lcdcven:1;      /* D1   polysylicon TFT enable  */
188 +       unsigned        slcden:1;       /* D2   SLCD enable             */
189 +} __attribute__ ((packed));
190 +} __attribute__ ((packed));
191 +
192 +union tc6393_scr_ccr {
193 +       u16             raw;
194 +struct {
195 +       unsigned        ck32ken:1;      /* D0   SD host clock enable    */
196 +       unsigned        usbcken:1;      /* D1   USB host clock enable   */
197 +       unsigned        x00:2;
198 +       unsigned        sharp:1;        /* D4   ??? set in Sharp's code */
199 +       unsigned        x01:3;
200 +       enum {                          disable = 0,
201 +                                       m12MHz  = 1,
202 +                                       m24MHz  = 2,
203 +                                       m48MHz  = 3,
204 +       }               mclksel:3;      /* D10-D8  LCD controller clock */
205 +       unsigned        x02:1;
206 +       enum {                          h24MHz  = 0,
207 +                                       h48MHz  = 1,
208 +       }               hclksel:2;      /* D13-D12 host bus clock       */
209 +       unsigned        x03:2;
210 +} __attribute__ ((packed));
211 +} __attribute__ ((packed));
212 +
213 +/*--------------------------------------------------------------------------*/
214 +
215 +struct tc6393 {
216 +       spinlock_t              lock;   /* read-modify-write lock       */
217 +       struct device*          dev;    /* TC6393 device                */
218 +       struct tc6393_scr __iomem *scr; /* system configuration reg     */
219 +
220 +       struct resource         rscr;   /* system config reg resource   */
221 +       struct resource*        iomem;  /* entire TC6393 iomem resource */
222 +       unsigned int            irq;    /* hardware cascade irq         */
223 +
224 +       struct tmio_device      tdev [TC6393_NUM_CELLS];
225 +};
226 +
227 +/*--------------------------------------------------------------------------*/
228 +
229 +static u32 tc6393_ioread32 (const void __iomem *addr)
230 +{
231 +       return ((u32) ioread16 (addr)) | (((u32) ioread16 (addr + 2)) << 16);
232 +}
233 +
234 +static u32 tc6393_iowrite32 (u32 val, const void __iomem *addr)
235 +{
236 +       iowrite16 (val,         addr);
237 +       iowrite16 (val >> 16,   addr + 2);
238 +       return val;
239 +}
240 +
241 +u32 get_tc6393_gpio (struct device *dev)
242 +{
243 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev);
244 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
245 +
246 +       return tc6393_ioread32 (scr->gpo_dsr);
247 +}
248 +EXPORT_SYMBOL (get_tc6393_gpio);
249 +
250 +u32 set_tc6393_gpio (struct device *dev, u32 bits)
251 +{
252 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev);
253 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
254 +       unsigned long                   flags;
255 +       u32                             dsr;
256 +
257 +       spin_lock_irqsave (&tc6393->lock, flags);
258 +       dsr = tc6393_ioread32 (scr->gpo_dsr) | bits;
259 +       tc6393_iowrite32 (dsr, scr->gpo_dsr);
260 +       spin_unlock_irqrestore (&tc6393->lock, flags);
261 +
262 +       return dsr;
263 +}
264 +EXPORT_SYMBOL (set_tc6393_gpio);
265 +
266 +u32 reset_tc6393_gpio (struct device *dev, u32 bits)
267 +{
268 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev);
269 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
270 +       unsigned long                   flags;
271 +       u32                             dsr;
272 +
273 +       spin_lock_irqsave (&tc6393->lock, flags);
274 +       dsr = tc6393_ioread32 (scr->gpo_dsr) & ~bits;
275 +       tc6393_iowrite32 (dsr, scr->gpo_dsr);
276 +       spin_unlock_irqrestore (&tc6393->lock, flags);
277 +
278 +       return dsr;
279 +}
280 +EXPORT_SYMBOL (reset_tc6393_gpio);
281 +
282 +/*--------------------------------------------------------------------------*/
283 +
284 +static void
285 +tc6393_irq (unsigned int irq, struct irqdesc *desc)
286 +{
287 +       struct tc6393*                  tc6393  = get_irq_chipdata (irq);
288 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
289 +       unsigned int                    isr;
290 +       unsigned int                    bit;
291 +       unsigned int                    i;
292 +
293 +       desc->chip->ack (irq);
294 +
295 +       while ((isr = ioread8(&scr->isr) & ~ioread8(&scr->imr)))
296 +               for (bit = 1, i = IRQ_TC6393_START; i <= IRQ_TC6393_LCD;
297 +                                                               bit <<= 1, i++)
298 +                       if (isr & bit)
299 +                               desc_handle_irq (i, irq_desc + i);
300 +}
301 +
302 +static void tc6393_irq_ack (unsigned int irq)
303 +{
304 +}
305 +
306 +static void tc6393_irq_mask (unsigned int irq)
307 +{
308 +       struct tc6393*                  tc6393  = get_irq_chipdata (irq);
309 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
310 +       unsigned long                   flags;
311 +
312 +       spin_lock_irqsave (&tc6393->lock, flags);
313 +       iowrite8 (ioread8 (&scr->imr) | (1 << (irq - IRQ_TC6393_START)),
314 +                                                               &scr->imr);
315 +       spin_unlock_irqrestore (&tc6393->lock, flags);
316 +}
317 +
318 +static void tc6393_irq_unmask (unsigned int irq)
319 +{
320 +       struct tc6393*                  tc6393  = get_irq_chipdata (irq);
321 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
322 +       unsigned long                   flags;
323 +
324 +       spin_lock_irqsave (&tc6393->lock, flags);
325 +       iowrite8 (ioread8 (&scr->imr) & ~(1 << (irq - IRQ_TC6393_START)),
326 +                                                               &scr->imr);
327 +       spin_unlock_irqrestore (&tc6393->lock, flags);
328 +}
329 +
330 +static struct irqchip tc6393_chip = {
331 +       .ack    = tc6393_irq_ack,
332 +       .mask   = tc6393_irq_mask,
333 +       .unmask = tc6393_irq_unmask,
334 +};
335 +
336 +static void tc6393_attach_irq (struct tc6393 *tc6393)
337 +{
338 +       unsigned int            irq;
339 +
340 +       for (irq = IRQ_TC6393_START; irq <= IRQ_TC6393_LCD; irq++) {
341 +               set_irq_chip    (irq, &tc6393_chip);
342 +               set_irq_chipdata(irq, tc6393);
343 +               set_irq_handler (irq, do_edge_IRQ);
344 +               set_irq_flags   (irq, IRQF_VALID | IRQF_PROBE);
345 +       }
346 +
347 +       set_irq_type            (tc6393->irq, IRQT_FALLING);
348 +       set_irq_chipdata        (tc6393->irq, tc6393);
349 +       set_irq_chained_handler (tc6393->irq, tc6393_irq);
350 +}
351 +
352 +static void tc6393_detach_irq (struct tc6393 *tc6393)
353 +{
354 +       unsigned int            irq;
355 +
356 +       set_irq_chained_handler (tc6393->irq, NULL);
357 +       set_irq_chipdata        (tc6393->irq, NULL);
358 +
359 +       for (irq = IRQ_TC6393_START; irq <= IRQ_TC6393_LCD; irq++) {
360 +               set_irq_flags   (irq, 0);
361 +               set_irq_chip    (irq, NULL);
362 +               set_irq_chipdata(irq, NULL);
363 +       }
364 +}
365 +
366 +/*--------------------------------------------------------------------------*/
367 +
368 +static int tc6393_bus_match (struct device *dev, struct device_driver *drv)
369 +{
370 +       struct tmio_device*             tdev    = dev_to_tdev (dev);
371 +       const struct tc6393_cell*       cell    = tdev->soc_data;
372 +
373 +       return !strcmp (cell->name, drv->name);
374 +}
375 +
376 +static int tc6393_bus_suspend (struct device *dev, pm_message_t state)
377 +{
378 +       struct device_driver*   drv     = dev->driver;
379 +       return drv && drv->suspend ? drv->suspend (dev, state) : 0;
380 +}
381 +
382 +static int tc6393_bus_resume (struct device *dev)
383 +{
384 +       struct device_driver*   drv     = dev->driver;
385 +       return drv && drv->resume ? drv->resume (dev) : 0;
386 +}
387 +
388 +struct bus_type tc6393_bus_type = {
389 +       .name           = TMIO_NAME_BUS,
390 +       .match          = tc6393_bus_match,
391 +       .suspend        = tc6393_bus_suspend,
392 +       .resume         = tc6393_bus_resume,
393 +};
394 +EXPORT_SYMBOL (tc6393_bus_type);
395 +
396 +/*--------------------------------------------------------------------------*/
397 +
398 +static void tc6393_cell_clock (struct device *dev, int enable)
399 +{
400 +       struct tmio_device*             tdev    = dev_to_tdev (dev);
401 +       const struct tc6393_cell*       cell    = tdev->soc_data;
402 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev->parent);
403 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
404 +       union tc6393_scr_ccr            ccr;
405 +       unsigned long                   flags;
406 +
407 +       spin_lock_irqsave (&tc6393->lock, flags);
408 +       ccr.raw = ioread16 (&scr->ccr);
409 +
410 +       switch (cell->id) {
411 +               case TC6393_CELL_SD:    ccr.ck32ken     = enable;       break;
412 +               case TC6393_CELL_OHCI:  ccr.usbcken     = enable;       break;
413 +               case TC6393_CELL_LCD:
414 +                       ccr.mclksel = enable ? m48MHz : disable;
415 +                       break;
416 +       }
417 +
418 +       printk (KERN_DEBUG TMIO_NAME_CORE ": scr->ccr = %04x\n", ccr.raw);
419 +
420 +       iowrite16(ccr.raw, &scr->ccr);
421 +       spin_unlock_irqrestore (&tc6393->lock, flags);
422 +}
423 +
424 +static void tc6393_cell_function (struct device *dev, int enable)
425 +{
426 +       struct tmio_device*             tdev    = dev_to_tdev (dev);
427 +       const struct tc6393_cell*       cell    = tdev->soc_data;
428 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev->parent);
429 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
430 +       union tc6393_scr_fer            fer;
431 +       unsigned long                   flags;
432 +
433 +       if (cell->id == TC6393_CELL_NAND) {
434 +               if (enable) {
435 +                       /* SMD buffer on */
436 +                       printk (KERN_DEBUG TMIO_NAME_CORE ": SMD buffer on\n");
437 +                       iowrite8 (0xff, scr->gpi_bcr + 1);
438 +               }
439 +               return;
440 +       }
441 +
442 +       spin_lock_irqsave (&tc6393->lock, flags);
443 +       fer.raw = ioread16 (&scr->fer);
444 +
445 +       switch (cell->id) {
446 +               case TC6393_CELL_OHCI:  fer.usben       = enable;       break;
447 +               case TC6393_CELL_LCD:   fer.slcden      = enable;       break;
448 +       }
449 +
450 +       printk (KERN_DEBUG TMIO_NAME_CORE ": scr->fer = %02x\n", fer.raw);
451 +
452 +       iowrite8 (fer.raw, &scr->fer);
453 +       spin_unlock_irqrestore (&tc6393->lock, flags);
454 +}
455 +
456 +static void
457 +tc6393_lcd_mode (struct device *dev, const struct fb_videomode *mode)
458 +{
459 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev->parent);
460 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
461 +
462 +       iowrite16 (mode->pixclock,              scr->pll1cr + 0);
463 +       iowrite16 (mode->pixclock >> 16,        scr->pll1cr + 1);
464 +}
465 +
466 +static struct tmio_cell_ops tc6393_cell_ops = {
467 +       .clock          = tc6393_cell_clock,
468 +       .function       = tc6393_cell_function,
469 +       .lcd_mode       = tc6393_lcd_mode,
470 +};
471 +
472 +static void tc6393_device_release (struct device *dev)
473 +{
474 +}
475 +
476 +static int
477 +tc6393_device_register (struct tc6393 *tc6393, struct tmio_cell *tcell)
478 +{
479 +       const struct tc6393_cell*       cell;
480 +       struct tmio_device*             tdev;
481 +       struct device*                  dev;
482 +       int                             i;
483 +
484 +       for (i = 0; strcmp (tcell->name, tc6393_cell [i].name); )
485 +               if (++i >= ARRAY_SIZE(tc6393_cell))
486 +                       return -EINVAL;
487 +
488 +       cell                    = tc6393_cell  + i;
489 +       tdev                    = tc6393->tdev + i;
490 +       dev                     = &tdev->dev;
491 +
492 +       tdev->ops               = &tc6393_cell_ops;
493 +       tdev->iomem             = tc6393->iomem;
494 +       tdev->soc_data          = (void*) cell;
495 +
496 +       dev->parent             = tc6393->dev;
497 +       strncpy (dev->bus_id, cell->name, sizeof dev->bus_id);
498 +       dev->bus                = &tc6393_bus_type;
499 +       dev->dma_mask           = tc6393->dev->dma_mask;
500 +       dev->coherent_dma_mask  = tc6393->dev->coherent_dma_mask;
501 +       dev->release            = tc6393_device_release;
502 +       dev->platform_data      = tcell->platform_data;
503 +
504 +       for (i=0; i < cell->num_resources; i++) {
505 +               const struct resource*  cr      = cell->resource + i;
506 +               struct resource*        dr      = tdev->resource + i;
507 +
508 +               dr->name        = cr->name;
509 +               dr->start       = cr->start;
510 +               dr->end         = cr->end;
511 +               dr->flags       = cr->flags;
512 +
513 +               /* convert memory offsets to absolutes */
514 +               if (cr->flags & IORESOURCE_MEM) {
515 +                       dr->start       += tc6393->iomem->start;
516 +                       dr->end         += tc6393->iomem->start;
517 +               }
518 +       }
519 +
520 +       return device_register (dev);
521 +}
522 +
523 +/*--------------------------------------------------------------------------*/
524 +
525 +static void tc6393_hw_init (struct tc6393 *tc6393)
526 +{
527 +       struct tc6393_scr __iomem *     scr     = tc6393->scr;
528 +       struct tc6393_platform_data*    tcpd    = tc6393->dev->platform_data;
529 +
530 +       tcpd->enable (tc6393->dev);
531 +
532 +       iowrite8 (0,                            &scr->fer);
533 +       iowrite16(tcpd->scr_pll2cr,             &scr->pll2cr);
534 +       iowrite16(tcpd->scr_ccr,                &scr->ccr);
535 +       iowrite16(tcpd->scr_mcr,                &scr->mcr);
536 +       iowrite16(tcpd->scr_gper,               &scr->gper);
537 +       iowrite8 (0,                            &scr->irr);
538 +       iowrite8 (0xbf,                         &scr->imr);
539 +       iowrite16(tcpd->scr_gpo_dsr,            scr->gpo_dsr + 0);
540 +       iowrite16(tcpd->scr_gpo_dsr >> 16,      scr->gpo_dsr + 1);
541 +       iowrite16(tcpd->scr_gpo_doecr,          scr->gpo_doecr + 0);
542 +       iowrite16(tcpd->scr_gpo_doecr >> 16,    scr->gpo_doecr + 1);
543 +}
544 +
545 +static int tc6393_probe (struct device *dev)
546 +{
547 +       struct platform_device*         pdev    = to_platform_device (dev);
548 +       struct tc6393_platform_data*    tcpd    = dev->platform_data;
549 +       struct tc6393*                  tc6393;
550 +       struct resource*                iomem;
551 +       struct resource*                rscr;
552 +       int                             retval;
553 +       int                             i;
554 +
555 +       iomem = platform_get_resource (pdev, IORESOURCE_MEM, 0);
556 +       if (!iomem)
557 +               return -EINVAL;
558 +
559 +       tc6393 = kzalloc (sizeof *tc6393, GFP_KERNEL);
560 +       if (!tc6393) {
561 +               retval = -ENOMEM;
562 +               goto err_kzalloc;
563 +       }
564 +
565 +       dev_set_drvdata (dev, tc6393);
566 +       spin_lock_init (&tc6393->lock);
567 +       tc6393->dev     = dev;
568 +       tc6393->iomem   = iomem;
569 +       tc6393->irq     = platform_get_irq (pdev, 0);
570 +
571 +       rscr            = &tc6393->rscr;
572 +       rscr->name      = TMIO_NAME_CORE;
573 +       rscr->start     = iomem->start;
574 +       rscr->end       = iomem->start + 0xff;
575 +       rscr->flags     = IORESOURCE_MEM;
576 +
577 +       retval = request_resource (iomem, rscr);
578 +       if (retval)
579 +               goto err_request_scr;
580 +
581 +       tc6393->scr     = ioremap (rscr->start, rscr->end - rscr->start + 1);
582 +       if (!tc6393->scr) {
583 +               retval = -ENOMEM;
584 +               goto err_ioremap;
585 +       }
586 +
587 +       tc6393_hw_init (tc6393);
588 +
589 +       printk (KERN_INFO "Toshiba %s revision %d at 0x%08lx, irq %d\n",
590 +                       TMIO_SOC_NAME, ioread8 (&tc6393->scr->revid),
591 +                       iomem->start, tc6393->irq);
592 +
593 +       if (tc6393->irq)
594 +               tc6393_attach_irq (tc6393);
595 +
596 +       for (i = 0; i < tcpd->num_cells; i++)
597 +               tc6393_device_register (tc6393, tcpd->cell + i);
598 +
599 +       return 0;
600 +
601 +err_ioremap:
602 +       release_resource (rscr);
603 +err_request_scr:
604 +       kfree(tc6393);
605 +err_kzalloc:
606 +       release_resource (iomem);
607 +       return retval;
608 +}
609 +
610 +static int tc6393_dev_remove (struct device *dev, void *data)
611 +{
612 +       device_unregister (dev);
613 +       return 0;
614 +}
615 +
616 +static int tc6393_remove (struct device *dev)
617 +{
618 +       struct tc6393*          tc6393  = dev_get_drvdata (dev);
619 +
620 +       device_for_each_child (dev, tc6393, tc6393_dev_remove);
621 +
622 +       if (tc6393->irq)
623 +               tc6393_detach_irq (tc6393);
624 +
625 +       iounmap (tc6393->scr);
626 +       release_resource (&tc6393->rscr);
627 +       release_resource (tc6393->iomem);
628 +       kfree (tc6393);
629 +       return 0;
630 +}
631 +
632 +#ifdef CONFIG_PM
633 +static int tc6393_suspend (struct device *dev, pm_message_t state)
634 +{
635 +       struct tc6393_platform_data*    tcpd    = dev->platform_data;
636 +       tcpd->disable (dev);
637 +       return 0;
638 +}
639 +
640 +static int tc6393_resume (struct device *dev)
641 +{
642 +       struct tc6393*                  tc6393  = dev_get_drvdata (dev);
643 +       tc6393_hw_init (tc6393);
644 +       return 0;
645 +}
646 +#endif
647 +
648 +static struct device_driver tc6393_device_driver = {
649 +       .name           = TMIO_SOC_NAME,
650 +       .bus            = &platform_bus_type,
651 +       .probe          = tc6393_probe,
652 +       .remove         = tc6393_remove,
653 +#ifdef CONFIG_PM
654 +       .suspend        = tc6393_suspend,
655 +       .resume         = tc6393_resume,
656 +#endif
657 +};
658 +
659 +/*--------------------------------------------------------------------------*/
660 +
661 +static int __init tc6393_init (void)
662 +{
663 +       int retval = bus_register (&tc6393_bus_type);
664 +       if (retval)
665 +               return retval;
666 +
667 +       return driver_register (&tc6393_device_driver);
668 +}
669 +
670 +static void __exit tc6393_exit (void)
671 +{
672 +       driver_unregister (&tc6393_device_driver);
673 +       bus_unregister (&tc6393_bus_type);
674 +}
675 +
676 +module_init (tc6393_init);
677 +module_exit (tc6393_exit);
678 +
679 +MODULE_DESCRIPTION ("TC6393 SoC bus driver");
680 +MODULE_AUTHOR ("Chris Humbert, Dirk Opfer");
681 +MODULE_LICENSE ("GPL");
682 Index: git/arch/arm/common/Kconfig
683 ===================================================================
684 --- git.orig/arch/arm/common/Kconfig    2006-10-31 16:08:28.000000000 +0000
685 +++ git/arch/arm/common/Kconfig 2006-11-07 22:13:09.000000000 +0000
686 @@ -31,3 +31,6 @@ config SHARPSL_PM
687  
688  config SHARP_SCOOP
689         bool
690 +
691 +config TOSHIBA_TC6393XB
692 +       bool
693 Index: git/arch/arm/mach-pxa/Kconfig
694 ===================================================================
695 --- git.orig/arch/arm/mach-pxa/Kconfig  2006-11-07 22:13:06.000000000 +0000
696 +++ git/arch/arm/mach-pxa/Kconfig       2006-11-07 23:30:34.000000000 +0000
697 @@ -128,6 +128,7 @@ config MACH_BORZOI
698  config MACH_TOSA
699         bool "Enable Sharp SL-6000x (Tosa) Support"
700         depends PXA_SHARPSL_25x
701 +       select TOSHIBA_TC6393XB
702  
703  config PXA25x
704         bool
705 Index: git/arch/arm/common/Makefile
706 ===================================================================
707 --- git.orig/arch/arm/common/Makefile   2006-10-31 16:08:28.000000000 +0000
708 +++ git/arch/arm/common/Makefile        2006-11-07 22:13:09.000000000 +0000
709 @@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM)      += sharpsl_pm.o
710  obj-$(CONFIG_SHARP_SCOOP)      += scoop.o
711  obj-$(CONFIG_ARCH_IXP2000)     += uengine.o
712  obj-$(CONFIG_ARCH_IXP23XX)     += uengine.o
713 +obj-$(CONFIG_TOSHIBA_TC6393XB) += tc6393xb.o
714 Index: git/include/asm-arm/hardware/tmio.h
715 ===================================================================
716 --- git.orig/include/asm-arm/hardware/tmio.h    2006-11-07 22:13:09.000000000 +0000
717 +++ git/include/asm-arm/hardware/tmio.h 2006-11-07 22:13:09.000000000 +0000
718 @@ -91,6 +91,50 @@ struct tmio_device {
719  
720  /*--------------------------------------------------------------------------*/
721  
722 +/*
723 + * TC6393XB SoC
724 + */
725 +#ifdef CONFIG_TOSHIBA_TC6393XB
726 +#define TMIO_SOC_TC6393XB
727 +#define TMIO_SOC_NAME                  "TC6393XB"
728 +#define TMIO_NAME_BUS                  "tc6393-bus"
729 +#define TMIO_NAME_CORE                 "tc6393-core"
730 +#define TMIO_NAME_NAND                 "tc6393-nand"
731 +#define TMIO_NAME_SD                   "tc6393-sd"
732 +#define TMIO_NAME_OHCI                 "tc6393-ohci"
733 +#define TMIO_NAME_SERIAL               "tc6393-serial"
734 +#define TMIO_NAME_LCD                  "tc6393-lcd"
735 +#define tmio_bus_type                  tc6393_bus_type
736 +
737 +#define TC6393_GPIO(x)                 (1 << (x))
738 +
739 +extern struct bus_type tc6393_bus_type;
740 +
741 +struct tc6393_platform_data {
742 +       u16     scr_pll2cr;             /* PLL2 Control                 */
743 +       u16     scr_ccr;                /* Clock Control                */
744 +       u16     scr_mcr;                /* Mode Control                 */
745 +       u16     scr_gper;               /* GP Enable                    */
746 +       u32     scr_gpo_doecr;          /* GPO Data OE Control          */
747 +       u32     scr_gpo_dsr;            /* GPO Data Set                 */
748 +
749 +       /* cells to register as devices */
750 +       struct tmio_cell*               cell;
751 +       unsigned int                    num_cells;
752 +
753 +       /* callbacks to enable and disable the TC6393XB's power and clock */
754 +       void (*enable)  (struct device *dev);
755 +       void (*disable) (struct device *dev);
756 +};
757 +
758 +u32    get_tc6393_gpio         (struct device *dev);
759 +u32    set_tc6393_gpio         (struct device *dev, u32 bits);
760 +u32    reset_tc6393_gpio       (struct device *dev, u32 bits);
761 +
762 +/*--------------------------------------------------------------------------*/
763 +
764 +#else
765  #error "no TMIO SoC configured"
766 +#endif
767  
768  #endif
769 Index: git/include/asm-arm/arch-pxa/irqs.h
770 ===================================================================
771 --- git.orig/include/asm-arm/arch-pxa/irqs.h    2006-10-31 16:09:33.000000000 +0000
772 +++ git/include/asm-arm/arch-pxa/irqs.h 2006-11-07 22:13:09.000000000 +0000
773 @@ -163,17 +163,27 @@
774  #define IRQ_LOCOMO_SPI_OVRN    (IRQ_BOARD_END + 20)
775  #define IRQ_LOCOMO_SPI_TEND    (IRQ_BOARD_END + 21)
776  
777 +#define IRQ_TC6393_START       (IRQ_BOARD_END)
778 +#define IRQ_TC6393_NAND                (IRQ_BOARD_END + 0)
779 +#define IRQ_TC6393_SD          (IRQ_BOARD_END + 1)
780 +#define IRQ_TC6393_OHCI                (IRQ_BOARD_END + 2)
781 +#define IRQ_TC6393_SERIAL      (IRQ_BOARD_END + 3)
782 +#define IRQ_TC6393_LCD         (IRQ_BOARD_END + 4)
783 +
784  /*
785   * Figure out the MAX IRQ number.
786   *
787   * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
788   * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
789 + * If we have an TC6393XB, the max IRQ is IRQ_TC6393_LCD+1
790   * Otherwise, we have the standard IRQs only.
791   */
792  #ifdef CONFIG_SA1111
793  #define NR_IRQS                        (IRQ_S1_BVD1_STSCHG + 1)
794  #elif defined(CONFIG_SHARP_LOCOMO)
795  #define NR_IRQS                        (IRQ_LOCOMO_SPI_TEND + 1)
796 +#elif defined(CONFIG_TOSHIBA_TC6393XB)
797 +#define NR_IRQS                        (IRQ_TC6393_LCD + 1)
798  #elif defined(CONFIG_ARCH_LUBBOCK) || \
799        defined(CONFIG_MACH_LOGICPD_PXA270) || \
800        defined(CONFIG_MACH_MAINSTONE)