diff options
author | Ian Molton <spyro@f2s.com> | 2008-08-10 17:32:07 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@openedhand.com> | 2008-08-10 17:32:07 -0400 |
commit | 25d6cbd840d958aada29a342c9ee370590ff7b21 (patch) | |
tree | 7b2bcc92ad14d046a1c0beb5e8edb732e819eaa4 /drivers/mfd/tc6393xb.c | |
parent | 1c2c30acc52320d506d722f41d50e8eb8fda5cb5 (diff) |
mfd: tc6393 cleanup and update
This patchset cleans up the TC6393XB support.
* Add provision for the MMC subdevice
* Disable / enable clocks on suspend / resume
* Remove fragments of badly merged code (eg. linux/fb include etc.)
* Use a device specific clock name to break dependancy on ARM/PXA2XX
* Drop unnecessary resource names
* Switch to tmio_io* accessors
Signed-off-by: Ian Molton <spyro@f2s.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
Diffstat (limited to 'drivers/mfd/tc6393xb.c')
-rw-r--r-- | drivers/mfd/tc6393xb.c | 156 |
1 files changed, 93 insertions, 63 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"); |