From 1c1b6ffce5737d764cc474b9bd6677bb9a344094 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 24 Sep 2008 23:36:23 +0200 Subject: mfd: provide and use setup hook for tc6393xb Instead of using bitfields for initial gpio setup, provide generic setup/teardown hooks that can be used to set the gpio states, register child devices, etc. Signed-off-by: Dmitry Baryshkov Signed-off-by: Samuel Ortiz --- arch/arm/mach-pxa/include/mach/tosa.h | 2 -- arch/arm/mach-pxa/tosa.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index a72803f0461b..8bce6d8615b9 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -59,8 +59,6 @@ * TC6393XB GPIOs */ #define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12) -#define TOSA_TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i)) -#define TOSA_TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE)) #define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0) #define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1) diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 130e37e4ebdd..fac846b0d070 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -706,16 +706,39 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = { .badblock_pattern = &tosa_tc6393xb_nand_bbt, }; -static struct tc6393xb_platform_data tosa_tc6393xb_setup = { +static int tosa_tc6393xb_setup(struct platform_device *dev) +{ + int rc; + + rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON"); + if (rc) + goto err_req; + + rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1); + if (rc) + goto err_dir; + + return rc; + +err_dir: + gpio_free(TOSA_GPIO_CARD_VCC_ON); +err_req: + return rc; +} + +static void tosa_tc6393xb_teardown(struct platform_device *dev) +{ + gpio_free(TOSA_GPIO_CARD_VCC_ON); +} + +static struct tc6393xb_platform_data tosa_tc6393xb_data = { .scr_pll2cr = 0x0cc1, .scr_gper = 0x3300, - .scr_gpo_dsr = - TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), - .scr_gpo_doecr = - TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), .irq_base = IRQ_BOARD_START, .gpio_base = TOSA_TC6393XB_GPIO_BASE, + .setup = tosa_tc6393xb_setup, + .teardown = tosa_tc6393xb_teardown, .enable = tosa_tc6393xb_enable, .disable = tosa_tc6393xb_disable, @@ -730,7 +753,7 @@ static struct platform_device tc6393xb_device = { .name = "tc6393xb", .id = -1, .dev = { - .platform_data = &tosa_tc6393xb_setup, + .platform_data = &tosa_tc6393xb_data, }, .num_resources = ARRAY_SIZE(tc6393xb_resources), .resource = tc6393xb_resources, -- cgit v1.2.3-58-ga151 From f98a0bd0e4b77b12e49ce01f4c9f04503931c291 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 24 Sep 2008 23:46:10 +0200 Subject: mfd: do tcb6393xb state restore on resume only if requested As requested by Ian make state restore only if it's requested by platform data: some platforms do correctly save the state of the chip during suspend/resume, but some (like tosa) incorrectly power off the chip at suspend, so the driver supports restoring some bits of the tc6393xb state (not full, merely enough to support resume on tosa). With this patch this code is disabled by default. Signed-off-by: Dmitry Baryshkov Acked-by: Ian Molton Signed-off-by: Samuel Ortiz --- arch/arm/mach-pxa/tosa.c | 2 ++ drivers/mfd/tc6393xb.c | 74 ++++++++++++++++++++------------------------ include/linux/mfd/tc6393xb.h | 4 +++ 3 files changed, 40 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index fac846b0d070..a6c4694359ca 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -746,6 +746,8 @@ static struct tc6393xb_platform_data tosa_tc6393xb_data = { .resume = tosa_tc6393xb_resume, .nand_data = &tosa_tc6393xb_nand_config, + + .resume_restore = 1, }; diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 83dc703f3767..c3c64aeeb12a 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -369,41 +369,12 @@ static void tc6393xb_detach_irq(struct platform_device *dev) /*--------------------------------------------------------------------------*/ -static int tc6393xb_hw_init(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - int i; - - iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); - iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); - iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); - iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | - SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | - BIT(15), tc6393xb->scr + SCR_MCR); - iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); - iowrite8(0, tc6393xb->scr + SCR_IRR); - iowrite8(0xbf, tc6393xb->scr + SCR_IMR); - - for (i = 0; i < 3; i++) { - iowrite8(tc6393xb->suspend_state.gpo_dsr[i], - tc6393xb->scr + SCR_GPO_DSR(i)); - iowrite8(tc6393xb->suspend_state.gpo_doecr[i], - tc6393xb->scr + SCR_GPO_DOECR(i)); - iowrite8(tc6393xb->suspend_state.gpi_bcr[i], - tc6393xb->scr + SCR_GPI_BCR(i)); - } - - return 0; -} - static int __devinit tc6393xb_probe(struct platform_device *dev) { struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; struct tc6393xb *tc6393xb; struct resource *iomem, *rscr; int ret, temp; - int i; iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!iomem) @@ -458,14 +429,16 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) if (ret) goto err_enable; - tc6393xb->suspend_state.fer = 0; - - tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | - SCR_CCR_HCLK_48; - - ret = tc6393xb_hw_init(dev); - if (ret) - goto err_hw_init; + iowrite8(0, tc6393xb->scr + SCR_FER); + iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); + iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48, + tc6393xb->scr + SCR_CCR); + iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | + SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | + BIT(15), tc6393xb->scr + SCR_MCR); + iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); + iowrite8(0, tc6393xb->scr + SCR_IRR); + iowrite8(0xbf, tc6393xb->scr + SCR_IMR); printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", tmio_ioread8(tc6393xb->scr + SCR_REVID), @@ -514,7 +487,6 @@ err_setup: err_gpio_add: if (tc6393xb->gpio.base != -1) temp = gpiochip_remove(&tc6393xb->gpio); -err_hw_init: tcpd->disable(dev); err_clk_enable: clk_disable(tc6393xb->clk); @@ -592,15 +564,37 @@ static int tc6393xb_resume(struct platform_device *dev) struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; struct tc6393xb *tc6393xb = platform_get_drvdata(dev); int ret; + int i; clk_enable(tc6393xb->clk); ret = tcpd->resume(dev); - if (ret) return ret; - return tc6393xb_hw_init(dev); + if (!tcpd->resume_restore) + return 0; + + iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); + iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); + iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); + iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | + SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | + BIT(15), tc6393xb->scr + SCR_MCR); + iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); + iowrite8(0, tc6393xb->scr + SCR_IRR); + iowrite8(0xbf, tc6393xb->scr + SCR_IMR); + + for (i = 0; i < 3; i++) { + iowrite8(tc6393xb->suspend_state.gpo_dsr[i], + tc6393xb->scr + SCR_GPO_DSR(i)); + iowrite8(tc6393xb->suspend_state.gpo_doecr[i], + tc6393xb->scr + SCR_GPO_DOECR(i)); + iowrite8(tc6393xb->suspend_state.gpi_bcr[i], + tc6393xb->scr + SCR_GPI_BCR(i)); + } + + return 0; } #else #define tc6393xb_suspend NULL diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h index 1fa820646d98..3ce10ae0f397 100644 --- a/include/linux/mfd/tc6393xb.h +++ b/include/linux/mfd/tc6393xb.h @@ -33,6 +33,10 @@ struct tc6393xb_platform_data { void (*teardown)(struct platform_device *dev); struct tmio_nand_data *nand_data; + + unsigned resume_restore : 1; /* make special actions + to preserve the state + on suspend/resume */ }; /* -- cgit v1.2.3-58-ga151