diff options
Diffstat (limited to 'drivers/mfd/tc6393xb.c')
| -rw-r--r-- | drivers/mfd/tc6393xb.c | 159 |
1 files changed, 93 insertions, 66 deletions
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index f4fd797c1590..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,25 +136,40 @@ 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 | .name = TMIO_NAND_CONFIG, | 139 | .start = 0x1000, |
| 139 | .start = 0x0100, | 140 | .end = 0x1007, |
| 140 | .end = 0x01ff, | ||
| 141 | .flags = IORESOURCE_MEM, | 141 | .flags = IORESOURCE_MEM, |
| 142 | }, | 142 | }, |
| 143 | { | 143 | { |
| 144 | .name = TMIO_NAND_CONTROL, | 144 | .start = 0x0100, |
| 145 | .start = 0x1000, | 145 | .end = 0x01ff, |
| 146 | .end = 0x1007, | ||
| 147 | .flags = IORESOURCE_MEM, | 146 | .flags = IORESOURCE_MEM, |
| 148 | }, | 147 | }, |
| 149 | { | 148 | { |
| 150 | .name = TMIO_NAND_IRQ, | ||
| 151 | .start = IRQ_TC6393_NAND, | 149 | .start = IRQ_TC6393_NAND, |
| 152 | .end = IRQ_TC6393_NAND, | 150 | .end = IRQ_TC6393_NAND, |
| 153 | .flags = IORESOURCE_IRQ, | 151 | .flags = IORESOURCE_IRQ, |
| 154 | }, | 152 | }, |
| 155 | }; | 153 | }; |
| 156 | 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 | |||
| 157 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { | 173 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { |
| 158 | [TC6393XB_CELL_NAND] = { | 174 | [TC6393XB_CELL_NAND] = { |
| 159 | .name = "tmio-nand", | 175 | .name = "tmio-nand", |
| @@ -161,6 +177,11 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { | |||
| 161 | .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), | 177 | .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), |
| 162 | .resources = tc6393xb_nand_resources, | 178 | .resources = tc6393xb_nand_resources, |
| 163 | }, | 179 | }, |
| 180 | [TC6393XB_CELL_MMC] = { | ||
| 181 | .name = "tmio-mmc", | ||
| 182 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), | ||
| 183 | .resources = tc6393xb_mmc_resources, | ||
| 184 | }, | ||
| 164 | }; | 185 | }; |
| 165 | 186 | ||
| 166 | /*--------------------------------------------------------------------------*/ | 187 | /*--------------------------------------------------------------------------*/ |
| @@ -171,7 +192,7 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip, | |||
| 171 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); | 192 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); |
| 172 | 193 | ||
| 173 | /* XXX: does dsr also represent inputs? */ | 194 | /* XXX: does dsr also represent inputs? */ |
| 174 | return ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) | 195 | return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) |
| 175 | & TC_GPIO_BIT(offset); | 196 | & TC_GPIO_BIT(offset); |
| 176 | } | 197 | } |
| 177 | 198 | ||
| @@ -181,13 +202,13 @@ static void __tc6393xb_gpio_set(struct gpio_chip *chip, | |||
| 181 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); | 202 | struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); |
| 182 | u8 dsr; | 203 | u8 dsr; |
| 183 | 204 | ||
| 184 | dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); | 205 | dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); |
| 185 | if (value) | 206 | if (value) |
| 186 | dsr |= TC_GPIO_BIT(offset); | 207 | dsr |= TC_GPIO_BIT(offset); |
| 187 | else | 208 | else |
| 188 | dsr &= ~TC_GPIO_BIT(offset); | 209 | dsr &= ~TC_GPIO_BIT(offset); |
| 189 | 210 | ||
| 190 | iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); | 211 | tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); |
| 191 | } | 212 | } |
| 192 | 213 | ||
| 193 | static void tc6393xb_gpio_set(struct gpio_chip *chip, | 214 | static void tc6393xb_gpio_set(struct gpio_chip *chip, |
| @@ -212,9 +233,9 @@ static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, | |||
| 212 | 233 | ||
| 213 | spin_lock_irqsave(&tc6393xb->lock, flags); | 234 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 214 | 235 | ||
| 215 | doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 236 | doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 216 | doecr &= ~TC_GPIO_BIT(offset); | 237 | doecr &= ~TC_GPIO_BIT(offset); |
| 217 | iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 238 | tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 218 | 239 | ||
| 219 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 240 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 220 | 241 | ||
| @@ -232,9 +253,9 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, | |||
| 232 | 253 | ||
| 233 | __tc6393xb_gpio_set(chip, offset, value); | 254 | __tc6393xb_gpio_set(chip, offset, value); |
| 234 | 255 | ||
| 235 | doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 256 | doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 236 | doecr |= TC_GPIO_BIT(offset); | 257 | doecr |= TC_GPIO_BIT(offset); |
| 237 | iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); | 258 | tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); |
| 238 | 259 | ||
| 239 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 260 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 240 | 261 | ||
| @@ -265,8 +286,8 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc) | |||
| 265 | 286 | ||
| 266 | irq_base = tc6393xb->irq_base; | 287 | irq_base = tc6393xb->irq_base; |
| 267 | 288 | ||
| 268 | while ((isr = ioread8(tc6393xb->scr + SCR_ISR) & | 289 | while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) & |
| 269 | ~ioread8(tc6393xb->scr + SCR_IMR))) | 290 | ~tmio_ioread8(tc6393xb->scr + SCR_IMR))) |
| 270 | for (i = 0; i < TC6393XB_NR_IRQS; i++) { | 291 | for (i = 0; i < TC6393XB_NR_IRQS; i++) { |
| 271 | if (isr & (1 << i)) | 292 | if (isr & (1 << i)) |
| 272 | generic_handle_irq(irq_base + i); | 293 | generic_handle_irq(irq_base + i); |
| @@ -284,9 +305,9 @@ static void tc6393xb_irq_mask(unsigned int irq) | |||
| 284 | u8 imr; | 305 | u8 imr; |
| 285 | 306 | ||
| 286 | spin_lock_irqsave(&tc6393xb->lock, flags); | 307 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 287 | imr = ioread8(tc6393xb->scr + SCR_IMR); | 308 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 288 | imr |= 1 << (irq - tc6393xb->irq_base); | 309 | imr |= 1 << (irq - tc6393xb->irq_base); |
| 289 | iowrite8(imr, tc6393xb->scr + SCR_IMR); | 310 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 290 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 311 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 291 | } | 312 | } |
| 292 | 313 | ||
| @@ -297,9 +318,9 @@ static void tc6393xb_irq_unmask(unsigned int irq) | |||
| 297 | u8 imr; | 318 | u8 imr; |
| 298 | 319 | ||
| 299 | spin_lock_irqsave(&tc6393xb->lock, flags); | 320 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 300 | imr = ioread8(tc6393xb->scr + SCR_IMR); | 321 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 301 | imr &= ~(1 << (irq - tc6393xb->irq_base)); | 322 | imr &= ~(1 << (irq - tc6393xb->irq_base)); |
| 302 | iowrite8(imr, tc6393xb->scr + SCR_IMR); | 323 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 303 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 324 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 304 | } | 325 | } |
| 305 | 326 | ||
| @@ -380,9 +401,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
| 380 | { | 401 | { |
| 381 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 402 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
| 382 | struct tc6393xb *tc6393xb; | 403 | struct tc6393xb *tc6393xb; |
| 383 | struct resource *iomem; | 404 | struct resource *iomem, *rscr; |
| 384 | struct resource *rscr; | 405 | int ret, temp; |
| 385 | int retval, temp; | ||
| 386 | int i; | 406 | int i; |
| 387 | 407 | ||
| 388 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 408 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
| @@ -391,20 +411,26 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
| 391 | 411 | ||
| 392 | tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); | 412 | tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); |
| 393 | if (!tc6393xb) { | 413 | if (!tc6393xb) { |
| 394 | retval = -ENOMEM; | 414 | ret = -ENOMEM; |
| 395 | goto err_kzalloc; | 415 | goto err_kzalloc; |
| 396 | } | 416 | } |
| 397 | 417 | ||
| 398 | spin_lock_init(&tc6393xb->lock); | 418 | spin_lock_init(&tc6393xb->lock); |
| 399 | 419 | ||
| 400 | 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 | |||
| 401 | tc6393xb->iomem = iomem; | 428 | tc6393xb->iomem = iomem; |
| 402 | tc6393xb->irq = platform_get_irq(dev, 0); | ||
| 403 | tc6393xb->irq_base = tcpd->irq_base; | 429 | tc6393xb->irq_base = tcpd->irq_base; |
| 404 | 430 | ||
| 405 | tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */); | 431 | tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI"); |
| 406 | if (IS_ERR(tc6393xb->clk)) { | 432 | if (IS_ERR(tc6393xb->clk)) { |
| 407 | retval = PTR_ERR(tc6393xb->clk); | 433 | ret = PTR_ERR(tc6393xb->clk); |
| 408 | goto err_clk_get; | 434 | goto err_clk_get; |
| 409 | } | 435 | } |
| 410 | 436 | ||
| @@ -414,71 +440,73 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
| 414 | rscr->end = iomem->start + 0xff; | 440 | rscr->end = iomem->start + 0xff; |
| 415 | rscr->flags = IORESOURCE_MEM; | 441 | rscr->flags = IORESOURCE_MEM; |
| 416 | 442 | ||
| 417 | retval = request_resource(iomem, rscr); | 443 | ret = request_resource(iomem, rscr); |
| 418 | if (retval) | 444 | if (ret) |
| 419 | goto err_request_scr; | 445 | goto err_request_scr; |
| 420 | 446 | ||
| 421 | tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); | 447 | tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); |
| 422 | if (!tc6393xb->scr) { | 448 | if (!tc6393xb->scr) { |
| 423 | retval = -ENOMEM; | 449 | ret = -ENOMEM; |
| 424 | goto err_ioremap; | 450 | goto err_ioremap; |
| 425 | } | 451 | } |
| 426 | 452 | ||
| 427 | retval = clk_enable(tc6393xb->clk); | 453 | ret = clk_enable(tc6393xb->clk); |
| 428 | if (retval) | 454 | if (ret) |
| 429 | goto err_clk_enable; | 455 | goto err_clk_enable; |
| 430 | 456 | ||
| 431 | retval = tcpd->enable(dev); | 457 | ret = tcpd->enable(dev); |
| 432 | if (retval) | 458 | if (ret) |
| 433 | goto err_enable; | 459 | goto err_enable; |
| 434 | 460 | ||
| 435 | tc6393xb->suspend_state.fer = 0; | 461 | tc6393xb->suspend_state.fer = 0; |
| 462 | |||
| 436 | for (i = 0; i < 3; i++) { | 463 | for (i = 0; i < 3; i++) { |
| 437 | tc6393xb->suspend_state.gpo_dsr[i] = | 464 | tc6393xb->suspend_state.gpo_dsr[i] = |
| 438 | (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; | 465 | (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; |
| 439 | tc6393xb->suspend_state.gpo_doecr[i] = | 466 | tc6393xb->suspend_state.gpo_doecr[i] = |
| 440 | (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; | 467 | (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; |
| 441 | } | 468 | } |
| 442 | /* | 469 | |
| 443 | * It may be necessary to change this back to | ||
| 444 | * platform-dependant code | ||
| 445 | */ | ||
| 446 | tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | | 470 | tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | |
| 447 | SCR_CCR_HCLK_48; | 471 | SCR_CCR_HCLK_48; |
| 448 | 472 | ||
| 449 | retval = tc6393xb_hw_init(dev); | 473 | ret = tc6393xb_hw_init(dev); |
| 450 | if (retval) | 474 | if (ret) |
| 451 | goto err_hw_init; | 475 | goto err_hw_init; |
| 452 | 476 | ||
| 453 | 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", |
| 454 | ioread8(tc6393xb->scr + SCR_REVID), | 478 | tmio_ioread8(tc6393xb->scr + SCR_REVID), |
| 455 | (unsigned long) iomem->start, tc6393xb->irq); | 479 | (unsigned long) iomem->start, tc6393xb->irq); |
| 456 | 480 | ||
| 457 | tc6393xb->gpio.base = -1; | 481 | tc6393xb->gpio.base = -1; |
| 458 | 482 | ||
| 459 | if (tcpd->gpio_base >= 0) { | 483 | if (tcpd->gpio_base >= 0) { |
| 460 | retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); | 484 | ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); |
| 461 | if (retval) | 485 | if (ret) |
| 462 | goto err_gpio_add; | 486 | goto err_gpio_add; |
| 463 | } | 487 | } |
| 464 | 488 | ||
| 465 | if (tc6393xb->irq) | 489 | tc6393xb_attach_irq(dev); |
| 466 | tc6393xb_attach_irq(dev); | ||
| 467 | 490 | ||
| 468 | tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; | 491 | tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; |
| 469 | tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = | 492 | tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = |
| 470 | &tc6393xb_cells[TC6393XB_CELL_NAND]; | 493 | &tc6393xb_cells[TC6393XB_CELL_NAND]; |
| 471 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = | 494 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = |
| 472 | 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 | |||
| 473 | 501 | ||
| 474 | retval = mfd_add_devices(&dev->dev, dev->id, | 502 | ret = mfd_add_devices(&dev->dev, dev->id, |
| 475 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 503 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |
| 476 | iomem, tcpd->irq_base); | 504 | iomem, tcpd->irq_base); |
| 477 | 505 | ||
| 478 | return 0; | 506 | if (!ret) |
| 507 | return 0; | ||
| 479 | 508 | ||
| 480 | if (tc6393xb->irq) | 509 | tc6393xb_detach_irq(dev); |
| 481 | tc6393xb_detach_irq(dev); | ||
| 482 | 510 | ||
| 483 | err_gpio_add: | 511 | err_gpio_add: |
| 484 | if (tc6393xb->gpio.base != -1) | 512 | if (tc6393xb->gpio.base != -1) |
| @@ -493,10 +521,11 @@ err_ioremap: | |||
| 493 | release_resource(&tc6393xb->rscr); | 521 | release_resource(&tc6393xb->rscr); |
| 494 | err_request_scr: | 522 | err_request_scr: |
| 495 | clk_put(tc6393xb->clk); | 523 | clk_put(tc6393xb->clk); |
| 524 | err_noirq: | ||
| 496 | err_clk_get: | 525 | err_clk_get: |
| 497 | kfree(tc6393xb); | 526 | kfree(tc6393xb); |
| 498 | err_kzalloc: | 527 | err_kzalloc: |
| 499 | return retval; | 528 | return ret; |
| 500 | } | 529 | } |
| 501 | 530 | ||
| 502 | static int __devexit tc6393xb_remove(struct platform_device *dev) | 531 | static int __devexit tc6393xb_remove(struct platform_device *dev) |
| @@ -506,9 +535,7 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) | |||
| 506 | int ret; | 535 | int ret; |
| 507 | 536 | ||
| 508 | mfd_remove_devices(&dev->dev); | 537 | mfd_remove_devices(&dev->dev); |
| 509 | 538 | tc6393xb_detach_irq(dev); | |
| 510 | if (tc6393xb->irq) | ||
| 511 | tc6393xb_detach_irq(dev); | ||
| 512 | 539 | ||
| 513 | if (tc6393xb->gpio.base != -1) { | 540 | if (tc6393xb->gpio.base != -1) { |
| 514 | ret = gpiochip_remove(&tc6393xb->gpio); | 541 | ret = gpiochip_remove(&tc6393xb->gpio); |
| @@ -519,17 +546,11 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) | |||
| 519 | } | 546 | } |
| 520 | 547 | ||
| 521 | ret = tcpd->disable(dev); | 548 | ret = tcpd->disable(dev); |
| 522 | |||
| 523 | clk_disable(tc6393xb->clk); | 549 | clk_disable(tc6393xb->clk); |
| 524 | |||
| 525 | iounmap(tc6393xb->scr); | 550 | iounmap(tc6393xb->scr); |
| 526 | |||
| 527 | release_resource(&tc6393xb->rscr); | 551 | release_resource(&tc6393xb->rscr); |
| 528 | |||
| 529 | platform_set_drvdata(dev, NULL); | 552 | platform_set_drvdata(dev, NULL); |
| 530 | |||
| 531 | clk_put(tc6393xb->clk); | 553 | clk_put(tc6393xb->clk); |
| 532 | |||
| 533 | kfree(tc6393xb); | 554 | kfree(tc6393xb); |
| 534 | 555 | ||
| 535 | return ret; | 556 | return ret; |
| @@ -540,8 +561,7 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) | |||
| 540 | { | 561 | { |
| 541 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 562 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
| 542 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | 563 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); |
| 543 | int i; | 564 | int i, ret; |
| 544 | |||
| 545 | 565 | ||
| 546 | tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); | 566 | tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); |
| 547 | tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); | 567 | tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); |
| @@ -554,14 +574,21 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) | |||
| 554 | tc6393xb->suspend_state.gpi_bcr[i] = | 574 | tc6393xb->suspend_state.gpi_bcr[i] = |
| 555 | ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); | 575 | ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); |
| 556 | } | 576 | } |
| 577 | ret = tcpd->suspend(dev); | ||
| 578 | clk_disable(tc6393xb->clk); | ||
| 557 | 579 | ||
| 558 | return tcpd->suspend(dev); | 580 | return ret; |
| 559 | } | 581 | } |
| 560 | 582 | ||
| 561 | static int tc6393xb_resume(struct platform_device *dev) | 583 | static int tc6393xb_resume(struct platform_device *dev) |
| 562 | { | 584 | { |
| 563 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 585 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
| 564 | 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); | ||
| 565 | 592 | ||
| 566 | if (ret) | 593 | if (ret) |
| 567 | return ret; | 594 | return ret; |
| @@ -598,7 +625,7 @@ static void __exit tc6393xb_exit(void) | |||
| 598 | subsys_initcall(tc6393xb_init); | 625 | subsys_initcall(tc6393xb_init); |
| 599 | module_exit(tc6393xb_exit); | 626 | module_exit(tc6393xb_exit); |
| 600 | 627 | ||
| 601 | MODULE_LICENSE("GPL"); | 628 | MODULE_LICENSE("GPL v2"); |
| 602 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); | 629 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); |
| 603 | MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); | 630 | MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); |
| 604 | MODULE_ALIAS("platform:tc6393xb"); | 631 | MODULE_ALIAS("platform:tc6393xb"); |
