Skip to content

Commit 25d6cbd

Browse files
Ian MoltonSamuel Ortiz
authored andcommitted
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>
1 parent 1c2c30a commit 25d6cbd

File tree

2 files changed

+96
-69
lines changed

2 files changed

+96
-69
lines changed

drivers/mfd/tc6393xb.c

Lines changed: 93 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#include <linux/io.h>
2020
#include <linux/irq.h>
2121
#include <linux/platform_device.h>
22-
#include <linux/fb.h>
2322
#include <linux/clk.h>
23+
#include <linux/err.h>
2424
#include <linux/mfd/core.h>
2525
#include <linux/mfd/tmio.h>
2626
#include <linux/mfd/tc6393xb.h>
@@ -112,6 +112,7 @@ struct tc6393xb {
112112

113113
enum {
114114
TC6393XB_CELL_NAND,
115+
TC6393XB_CELL_MMC,
115116
};
116117

117118
/*--------------------------------------------------------------------------*/
@@ -126,7 +127,7 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
126127

127128
/* SMD buffer on */
128129
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));
130131

131132
spin_unlock_irqrestore(&tc6393xb->lock, flags);
132133

@@ -135,13 +136,13 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
135136

136137
static struct resource __devinitdata tc6393xb_nand_resources[] = {
137138
{
138-
.start = 0x0100,
139-
.end = 0x01ff,
139+
.start = 0x1000,
140+
.end = 0x1007,
140141
.flags = IORESOURCE_MEM,
141142
},
142143
{
143-
.start = 0x1000,
144-
.end = 0x1007,
144+
.start = 0x0100,
145+
.end = 0x01ff,
145146
.flags = IORESOURCE_MEM,
146147
},
147148
{
@@ -151,13 +152,36 @@ static struct resource __devinitdata tc6393xb_nand_resources[] = {
151152
},
152153
};
153154

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+
154173
static struct mfd_cell __devinitdata tc6393xb_cells[] = {
155174
[TC6393XB_CELL_NAND] = {
156175
.name = "tmio-nand",
157176
.enable = tc6393xb_nand_enable,
158177
.num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
159178
.resources = tc6393xb_nand_resources,
160179
},
180+
[TC6393XB_CELL_MMC] = {
181+
.name = "tmio-mmc",
182+
.num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
183+
.resources = tc6393xb_mmc_resources,
184+
},
161185
};
162186

163187
/*--------------------------------------------------------------------------*/
@@ -168,7 +192,7 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip,
168192
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
169193

170194
/* 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))
172196
& TC_GPIO_BIT(offset);
173197
}
174198

@@ -178,13 +202,13 @@ static void __tc6393xb_gpio_set(struct gpio_chip *chip,
178202
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
179203
u8 dsr;
180204

181-
dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
205+
dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
182206
if (value)
183207
dsr |= TC_GPIO_BIT(offset);
184208
else
185209
dsr &= ~TC_GPIO_BIT(offset);
186210

187-
iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
211+
tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
188212
}
189213

190214
static void tc6393xb_gpio_set(struct gpio_chip *chip,
@@ -209,9 +233,9 @@ static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
209233

210234
spin_lock_irqsave(&tc6393xb->lock, flags);
211235

212-
doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
236+
doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
213237
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));
215239

216240
spin_unlock_irqrestore(&tc6393xb->lock, flags);
217241

@@ -229,9 +253,9 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
229253

230254
__tc6393xb_gpio_set(chip, offset, value);
231255

232-
doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
256+
doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
233257
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));
235259

236260
spin_unlock_irqrestore(&tc6393xb->lock, flags);
237261

@@ -262,8 +286,8 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
262286

263287
irq_base = tc6393xb->irq_base;
264288

265-
while ((isr = ioread8(tc6393xb->scr + SCR_ISR) &
266-
~ioread8(tc6393xb->scr + SCR_IMR)))
289+
while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) &
290+
~tmio_ioread8(tc6393xb->scr + SCR_IMR)))
267291
for (i = 0; i < TC6393XB_NR_IRQS; i++) {
268292
if (isr & (1 << i))
269293
generic_handle_irq(irq_base + i);
@@ -281,9 +305,9 @@ static void tc6393xb_irq_mask(unsigned int irq)
281305
u8 imr;
282306

283307
spin_lock_irqsave(&tc6393xb->lock, flags);
284-
imr = ioread8(tc6393xb->scr + SCR_IMR);
308+
imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
285309
imr |= 1 << (irq - tc6393xb->irq_base);
286-
iowrite8(imr, tc6393xb->scr + SCR_IMR);
310+
tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
287311
spin_unlock_irqrestore(&tc6393xb->lock, flags);
288312
}
289313

@@ -294,9 +318,9 @@ static void tc6393xb_irq_unmask(unsigned int irq)
294318
u8 imr;
295319

296320
spin_lock_irqsave(&tc6393xb->lock, flags);
297-
imr = ioread8(tc6393xb->scr + SCR_IMR);
321+
imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
298322
imr &= ~(1 << (irq - tc6393xb->irq_base));
299-
iowrite8(imr, tc6393xb->scr + SCR_IMR);
323+
tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
300324
spin_unlock_irqrestore(&tc6393xb->lock, flags);
301325
}
302326

@@ -377,9 +401,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
377401
{
378402
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
379403
struct tc6393xb *tc6393xb;
380-
struct resource *iomem;
381-
struct resource *rscr;
382-
int retval, temp;
404+
struct resource *iomem, *rscr;
405+
int ret, temp;
383406
int i;
384407

385408
iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
@@ -388,20 +411,26 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
388411

389412
tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
390413
if (!tc6393xb) {
391-
retval = -ENOMEM;
414+
ret = -ENOMEM;
392415
goto err_kzalloc;
393416
}
394417

395418
spin_lock_init(&tc6393xb->lock);
396419

397420
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+
398428
tc6393xb->iomem = iomem;
399-
tc6393xb->irq = platform_get_irq(dev, 0);
400429
tc6393xb->irq_base = tcpd->irq_base;
401430

402-
tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */);
431+
tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI");
403432
if (IS_ERR(tc6393xb->clk)) {
404-
retval = PTR_ERR(tc6393xb->clk);
433+
ret = PTR_ERR(tc6393xb->clk);
405434
goto err_clk_get;
406435
}
407436

