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"); |