diff options
| -rw-r--r-- | drivers/mfd/tc6393xb.c | 156 | ||||
| -rw-r--r-- | include/linux/mfd/tc6393xb.h | 9 |
2 files changed, 96 insertions, 69 deletions
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 81e2605ea10d..e4c1c788b5f8 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
| @@ -19,8 +19,8 @@ | |||
| 19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/fb.h> | ||
| 23 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
| 23 | #include <linux/err.h> | ||
| 24 | #include <linux/mfd/core.h> | 24 | #include <linux/mfd/core.h> |
| 25 | #include <linux/mfd/tmio.h> | 25 | #include <linux/mfd/tmio.h> |
| 26 | #include <linux/mfd/tc6393xb.h> | 26 | #include <linux/mfd/tc6393xb.h> |
| @@ -112,6 +112,7 @@ struct tc6393xb { | |||
| 112 | 112 | ||
| 113 | enum { | 113 | enum { |
| 114 | TC6393XB_CELL_NAND, | 114 | TC6393XB_CELL_NAND, |
| 115 | TC6393XB_CELL_MMC, | ||
| 115 | }; | 116 | }; |
| 116 | 117 | ||
| 117 | /*--------------------------------------------------------------------------*/ | 118 | /*--------------------------------------------------------------------------*/ |
| @@ -126,7 +127,7 @@ static int tc6393xb_nand_enable(struct platform_device *nand) | |||
| 126 | 127 | ||
| 127 | /* SMD buffer on */ | 128 | /* SMD buffer on */ |
| 128 | dev_dbg(&dev->dev, "SMD buffer on\n"); | 129 | dev_dbg(&dev->dev, "SMD buffer on\n"); |
| 129 | iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); | 130 | tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); |
| 130 | 131 | ||
| 131 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 132 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 132 | 133 | ||
| @@ -135,13 +136,13 @@ static int tc6393xb_nand_enable(struct platform_device *nand) | |||
| 135 | 136 | ||
| 136 | static struct resource __devinitdata tc6393xb_nand_resources[] = { | 137 | static struct resource __devinitdata tc6393xb_nand_resources[] = { |
| 137 | { | 138 | { |
| 138 | .start = 0x0100, | 139 | .start = 0x1000, |
| 139 | .end = 0x01ff, | 140 | .end = 0x1007, |
| 140 | .flags = IORESOURCE_MEM, | 141 | .flags = IORESOURCE_MEM, |
| 141 | }, | 142 | }, |
| 142 | { | 143 | { |
| 143 | .start = 0x1000, | 144 | .start = 0x0100, |
| 144 | .end = 0x1007, | 145 | .end = 0x01ff, |
| 145 | .flags = IORESOURCE_MEM, | 146 | .flags = IORESOURCE_MEM, |
| 146 | }, | 147 | }, |
| 147 | { | 148 | { |
| @@ -151,6 +152,24 @@ static struct resource __devinitdata tc6393xb_nand_resources[] = { | |||
| 151 | }, | 152 | }, |
| 152 | }; | 153 | }; |
| 153 | 154 | ||
| 155 | static struct resource __devinitdata tc6393xb_mmc_resources[] = { | ||
| 156 | { | ||
| 157 | .start = 0x800, | ||
| 158 | .end = 0x9ff, | ||
| 159 | .flags = IORESOURCE_MEM, | ||
| 160 | }, | ||
| 161 | { | ||
| 162 | .start = 0x200, | ||
| 163 | .end = 0x2ff, | ||
| 164 | .flags = IORESOURCE_MEM, | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | .start = IRQ_TC6393_MMC, | ||
| 168 | .end = IRQ_TC6393_MMC, | ||
| 169 | .flags = IORESOURCE_IRQ, | ||
| 170 | }, | ||
| 171 | }; | ||
| 172 | |||
| 154 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { | 173 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { |
| 155 | [TC6393XB_CELL_NAND] = { | 174 | [TC6393XB_CELL_NAND] = { |
| 156 | .name = "tmio-nand", | 175 | .name = "tmio-nand", |
| @@ -158,6 +177,11 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { | |||
| 158 | .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), | 177 | .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), |
| 159 | .resources = tc6393xb_nand_resources, | 178 | .resources = tc6393xb_nand_resources, |
| 160 | }, | 179 | }, |
| 180 | [TC6393XB_CELL_MMC] = { | ||
| 181 | .name = "tmio-mmc", | ||
| 182 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), | ||
| 183 | .resources = tc6393xb_mmc_resources, | ||
| 184 | }, | ||
| 161 | }; | 185 | }; |
| 162 | 186 | ||
| 163 | /*--------------------------------------------------------------------------*/ | 187 | /*--------------------------------------------------------------------------*/ |
| @@ -168,7 +192,7 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip, | |||
| 168 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); | 192 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); |
| 169 | 193 | ||
| 170 | /* XXX: does dsr also represent inputs? */ | 194 | /* XXX: does dsr also represent inputs? */ |
| 171 | return ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) | 195 | return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) |
| 172 | & TC_GPIO_BIT(offset); | 196 | & TC_GPIO_BIT(offset); |
| 173 | } | 197 | } |
| 174 | 198 | ||
| @@ -178,13 +202,13 @@ static void __tc6393xb_gpio_set(struct gpio_chip *chip, | |||
| 178 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); | 202 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); |
| 179 | u8 dsr; | 203 | u8 dsr; |
| 180 | 204 | ||
| 181 | dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); | 205 | dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); |
| 182 | if (value) | 206 | if (value) |
| 183 | dsr |= TC_GPIO_BIT(offset); | 207 | dsr |= TC_GPIO_BIT(offset); |
| 184 | else | 208 | else |
| 185 | dsr &= ~TC_GPIO_BIT(offset); | 209 | dsr &= ~TC_GPIO_BIT(offset); |
| 186 | 210 | ||
| 187 | iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); | 211 | tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); |
| 188 | } | 212 | } |
| 189 | 213 | ||
| 190 | static void tc6393xb_gpio_set(struct gpio_chip *chip, | 214 | static void tc6393xb_gpio_set(struct gpio_chip *chip, |
| @@ -209,9 +233,9 @@ static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, | |||
| 209 | 233 | ||
| 210 | spin_lock_irqsave(&tc6393xb->lock, flags); | 234 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 211 | 235 | ||
| 212 | doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 236 | doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 213 | doecr &= ~TC_GPIO_BIT(offset); | 237 | doecr &= ~TC_GPIO_BIT(offset); |
| 214 | iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 238 | tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 215 | 239 | ||
| 216 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 240 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 217 | 241 | ||
| @@ -229,9 +253,9 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, | |||
| 229 | 253 | ||
| 230 | __tc6393xb_gpio_set(chip, offset, value); | 254 | __tc6393xb_gpio_set(chip, offset, value); |
| 231 | 255 | ||
| 232 | doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 256 | doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 233 | doecr |= TC_GPIO_BIT(offset); | 257 | doecr |= TC_GPIO_BIT(offset); |
| 234 | iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 258 | tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 235 | 259 | ||
| 236 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 260 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 237 | 261 | ||
| @@ -262,8 +286,8 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc) | |||
| 262 | 286 | ||
| 263 | irq_base = tc6393xb->irq_base; | 287 | irq_base = tc6393xb->irq_base; |
| 264 | 288 | ||
| 265 | while ((isr = ioread8(tc6393xb->scr + SCR_ISR) & | 289 | while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) & |
| 266 | ~ioread8(tc6393xb->scr + SCR_IMR))) | 290 | ~tmio_ioread8(tc6393xb->scr + SCR_IMR))) |
| 267 | for (i = 0; i < TC6393XB_NR_IRQS; i++) { | 291 | for (i = 0; i < TC6393XB_NR_IRQS; i++) { |
| 268 | if (isr & (1 << i)) | 292 | if (isr & (1 << i)) |
| 269 | generic_handle_irq(irq_base + i); | 293 | generic_handle_irq(irq_base + i); |
| @@ -281,9 +305,9 @@ static void tc6393xb_irq_mask(unsigned int irq) | |||
| 281 | u8 imr; | 305 | u8 imr; |
| 282 | 306 | ||
| 283 | spin_lock_irqsave(&tc6393xb->lock, flags); | 307 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 284 | imr = ioread8(tc6393xb->scr + SCR_IMR); | 308 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 285 | imr |= 1 << (irq - tc6393xb->irq_base); | 309 | imr |= 1 << (irq - tc6393xb->irq_base); |
| 286 | iowrite8(imr, tc6393xb->scr + SCR_IMR); | 310 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 287 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 311 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 288 | } | 312 | } |
| 289 | 313 | ||
| @@ -294,9 +318,9 @@ static void tc6393xb_irq_unmask(unsigned int irq) | |||
| 294 | u8 imr; | 318 | u8 imr; |
| 295 | 319 | ||
| 296 | spin_lock_irqsave(&tc6393xb->lock, flags); | 320 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 297 | imr = ioread8(tc6393xb->scr + SCR_IMR); | 321 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 298 | imr &= ~(1 << (irq - tc6393xb->irq_base)); | 322 | imr &= ~(1 << (irq - tc6393xb->irq_base)); |
| 299 | iowrite8(imr, tc6393xb->scr + SCR_IMR); | 323 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 300 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 324 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 301 | } | 325 | } |
| 302 | 326 | ||
| @@ -377,9 +401,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
| 377 | { | 401 | { |
| 378 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 402 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
| 379 | struct tc6393xb *tc6393xb; | 403 | struct tc6393xb *tc6393xb; |
| 380 | struct resource *iomem; | 404 | struct resource *iomem, *rscr; |
| 381 | struct resource *rscr; | 405 | int ret, temp; |
| 382 | int retval, temp; | ||
| 383 | int i; | 406 | int i; |
| 384 | 407 | ||
| 385 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 408 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
| @@ -388,20 +411,26 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
| 388 | 411 | ||
| 389 | tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); | 412 | tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); |
| 390 | if (!tc6393xb) { | 413 | if (!tc6393xb) { |
| 391 | retval = -ENOMEM; | 414 | ret = -ENOMEM; |
| 392 | goto err_kzalloc; | 415 | goto err_kzalloc; |
| 393 | } | 416 | } |
| 394 | 417 | ||
| 395 | spin_lock_init(&tc6393xb->lock); | 418 | spin_lock_init(&tc6393xb->lock); |
| 396 | 419 | ||
| 397 | platform_set_drvdata(dev, tc6393xb); | 420 | platform_set_drvdata(dev, tc6393xb); |
| 421 | |||
| 422 | ret = platform_get_irq(dev, 0); | ||
| 423 | if (ret >= 0) | ||
| 424 | tc6393xb->irq = ret; | ||
| 425 | else | ||
| 426 | goto err_noirq; | ||
| 427 | |||
| 398 | tc6393xb->iomem = iomem; | 428 | tc6393xb->iomem = iomem; |
| 399 | tc6393xb->irq = platform_get_irq(dev, 0); | ||
| 400 | tc6393xb->irq_base = tcpd->irq_base; | 429 | tc6393xb->irq_base = tcpd->irq_base; |
| 401 | 430 | ||
| 402 | tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */); | 431 | tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI"); |
| 403 | if (IS_ERR(tc6393xb->clk)) { | 432 | if (IS_ERR(tc6393xb->clk)) { |
| 404 | retval = PTR_ERR(tc6393xb->clk); | 433 | ret = PTR_ERR(tc6393xb->clk); |
| 405 | goto err_clk_get; | 434 | goto err_clk_get; |
| 406 | } | 435 | } |
| 407 | 436 | ||
| @@ -411,71 +440,73 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
| 411 | rscr->end = iomem->start + 0xff; | 440 | rscr->end = iomem->start + 0xff; |
| 412 | rscr->flags = IORESOURCE_MEM; | 441 | rscr->flags = IORESOURCE_MEM; |
| 413 | 442 | ||
| 414 | retval = request_resource(iomem, rscr); | 443 | ret = request_resource(iomem, rscr); |
| 415 | if (retval) | 444 | if (ret) |
| 416 | goto err_request_scr; | 445 | goto err_request_scr; |
| 417 | 446 | ||
| 418 | tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); | 447 | tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); |
| 419 | if (!tc6393xb->scr) { | 448 | if (!tc6393xb->scr) { |
| 420 | retval = -ENOMEM; | 449 | ret = -ENOMEM; |
| 421 | goto err_ioremap; | 450 | goto err_ioremap; |
| 422 | } | 451 | } |
| 423 | 452 | ||
| 424 | retval = clk_enable(tc6393xb->clk); | 453 | ret = clk_enable(tc6393xb->clk); |
| 425 | if (retval) | 454 | if (ret) |
| 426 | goto err_clk_enable; | 455 | goto err_clk_enable; |
| 427 | 456 | ||
| 428 | retval = tcpd->enable(dev); | 457 | ret = tcpd->enable(dev); |
| 429 | if (retval) | 458 | if (ret) |
| 430 | goto err_enable; | 459 | goto err_enable; |
| 431 | 460 | ||
| 432 | tc6393xb->suspend_state.fer = 0; | 461 | tc6393xb->suspend_state.fer = 0; |
| 462 | |||
| 433 | for (i = 0; i < 3; i++) { | 463 | for (i = 0; i < 3; i++) { |
| 434 | tc6393xb->suspend_state.gpo_dsr[i] = | 464 | tc6393xb->suspend_state.gpo_dsr[i] = |
| 435 | (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; | 465 | (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; |
| 436 | tc6393xb->suspend_state.gpo_doecr[i] = | 466 | tc6393xb->suspend_state.gpo_doecr[i] = |
| 437 | (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; | 467 | (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; |
| 438 | } | 468 | } |
| 439 | /* | 469 | |
| 440 | * It may be necessary to change this back to | ||
| 441 | * platform-dependant code | ||
| 442 | */ | ||
| 443 | tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | | 470 | tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | |
| 444 | SCR_CCR_HCLK_48; | 471 | SCR_CCR_HCLK_48; |
| 445 | 472 | ||
| 446 | retval = tc6393xb_hw_init(dev); | 473 | ret = tc6393xb_hw_init(dev); |
| 447 | if (retval) | 474 | if (ret) |
| 448 | goto err_hw_init; | 475 | goto err_hw_init; |
| 449 | 476 | ||
| 450 | printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", | 477 | printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", |
| 451 | ioread8(tc6393xb->scr + SCR_REVID), | 478 | tmio_ioread8(tc6393xb->scr + SCR_REVID), |
| 452 | (unsigned long) iomem->start, tc6393xb->irq); | 479 | (unsigned long) iomem->start, tc6393xb->irq); |
| 453 | 480 | ||
| 454 | tc6393xb->gpio.base = -1; | 481 | tc6393xb->gpio.base = -1; |
| 455 | 482 | ||
| 456 | if (tcpd->gpio_base >= 0) { | 483 | if (tcpd->gpio_base >= 0) { |
| 457 | retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); | 484 | ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); |
| 458 | if (retval) | 485 | if (ret) |
| 459 | goto err_gpio_add; | 486 | goto err_gpio_add; |
| 460 | } | 487 | } |
| 461 | 488 | ||
| 462 | if (tc6393xb->irq) | 489 | tc6393xb_attach_irq(dev); |
| 463 | tc6393xb_attach_irq(dev); | ||
| 464 | 490 | ||
| 465 | tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; | 491 | tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; |
| 466 | tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = | 492 | tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = |
| 467 | &tc6393xb_cells[TC6393XB_CELL_NAND]; | 493 | &tc6393xb_cells[TC6393XB_CELL_NAND]; |
| 468 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = | 494 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = |
| 469 | sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); | 495 | sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); |
| 496 | tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = | ||
| 497 | &tc6393xb_cells[TC6393XB_CELL_MMC]; | ||
| 498 | tc6393xb_cells[TC6393XB_CELL_MMC].data_size = | ||
| 499 | sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]); | ||
| 500 | |||
| 470 | 501 | ||
| 471 | retval = mfd_add_devices(&dev->dev, dev->id, | 502 | ret = mfd_add_devices(&dev->dev, dev->id, |
| 472 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 503 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |
| 473 | iomem, tcpd->irq_base); | 504 | iomem, tcpd->irq_base); |
| 474 | 505 | ||
| 475 | return 0; | 506 | if (!ret) |
| 507 | return 0; | ||
| 476 | 508 | ||
| 477 | if (tc6393xb->irq) | 509 | tc6393xb_detach_irq(dev); |
| 478 | tc6393xb_detach_irq(dev); | ||
| 479 | 510 | ||
| 480 | err_gpio_add: | 511 | err_gpio_add: |
| 481 | if (tc6393xb->gpio.base != -1) | 512 | if (tc6393xb->gpio.base != -1) |
| @@ -490,10 +521,11 @@ err_ioremap: | |||
| 490 | release_resource(&tc6393xb->rscr); | 521 | release_resource(&tc6393xb->rscr); |
| 491 | err_request_scr: | 522 | err_request_scr: |
| 492 | clk_put(tc6393xb->clk); | 523 | clk_put(tc6393xb->clk); |
| 524 | err_noirq: | ||
| 493 | err_clk_get: | 525 | err_clk_get: |
| 494 | kfree(tc6393xb); | 526 | kfree(tc6393xb); |
| 495 | err_kzalloc: | 527 | err_kzalloc: |
| 496 | return retval; | 528 | return ret; |
| 497 | } | 529 | } |
| 498 | 530 | ||
| 499 | static int __devexit tc6393xb_remove(struct platform_device *dev) | 531 | static int __devexit tc6393xb_remove(struct platform_device *dev) |
| @@ -503,9 +535,7 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) | |||
| 503 | int ret; | 535 | int ret; |
| 504 | 536 | ||
| 505 | mfd_remove_devices(&dev->dev); | 537 | mfd_remove_devices(&dev->dev); |
| 506 | 538 | tc6393xb_detach_irq(dev); | |
| 507 | if (tc6393xb->irq) | ||
| 508 | tc6393xb_detach_irq(dev); | ||
| 509 | 539 | ||
| 510 | if (tc6393xb->gpio.base != -1) { | 540 | if (tc6393xb->gpio.base != -1) { |
| 511 | ret = gpiochip_remove(&tc6393xb->gpio); | 541 | ret = gpiochip_remove(&tc6393xb->gpio); |
| @@ -516,17 +546,11 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) | |||
| 516 | } | 546 | } |
| 517 | 547 | ||
| 518 | ret = tcpd->disable(dev); | 548 | ret = tcpd->disable(dev); |
| 519 | |||
| 520 | clk_disable(tc6393xb->clk); | 549 | clk_disable(tc6393xb->clk); |
| 521 | |||
| 522 | iounmap(tc6393xb->scr); | 550 | iounmap(tc6393xb->scr); |
| 523 | |||
| 524 | release_resource(&tc6393xb->rscr); | 551 | release_resource(&tc6393xb->rscr); |
| 525 | |||
| 526 | platform_set_drvdata(dev, NULL); | 552 | platform_set_drvdata(dev, NULL); |
| 527 | |||
| 528 | clk_put(tc6393xb->clk); | 553 | clk_put(tc6393xb->clk); |
| 529 | |||
| 530 | kfree(tc6393xb); | 554 | kfree(tc6393xb); |
| 531 | 555 | ||
| 532 | return ret; | 556 | return ret; |
| @@ -537,8 +561,7 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) | |||
| 537 | { | 561 | { |
| 538 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 562 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
| 539 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | 563 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); |
| 540 | int i; | 564 | int i, ret; |
| 541 | |||
| 542 | 565 | ||
| 543 | tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); | 566 | tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); |
| 544 | tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); | 567 | tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); |
| @@ -551,14 +574,21 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) | |||
| 551 | tc6393xb->suspend_state.gpi_bcr[i] = | 574 | tc6393xb->suspend_state.gpi_bcr[i] = |
| 552 | ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); | 575 | ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); |
| 553 | } | 576 | } |
| 577 | ret = tcpd->suspend(dev); | ||
| 578 | clk_disable(tc6393xb->clk); | ||
| 554 | 579 | ||
| 555 | return tcpd->suspend(dev); | 580 | return ret; |
| 556 | } | 581 | } |
| 557 | 582 | ||
| 558 | static int tc6393xb_resume(struct platform_device *dev) | 583 | static int tc6393xb_resume(struct platform_device *dev) |
| 559 | { | 584 | { |
| 560 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 585 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
| 561 | int ret = tcpd->resume(dev); | 586 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); |
| 587 | int ret; | ||
| 588 | |||
| 589 | clk_enable(tc6393xb->clk); | ||
| 590 | |||
| 591 | ret = tcpd->resume(dev); | ||
| 562 | 592 | ||
| 563 | if (ret) | 593 | if (ret) |
| 564 | return ret; | 594 | return ret; |
| @@ -595,7 +625,7 @@ static void __exit tc6393xb_exit(void) | |||
| 595 | subsys_initcall(tc6393xb_init); | 625 | subsys_initcall(tc6393xb_init); |
| 596 | module_exit(tc6393xb_exit); | 626 | module_exit(tc6393xb_exit); |
| 597 | 627 | ||
| 598 | MODULE_LICENSE("GPL"); | 628 | MODULE_LICENSE("GPL v2"); |
| 599 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); | 629 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); |
| 600 | MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); | 630 | MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); |
| 601 | MODULE_ALIAS("platform:tc6393xb"); | 631 | MODULE_ALIAS("platform:tc6393xb"); |
diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h index 7cc824a58f7c..fec7b3f7a81f 100644 --- a/include/linux/mfd/tc6393xb.h +++ b/include/linux/mfd/tc6393xb.h | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #ifndef TC6393XB_H | 17 | #ifndef MFD_TC6393XB_H |
| 18 | #define TC6393XB_H | 18 | #define MFD_TC6393XB_H |
| 19 | 19 | ||
| 20 | /* Also one should provide the CK3P6MI clock */ | 20 | /* Also one should provide the CK3P6MI clock */ |
| 21 | struct tc6393xb_platform_data { | 21 | struct tc6393xb_platform_data { |
| @@ -29,7 +29,7 @@ struct tc6393xb_platform_data { | |||
| 29 | int (*suspend)(struct platform_device *dev); | 29 | int (*suspend)(struct platform_device *dev); |
| 30 | int (*resume)(struct platform_device *dev); | 30 | int (*resume)(struct platform_device *dev); |
| 31 | 31 | ||
| 32 | int irq_base; /* a base for cascaded irq */ | 32 | int irq_base; /* base for subdevice irqs */ |
| 33 | int gpio_base; | 33 | int gpio_base; |
| 34 | 34 | ||
| 35 | struct tmio_nand_data *nand_data; | 35 | struct tmio_nand_data *nand_data; |
| @@ -40,9 +40,6 @@ struct tc6393xb_platform_data { | |||
| 40 | */ | 40 | */ |
| 41 | #define IRQ_TC6393_NAND 0 | 41 | #define IRQ_TC6393_NAND 0 |
| 42 | #define IRQ_TC6393_MMC 1 | 42 | #define IRQ_TC6393_MMC 1 |
| 43 | #define IRQ_TC6393_OHCI 2 | ||
| 44 | #define IRQ_TC6393_SERIAL 3 | ||
| 45 | #define IRQ_TC6393_FB 4 | ||
| 46 | 43 | ||
| 47 | #define TC6393XB_NR_IRQS 8 | 44 | #define TC6393XB_NR_IRQS 8 |
| 48 | 45 | ||