@@ -411,71 +440,73 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
411440
rscr->end = iomem->start + 0xff;
412441
rscr->flags = IORESOURCE_MEM;
413442

414-
retval = request_resource(iomem, rscr);
415-
if (retval)
443+
ret = request_resource(iomem, rscr);
444+
if (ret)
416445
goto err_request_scr;
417446

418447
tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
419448
if (!tc6393xb->scr) {
420-
retval = -ENOMEM;
449+
ret = -ENOMEM;
421450
goto err_ioremap;
422451
}
423452

424-
retval = clk_enable(tc6393xb->clk);
425-
if (retval)
453+
ret = clk_enable(tc6393xb->clk);
454+
if (ret)
426455
goto err_clk_enable;
427456

428-
retval = tcpd->enable(dev);
429-
if (retval)
457+
ret = tcpd->enable(dev);
458+
if (ret)
430459
goto err_enable;
431460

432461
tc6393xb->suspend_state.fer = 0;
462+
433463
for (i = 0; i < 3; i++) {
434464
tc6393xb->suspend_state.gpo_dsr[i] =
435465
(tcpd->scr_gpo_dsr >> (8 * i)) & 0xff;
436466
tc6393xb->suspend_state.gpo_doecr[i] =
437467
(tcpd->scr_gpo_doecr >> (8 * i)) & 0xff;
438468
}
439-
/*
440-
* It may be necessary to change this back to
441-
* platform-dependant code
442-
*/
469+
443470
tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 |
444471
SCR_CCR_HCLK_48;
445472

