Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tc6393xb.c
Go to the documentation of this file.
1 /*
2  * Toshiba TC6393XB SoC support
3  *
4  * Copyright(c) 2005-2006 Chris Humbert
5  * Copyright(c) 2005 Dirk Opfer
6  * Copyright(c) 2005 Ian Molton <[email protected]>
7  * Copyright(c) 2007 Dmitry Baryshkov
8  *
9  * Based on code written by Sharp/Lineo for 2.4 kernels
10  * Based on locomo.c
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16 
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/io.h>
20 #include <linux/irq.h>
21 #include <linux/platform_device.h>
22 #include <linux/clk.h>
23 #include <linux/err.h>
24 #include <linux/mfd/core.h>
25 #include <linux/mfd/tmio.h>
26 #include <linux/mfd/tc6393xb.h>
27 #include <linux/gpio.h>
28 #include <linux/slab.h>
29 
30 #define SCR_REVID 0x08 /* b Revision ID */
31 #define SCR_ISR 0x50 /* b Interrupt Status */
32 #define SCR_IMR 0x52 /* b Interrupt Mask */
33 #define SCR_IRR 0x54 /* b Interrupt Routing */
34 #define SCR_GPER 0x60 /* w GP Enable */
35 #define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */
36 #define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */
37 #define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */
38 #define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */
39 #define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */
40 #define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */
41 #define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */
42 #define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */
43 #define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */
44 #define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */
45 #define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */
46 #define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */
47 #define SCR_CCR 0x98 /* w Clock Control */
48 #define SCR_PLL2CR 0x9a /* w PLL2 Control */
49 #define SCR_PLL1CR 0x9c /* l PLL1 Control */
50 #define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */
51 #define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */
52 #define SCR_FER 0xe0 /* b Function Enable */
53 #define SCR_MCR 0xe4 /* w Mode Control */
54 #define SCR_CONFIG 0xfc /* b Configuration Control */
55 #define SCR_DEBUG 0xff /* b Debug */
56 
57 #define SCR_CCR_CK32K BIT(0)
58 #define SCR_CCR_USBCK BIT(1)
59 #define SCR_CCR_UNK1 BIT(4)
60 #define SCR_CCR_MCLK_MASK (7 << 8)
61 #define SCR_CCR_MCLK_OFF (0 << 8)
62 #define SCR_CCR_MCLK_12 (1 << 8)
63 #define SCR_CCR_MCLK_24 (2 << 8)
64 #define SCR_CCR_MCLK_48 (3 << 8)
65 #define SCR_CCR_HCLK_MASK (3 << 12)
66 #define SCR_CCR_HCLK_24 (0 << 12)
67 #define SCR_CCR_HCLK_48 (1 << 12)
68 
69 #define SCR_FER_USBEN BIT(0) /* USB host enable */
70 #define SCR_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */
71 #define SCR_FER_SLCDEN BIT(2) /* SLCD enable */
72 
73 #define SCR_MCR_RDY_MASK (3 << 0)
74 #define SCR_MCR_RDY_OPENDRAIN (0 << 0)
75 #define SCR_MCR_RDY_TRISTATE (1 << 0)
76 #define SCR_MCR_RDY_PUSHPULL (2 << 0)
77 #define SCR_MCR_RDY_UNK BIT(2)
78 #define SCR_MCR_RDY_EN BIT(3)
79 #define SCR_MCR_INT_MASK (3 << 4)
80 #define SCR_MCR_INT_OPENDRAIN (0 << 4)
81 #define SCR_MCR_INT_TRISTATE (1 << 4)
82 #define SCR_MCR_INT_PUSHPULL (2 << 4)
83 #define SCR_MCR_INT_UNK BIT(6)
84 #define SCR_MCR_INT_EN BIT(7)
85 /* bits 8 - 16 are unknown */
86 
87 #define TC_GPIO_BIT(i) (1 << (i & 0x7))
88 
89 /*--------------------------------------------------------------------------*/
90 
91 struct tc6393xb {
92  void __iomem *scr;
93 
94  struct gpio_chip gpio;
95 
96  struct clk *clk; /* 3,6 Mhz */
97 
98  spinlock_t lock; /* protects RMW cycles */
99 
100  struct {
106  } suspend_state;
107 
108  struct resource rscr;
109  struct resource *iomem;
110  int irq;
111  int irq_base;
112 };
113 
114 enum {
119 };
120 
121 /*--------------------------------------------------------------------------*/
122 
123 static int tc6393xb_nand_enable(struct platform_device *nand)
124 {
125  struct platform_device *dev = to_platform_device(nand->dev.parent);
126  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
127  unsigned long flags;
128 
129  spin_lock_irqsave(&tc6393xb->lock, flags);
130 
131  /* SMD buffer on */
132  dev_dbg(&dev->dev, "SMD buffer on\n");
133  tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
134 
135  spin_unlock_irqrestore(&tc6393xb->lock, flags);
136 
137  return 0;
138 }
139 
140 static struct resource __devinitdata tc6393xb_nand_resources[] = {
141  {
142  .start = 0x1000,
143  .end = 0x1007,
144  .flags = IORESOURCE_MEM,
145  },
146  {
147  .start = 0x0100,
148  .end = 0x01ff,
149  .flags = IORESOURCE_MEM,
150  },
151  {
152  .start = IRQ_TC6393_NAND,
153  .end = IRQ_TC6393_NAND,
154  .flags = IORESOURCE_IRQ,
155  },
156 };
157 
158 static struct resource tc6393xb_mmc_resources[] = {
159  {
160  .start = 0x800,
161  .end = 0x9ff,
162  .flags = IORESOURCE_MEM,
163  },
164  {
165  .start = IRQ_TC6393_MMC,
166  .end = IRQ_TC6393_MMC,
167  .flags = IORESOURCE_IRQ,
168  },
169 };
170 
171 static const struct resource tc6393xb_ohci_resources[] = {
172  {
173  .start = 0x3000,
174  .end = 0x31ff,
175  .flags = IORESOURCE_MEM,
176  },
177  {
178  .start = 0x0300,
179  .end = 0x03ff,
180  .flags = IORESOURCE_MEM,
181  },
182  {
183  .start = 0x010000,
184  .end = 0x017fff,
185  .flags = IORESOURCE_MEM,
186  },
187  {
188  .start = 0x018000,
189  .end = 0x01ffff,
190  .flags = IORESOURCE_MEM,
191  },
192  {
193  .start = IRQ_TC6393_OHCI,
194  .end = IRQ_TC6393_OHCI,
195  .flags = IORESOURCE_IRQ,
196  },
197 };
198 
199 static struct resource __devinitdata tc6393xb_fb_resources[] = {
200  {
201  .start = 0x5000,
202  .end = 0x51ff,
203  .flags = IORESOURCE_MEM,
204  },
205  {
206  .start = 0x0500,
207  .end = 0x05ff,
208  .flags = IORESOURCE_MEM,
209  },
210  {
211  .start = 0x100000,
212  .end = 0x1fffff,
213  .flags = IORESOURCE_MEM,
214  },
215  {
216  .start = IRQ_TC6393_FB,
217  .end = IRQ_TC6393_FB,
218  .flags = IORESOURCE_IRQ,
219  },
220 };
221 
222 static int tc6393xb_ohci_enable(struct platform_device *dev)
223 {
224  struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
225  unsigned long flags;
226  u16 ccr;
227  u8 fer;
228 
229  spin_lock_irqsave(&tc6393xb->lock, flags);
230 
231  ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
232  ccr |= SCR_CCR_USBCK;
233  tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
234 
235  fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
236  fer |= SCR_FER_USBEN;
237  tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
238 
239  spin_unlock_irqrestore(&tc6393xb->lock, flags);
240 
241  return 0;
242 }
243 
244 static int tc6393xb_ohci_disable(struct platform_device *dev)
245 {
246  struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
247  unsigned long flags;
248  u16 ccr;
249  u8 fer;
250 
251  spin_lock_irqsave(&tc6393xb->lock, flags);
252 
253  fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
254  fer &= ~SCR_FER_USBEN;
255  tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
256 
257  ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
258  ccr &= ~SCR_CCR_USBCK;
259  tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
260 
261  spin_unlock_irqrestore(&tc6393xb->lock, flags);
262 
263  return 0;
264 }
265 
266 static int tc6393xb_fb_enable(struct platform_device *dev)
267 {
268  struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
269  unsigned long flags;
270  u16 ccr;
271 
272  spin_lock_irqsave(&tc6393xb->lock, flags);
273 
274  ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
275  ccr &= ~SCR_CCR_MCLK_MASK;
276  ccr |= SCR_CCR_MCLK_48;
277  tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
278 
279  spin_unlock_irqrestore(&tc6393xb->lock, flags);
280 
281  return 0;
282 }
283 
284 static int tc6393xb_fb_disable(struct platform_device *dev)
285 {
286  struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
287  unsigned long flags;
288  u16 ccr;
289 
290  spin_lock_irqsave(&tc6393xb->lock, flags);
291 
292  ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
293  ccr &= ~SCR_CCR_MCLK_MASK;
294  ccr |= SCR_CCR_MCLK_OFF;
295  tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
296 
297  spin_unlock_irqrestore(&tc6393xb->lock, flags);
298 
299  return 0;
300 }
301 
303 {
304  struct platform_device *dev = to_platform_device(fb->dev.parent);
305  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
306  u8 fer;
307  unsigned long flags;
308 
309  spin_lock_irqsave(&tc6393xb->lock, flags);
310 
311  fer = ioread8(tc6393xb->scr + SCR_FER);
312  if (on)
313  fer |= SCR_FER_SLCDEN;
314  else
315  fer &= ~SCR_FER_SLCDEN;
316  iowrite8(fer, tc6393xb->scr + SCR_FER);
317 
318  spin_unlock_irqrestore(&tc6393xb->lock, flags);
319 
320  return 0;
321 }
323 
325  const struct fb_videomode *mode) {
326  struct platform_device *dev = to_platform_device(fb->dev.parent);
327  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
328  unsigned long flags;
329 
330  spin_lock_irqsave(&tc6393xb->lock, flags);
331 
332  iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0);
333  iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2);
334 
335  spin_unlock_irqrestore(&tc6393xb->lock, flags);
336 
337  return 0;
338 }
340 
341 static int tc6393xb_mmc_enable(struct platform_device *mmc)
342 {
343  struct platform_device *dev = to_platform_device(mmc->dev.parent);
344  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
345 
346  tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0,
347  tc6393xb_mmc_resources[0].start & 0xfffe);
348 
349  return 0;
350 }
351 
352 static int tc6393xb_mmc_resume(struct platform_device *mmc)
353 {
354  struct platform_device *dev = to_platform_device(mmc->dev.parent);
355  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
356 
357  tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0,
358  tc6393xb_mmc_resources[0].start & 0xfffe);
359 
360  return 0;
361 }
362 
363 static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state)
364 {
365  struct platform_device *dev = to_platform_device(mmc->dev.parent);
366  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
367 
368  tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state);
369 }
370 
371 static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state)
372 {
373  struct platform_device *dev = to_platform_device(mmc->dev.parent);
374  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
375 
376  tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state);
377 }
378 
379 static struct tmio_mmc_data tc6393xb_mmc_data = {
380  .hclk = 24000000,
381  .set_pwr = tc6393xb_mmc_pwr,
382  .set_clk_div = tc6393xb_mmc_clk_div,
383 };
384 
385 static struct mfd_cell __devinitdata tc6393xb_cells[] = {
386  [TC6393XB_CELL_NAND] = {
387  .name = "tmio-nand",
388  .enable = tc6393xb_nand_enable,
389  .num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
390  .resources = tc6393xb_nand_resources,
391  },
392  [TC6393XB_CELL_MMC] = {
393  .name = "tmio-mmc",
394  .enable = tc6393xb_mmc_enable,
395  .resume = tc6393xb_mmc_resume,
396  .platform_data = &tc6393xb_mmc_data,
397  .pdata_size = sizeof(tc6393xb_mmc_data),
398  .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
399  .resources = tc6393xb_mmc_resources,
400  },
401  [TC6393XB_CELL_OHCI] = {
402  .name = "tmio-ohci",
403  .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
404  .resources = tc6393xb_ohci_resources,
405  .enable = tc6393xb_ohci_enable,
406  .suspend = tc6393xb_ohci_disable,
407  .resume = tc6393xb_ohci_enable,
408  .disable = tc6393xb_ohci_disable,
409  },
410  [TC6393XB_CELL_FB] = {
411  .name = "tmio-fb",
412  .num_resources = ARRAY_SIZE(tc6393xb_fb_resources),
413  .resources = tc6393xb_fb_resources,
414  .enable = tc6393xb_fb_enable,
415  .suspend = tc6393xb_fb_disable,
416  .resume = tc6393xb_fb_enable,
417  .disable = tc6393xb_fb_disable,
418  },
419 };
420 
421 /*--------------------------------------------------------------------------*/
422 
423 static int tc6393xb_gpio_get(struct gpio_chip *chip,
424  unsigned offset)
425 {
426  struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
427 
428  /* XXX: does dsr also represent inputs? */
429  return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
430  & TC_GPIO_BIT(offset);
431 }
432 
433 static void __tc6393xb_gpio_set(struct gpio_chip *chip,
434  unsigned offset, int value)
435 {
436  struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
437  u8 dsr;
438 
439  dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
440  if (value)
441  dsr |= TC_GPIO_BIT(offset);
442  else
443  dsr &= ~TC_GPIO_BIT(offset);
444 
445  tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
446 }
447 
448 static void tc6393xb_gpio_set(struct gpio_chip *chip,
449  unsigned offset, int value)
450 {
451  struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
452  unsigned long flags;
453 
454  spin_lock_irqsave(&tc6393xb->lock, flags);
455 
456  __tc6393xb_gpio_set(chip, offset, value);
457 
458  spin_unlock_irqrestore(&tc6393xb->lock, flags);
459 }
460 
461 static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
462  unsigned offset)
463 {
464  struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
465  unsigned long flags;
466  u8 doecr;
467 
468  spin_lock_irqsave(&tc6393xb->lock, flags);
469 
470  doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
471  doecr &= ~TC_GPIO_BIT(offset);
472  tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
473 
474  spin_unlock_irqrestore(&tc6393xb->lock, flags);
475 
476  return 0;
477 }
478 
479 static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
480  unsigned offset, int value)
481 {
482  struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
483  unsigned long flags;
484  u8 doecr;
485 
486  spin_lock_irqsave(&tc6393xb->lock, flags);
487 
488  __tc6393xb_gpio_set(chip, offset, value);
489 
490  doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
491  doecr |= TC_GPIO_BIT(offset);
492  tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
493 
494  spin_unlock_irqrestore(&tc6393xb->lock, flags);
495 
496  return 0;
497 }
498 
499 static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
500 {
501  tc6393xb->gpio.label = "tc6393xb";
502  tc6393xb->gpio.base = gpio_base;
503  tc6393xb->gpio.ngpio = 16;
504  tc6393xb->gpio.set = tc6393xb_gpio_set;
505  tc6393xb->gpio.get = tc6393xb_gpio_get;
506  tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
507  tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
508 
509  return gpiochip_add(&tc6393xb->gpio);
510 }
511 
512 /*--------------------------------------------------------------------------*/
513 
514 static void
515 tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
516 {
517  struct tc6393xb *tc6393xb = irq_get_handler_data(irq);
518  unsigned int isr;
519  unsigned int i, irq_base;
520 
521  irq_base = tc6393xb->irq_base;
522 
523  while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) &
524  ~tmio_ioread8(tc6393xb->scr + SCR_IMR)))
525  for (i = 0; i < TC6393XB_NR_IRQS; i++) {
526  if (isr & (1 << i))
527  generic_handle_irq(irq_base + i);
528  }
529 }
530 
531 static void tc6393xb_irq_ack(struct irq_data *data)
532 {
533 }
534 
535 static void tc6393xb_irq_mask(struct irq_data *data)
536 {
537  struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
538  unsigned long flags;
539  u8 imr;
540 
541  spin_lock_irqsave(&tc6393xb->lock, flags);
542  imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
543  imr |= 1 << (data->irq - tc6393xb->irq_base);
544  tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
545  spin_unlock_irqrestore(&tc6393xb->lock, flags);
546 }
547 
548 static void tc6393xb_irq_unmask(struct irq_data *data)
549 {
550  struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
551  unsigned long flags;
552  u8 imr;
553 
554  spin_lock_irqsave(&tc6393xb->lock, flags);
555  imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
556  imr &= ~(1 << (data->irq - tc6393xb->irq_base));
557  tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
558  spin_unlock_irqrestore(&tc6393xb->lock, flags);
559 }
560 
561 static struct irq_chip tc6393xb_chip = {
562  .name = "tc6393xb",
563  .irq_ack = tc6393xb_irq_ack,
564  .irq_mask = tc6393xb_irq_mask,
565  .irq_unmask = tc6393xb_irq_unmask,
566 };
567 
568 static void tc6393xb_attach_irq(struct platform_device *dev)
569 {
570  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
571  unsigned int irq, irq_base;
572 
573  irq_base = tc6393xb->irq_base;
574 
575  for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
576  irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq);
577  irq_set_chip_data(irq, tc6393xb);
579  }
580 
582  irq_set_handler_data(tc6393xb->irq, tc6393xb);
583  irq_set_chained_handler(tc6393xb->irq, tc6393xb_irq);
584 }
585 
586 static void tc6393xb_detach_irq(struct platform_device *dev)
587 {
588  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
589  unsigned int irq, irq_base;
590 
591  irq_set_chained_handler(tc6393xb->irq, NULL);
592  irq_set_handler_data(tc6393xb->irq, NULL);
593 
594  irq_base = tc6393xb->irq_base;
595 
596  for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
597  set_irq_flags(irq, 0);
598  irq_set_chip(irq, NULL);
599  irq_set_chip_data(irq, NULL);
600  }
601 }
602 
603 /*--------------------------------------------------------------------------*/
604 
605 static int __devinit tc6393xb_probe(struct platform_device *dev)
606 {
607  struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
608  struct tc6393xb *tc6393xb;
609  struct resource *iomem, *rscr;
610  int ret, temp;
611 
612  iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
613  if (!iomem)
614  return -EINVAL;
615 
616  tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
617  if (!tc6393xb) {
618  ret = -ENOMEM;
619  goto err_kzalloc;
620  }
621 
622  spin_lock_init(&tc6393xb->lock);
623 
624  platform_set_drvdata(dev, tc6393xb);
625 
626  ret = platform_get_irq(dev, 0);
627  if (ret >= 0)
628  tc6393xb->irq = ret;
629  else
630  goto err_noirq;
631 
632  tc6393xb->iomem = iomem;
633  tc6393xb->irq_base = tcpd->irq_base;
634 
635  tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI");
636  if (IS_ERR(tc6393xb->clk)) {
637  ret = PTR_ERR(tc6393xb->clk);
638  goto err_clk_get;
639  }
640 
641  rscr = &tc6393xb->rscr;
642  rscr->name = "tc6393xb-core";
643  rscr->start = iomem->start;
644  rscr->end = iomem->start + 0xff;
645  rscr->flags = IORESOURCE_MEM;
646 
647  ret = request_resource(iomem, rscr);
648  if (ret)
649  goto err_request_scr;
650 
651  tc6393xb->scr = ioremap(rscr->start, resource_size(rscr));
652  if (!tc6393xb->scr) {
653  ret = -ENOMEM;
654  goto err_ioremap;
655  }
656 
657  ret = clk_enable(tc6393xb->clk);
658  if (ret)
659  goto err_clk_enable;
660 
661  ret = tcpd->enable(dev);
662  if (ret)
663  goto err_enable;
664 
665  iowrite8(0, tc6393xb->scr + SCR_FER);
666  iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR);
668  tc6393xb->scr + SCR_CCR);
671  BIT(15), tc6393xb->scr + SCR_MCR);
672  iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER);
673  iowrite8(0, tc6393xb->scr + SCR_IRR);
674  iowrite8(0xbf, tc6393xb->scr + SCR_IMR);
675 
676  printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
677  tmio_ioread8(tc6393xb->scr + SCR_REVID),
678  (unsigned long) iomem->start, tc6393xb->irq);
679 
680  tc6393xb->gpio.base = -1;
681 
682  if (tcpd->gpio_base >= 0) {
683  ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
684  if (ret)
685  goto err_gpio_add;
686  }
687 
688  tc6393xb_attach_irq(dev);
689 
690  if (tcpd->setup) {
691  ret = tcpd->setup(dev);
692  if (ret)
693  goto err_setup;
694  }
695 
696  tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data;
697  tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size =
698  sizeof(*tcpd->nand_data);
699  tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data;
700  tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);
701 
702  ret = mfd_add_devices(&dev->dev, dev->id,
703  tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
704  iomem, tcpd->irq_base, NULL);
705 
706  if (!ret)
707  return 0;
708 
709  if (tcpd->teardown)
710  tcpd->teardown(dev);
711 
712 err_setup:
713  tc6393xb_detach_irq(dev);
714 
715 err_gpio_add:
716  if (tc6393xb->gpio.base != -1)
717  temp = gpiochip_remove(&tc6393xb->gpio);
718  tcpd->disable(dev);
719 err_enable:
720  clk_disable(tc6393xb->clk);
721 err_clk_enable:
722  iounmap(tc6393xb->scr);
723 err_ioremap:
724  release_resource(&tc6393xb->rscr);
725 err_request_scr:
726  clk_put(tc6393xb->clk);
727 err_noirq:
728 err_clk_get:
729  kfree(tc6393xb);
730 err_kzalloc:
731  return ret;
732 }
733 
734 static int __devexit tc6393xb_remove(struct platform_device *dev)
735 {
736  struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
737  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
738  int ret;
739 
740  mfd_remove_devices(&dev->dev);
741 
742  if (tcpd->teardown)
743  tcpd->teardown(dev);
744 
745  tc6393xb_detach_irq(dev);
746 
747  if (tc6393xb->gpio.base != -1) {
748  ret = gpiochip_remove(&tc6393xb->gpio);
749  if (ret) {
750  dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret);
751  return ret;
752  }
753  }
754 
755  ret = tcpd->disable(dev);
756  clk_disable(tc6393xb->clk);
757  iounmap(tc6393xb->scr);
758  release_resource(&tc6393xb->rscr);
759  platform_set_drvdata(dev, NULL);
760  clk_put(tc6393xb->clk);
761  kfree(tc6393xb);
762 
763  return ret;
764 }
765 
766 #ifdef CONFIG_PM
767 static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
768 {
769  struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
770  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
771  int i, ret;
772 
773  tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
774  tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER);
775 
776  for (i = 0; i < 3; i++) {
777  tc6393xb->suspend_state.gpo_dsr[i] =
778  ioread8(tc6393xb->scr + SCR_GPO_DSR(i));
779  tc6393xb->suspend_state.gpo_doecr[i] =
780  ioread8(tc6393xb->scr + SCR_GPO_DOECR(i));
781  tc6393xb->suspend_state.gpi_bcr[i] =
782  ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
783  }
784  ret = tcpd->suspend(dev);
785  clk_disable(tc6393xb->clk);
786 
787  return ret;
788 }
789 
790 static int tc6393xb_resume(struct platform_device *dev)
791 {
792  struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
793  struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
794  int ret;
795  int i;
796 
797  clk_enable(tc6393xb->clk);
798 
799  ret = tcpd->resume(dev);
800  if (ret)
801  return ret;
802 
803  if (!tcpd->resume_restore)
804  return 0;
805 
806  iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER);
807  iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR);
808  iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR);
811  BIT(15), tc6393xb->scr + SCR_MCR);
812  iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER);
813  iowrite8(0, tc6393xb->scr + SCR_IRR);
814  iowrite8(0xbf, tc6393xb->scr + SCR_IMR);
815 
816  for (i = 0; i < 3; i++) {
817  iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
818  tc6393xb->scr + SCR_GPO_DSR(i));
819  iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
820  tc6393xb->scr + SCR_GPO_DOECR(i));
821  iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
822  tc6393xb->scr + SCR_GPI_BCR(i));
823  }
824 
825  return 0;
826 }
827 #else
828 #define tc6393xb_suspend NULL
829 #define tc6393xb_resume NULL
830 #endif
831 
832 static struct platform_driver tc6393xb_driver = {
833  .probe = tc6393xb_probe,
834  .remove = __devexit_p(tc6393xb_remove),
835  .suspend = tc6393xb_suspend,
836  .resume = tc6393xb_resume,
837 
838  .driver = {
839  .name = "tc6393xb",
840  .owner = THIS_MODULE,
841  },
842 };
843 
844 static int __init tc6393xb_init(void)
845 {
846  return platform_driver_register(&tc6393xb_driver);
847 }
848 
849 static void __exit tc6393xb_exit(void)
850 {
851  platform_driver_unregister(&tc6393xb_driver);
852 }
853 
854 subsys_initcall(tc6393xb_init);
855 module_exit(tc6393xb_exit);
856 
857 MODULE_LICENSE("GPL v2");
858 MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
859 MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
860 MODULE_ALIAS("platform:tc6393xb");
861