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