446-
retval = tc6393xb_hw_init(dev);
447-
if (retval)
473+
ret = tc6393xb_hw_init(dev);
474+
if (ret)
448475
goto err_hw_init;
449476

450477
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),
452479
(unsigned long) iomem->start, tc6393xb->irq);
453480

454481
tc6393xb->gpio.base = -1;
455482

456483
if (tcpd->gpio_base >= 0) {
457-
retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
458-
if (retval)
484+
ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
485+
if (ret)
459486
goto err_gpio_add;
460487
}
461488

462-
if (tc6393xb->irq)
463-
tc6393xb_attach_irq(dev);
489+
tc6393xb_attach_irq(dev);
464490

465491
tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data;
466492
tc6393xb_cells[TC6393XB_CELL_NAND].platform_data =
467493
&tc6393xb_cells[TC6393XB_CELL_NAND];
468494
tc6393xb_cells[TC6393XB_CELL_NAND].data_size =
469495
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+
470501

471-
retval = mfd_add_devices(&dev->dev, dev->id,
502+
ret = mfd_add_devices(&dev->dev, dev->id,
472503
tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
473504
iomem, tcpd->irq_base);
474505

475-
return 0;
506+
if (!ret)
507+
return 0;
476508

477-
if (tc6393xb->irq)
478-
tc6393xb_detach_irq(dev);
509+
tc6393xb_detach_irq(dev);
479510

480511
err_gpio_add:
481512
if (tc6393xb->gpio.base != -1)
@@ -490,10 +521,11 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
490521
release_resource(&tc6393xb->rscr);
491522
err_request_scr:
492523
clk_put(tc6393xb->clk);
524+
err_noirq:
493525
err_clk_get:
494526
kfree(tc6393xb);
495527
err_kzalloc:
496-
return retval;
528+
return ret;
497529
}
498530

499531
static int __devexit tc6393xb_remove(struct platform_device *dev)
@@ -503,9 +535,7 @@ static int __devexit tc6393xb_remove(struct platform_device *dev)
503535
int ret;
504536

505537
mfd_remove_devices(&dev->dev);
506-
507-
if (tc6393xb->irq)
508-
tc6393xb_detach_irq(dev);
538+
tc6393xb_detach_irq(dev);
509539

510540
if (tc6393xb->gpio.base != -1) {
511541
ret = gpiochip_remove(&tc6393xb->gpio);
@@ -516,17 +546,11 @@ static int __devexit tc6393xb_remove(struct platform_device *dev)
516546
}
517547

518548
ret = tcpd->disable(dev);
519-
520549
clk_disable(tc6393xb->clk);
521-
522550
iounmap(tc6393xb->scr);
523-
524551
release_resource(&tc6393xb->rscr);
525-
526552
platform_set_drvdata(dev, NULL);
527-
528553
clk_put(tc6393xb->clk);
529-
530554
kfree(tc6393xb);
531555

532556
return ret;
@@ -537,8 +561,7 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
537561
{
538562
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
539563
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
540-
int i;
541-
564+
int i, ret;
542565

543566
tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
544567
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)
551574
tc6393xb->suspend_state.gpi_bcr[i] =
552575
ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
553576
}
577+
ret = tcpd->suspend(dev);
578+
clk_disable(tc6393xb->clk);
554579

555-
return tcpd->suspend(dev);
580+
return ret;
556581
}
557582

558583
static int tc6393xb_resume(struct platform_device *dev)
559584
{
560585
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);
562592

563593
if (ret)
564594
return ret;
@@ -595,7 +625,7 @@ static void __exit tc6393xb_exit(void)
595625
subsys_initcall(tc6393xb_init);
596626
module_exit(tc6393xb_exit);
597627

598-
MODULE_LICENSE("GPL");
628+
MODULE_LICENSE("GPL v2");
599629
MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
600630
MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
601631
MODULE_ALIAS("platform:tc6393xb");

0 commit comments

Comments
 (0)