From c93ff6bf16523d33e991a1fadde1b8d63eb7cd2c Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov <roman.tereshonkov@nokia.com> Date: Thu, 17 Feb 2011 13:44:42 +0200 Subject: mtd: omap: add new variable to platform data to control onenand unlocking New variable skip_initial_unlocking is added to the omap_onenand_platform_data. This is used to inform the onenand driver to skip onenand unlocking when it is initialized. Signed-off-by: Roman Tereshonkov <roman.tereshonkov@nokia.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> --- arch/arm/plat-omap/include/plat/onenand.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm') diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h index affe87e9ece7..1b430d5fdd54 100644 --- a/arch/arm/plat-omap/include/plat/onenand.h +++ b/arch/arm/plat-omap/include/plat/onenand.h @@ -24,6 +24,7 @@ struct omap_onenand_platform_data { int dma_channel; u8 flags; u8 regulator_can_sleep; + u8 skip_initial_unlocking; }; #define ONENAND_MAX_PARTITIONS 8 -- cgit v1.2.3 From 4332c116869ceca58638beabd9e9a5d7db4cef83 Mon Sep 17 00:00:00 2001 From: Lei Wen <leiwen@marvell.com> Date: Thu, 3 Mar 2011 11:27:01 +0800 Subject: mtd: pxa3xx_nand: clean the keep configure code Use nand_scan_ident to unify the need of mtd member initilization for both normal detection and keep configuration method. Signed-off-by: Lei Wen <leiwen@marvell.com> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> --- arch/arm/plat-pxa/include/plat/pxa3xx_nand.h | 2 +- drivers/mtd/nand/pxa3xx_nand.c | 103 +++++++++------------------ 2 files changed, 36 insertions(+), 69 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h index 01a8448e471c..442301fe48b4 100644 --- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h +++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h @@ -30,6 +30,7 @@ struct pxa3xx_nand_cmdset { }; struct pxa3xx_nand_flash { + char *name; uint32_t chip_id; unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */ unsigned int page_size; /* Page size in bytes (PAGE_SZ) */ @@ -37,7 +38,6 @@ struct pxa3xx_nand_flash { unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ unsigned int num_blocks; /* Number of physical blocks in Flash */ - struct pxa3xx_nand_cmdset *cmdset; /* NAND command set */ struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ }; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index bb50cf2b11c4..ab7f4c33ced6 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -211,15 +211,15 @@ static struct pxa3xx_nand_timing timing[] = { }; static struct pxa3xx_nand_flash builtin_flash_types[] = { - { 0, 0, 2048, 8, 8, 0, &default_cmdset, &timing[0] }, - { 0x46ec, 32, 512, 16, 16, 4096, &default_cmdset, &timing[1] }, - { 0xdaec, 64, 2048, 8, 8, 2048, &default_cmdset, &timing[1] }, - { 0xd7ec, 128, 4096, 8, 8, 8192, &default_cmdset, &timing[1] }, - { 0xa12c, 64, 2048, 8, 8, 1024, &default_cmdset, &timing[2] }, - { 0xb12c, 64, 2048, 16, 16, 1024, &default_cmdset, &timing[2] }, - { 0xdc2c, 64, 2048, 8, 8, 4096, &default_cmdset, &timing[2] }, - { 0xcc2c, 64, 2048, 16, 16, 4096, &default_cmdset, &timing[2] }, - { 0xba20, 64, 2048, 16, 16, 2048, &default_cmdset, &timing[3] }, +{ "DEFAULT FLASH", 0, 0, 2048, 8, 8, 0, &timing[0] }, +{ "64MiB 16-bit", 0x46ec, 32, 512, 16, 16, 4096, &timing[1] }, +{ "256MiB 8-bit", 0xdaec, 64, 2048, 8, 8, 2048, &timing[1] }, +{ "4GiB 8-bit", 0xd7ec, 128, 4096, 8, 8, 8192, &timing[1] }, +{ "128MiB 8-bit", 0xa12c, 64, 2048, 8, 8, 1024, &timing[2] }, +{ "128MiB 16-bit", 0xb12c, 64, 2048, 16, 16, 1024, &timing[2] }, +{ "512MiB 8-bit", 0xdc2c, 64, 2048, 8, 8, 4096, &timing[2] }, +{ "512MiB 16-bit", 0xcc2c, 64, 2048, 16, 16, 4096, &timing[2] }, +{ "256MiB 16-bit", 0xba20, 64, 2048, 16, 16, 2048, &timing[3] }, }; /* Define a default flash type setting serve as flash detecting only */ @@ -779,9 +779,8 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, return -EINVAL; /* calculate flash information */ - info->cmdset = f->cmdset; + info->cmdset = &default_cmdset; info->page_size = f->page_size; - info->oob_buff = info->data_buff + f->page_size; info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; /* calculate addressing information */ @@ -811,45 +810,12 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) { uint32_t ndcr = nand_readl(info, NDCR); - struct nand_flash_dev *type = NULL; - uint32_t id = -1, page_per_block, num_blocks; - int i; - - page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32; info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; /* set info fields needed to read id */ info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; info->reg_ndcr = ndcr; info->cmdset = &default_cmdset; - pxa3xx_nand_cmdfunc(info->mtd, NAND_CMD_READID, 0, 0); - id = *((uint16_t *)(info->data_buff)); - if (id == 0) - return -ENODEV; - - /* Lookup the flash id */ - for (i = 0; nand_flash_ids[i].name != NULL; i++) { - if (id == nand_flash_ids[i].id) { - type = &nand_flash_ids[i]; - break; - } - } - - if (!type) - return -ENODEV; - - /* fill the missing flash information */ - i = __ffs(page_per_block * info->page_size); - num_blocks = type->chipsize << (20 - i); - - /* calculate addressing information */ - info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1; - - if (num_blocks * page_per_block > 65536) - info->row_addr_cycles = 3; - else - info->row_addr_cycles = 2; - info->ndtr0cs0 = nand_readl(info, NDTR0CS0); info->ndtr1cs0 = nand_readl(info, NDTR1CS0); @@ -916,13 +882,15 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) struct pxa3xx_nand_info *info = mtd->priv; struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; + struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} }; const struct pxa3xx_nand_flash *f = NULL; struct nand_chip *chip = mtd->priv; uint32_t id = -1; + uint64_t chipsize; int i, ret, num; if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) - return 0; + goto KEEP_CONFIG; ret = pxa3xx_nand_sensing(info); if (!ret) { @@ -953,22 +921,11 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) f = &builtin_flash_types[i - pdata->num_flash + 1]; /* find the chip in default list */ - if (f->chip_id == id) { - pxa3xx_nand_config_flash(info, f); - mtd->writesize = f->page_size; - mtd->writesize_shift = ffs(mtd->writesize) - 1; - mtd->writesize_mask = (1 << mtd->writesize_shift) - 1; - mtd->oobsize = mtd->writesize / 32; - mtd->erasesize = f->page_size * f->page_per_block; - mtd->erasesize_shift = ffs(mtd->erasesize) - 1; - mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1; - - mtd->name = mtd_names[0]; + if (f->chip_id == id) break; - } } - if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash)) { + if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) { kfree(mtd); info->mtd = NULL; printk(KERN_ERR "ERROR!! flash not defined!!!\n"); @@ -976,18 +933,28 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) return -EINVAL; } + pxa3xx_nand_config_flash(info, f); + pxa3xx_flash_ids[0].name = f->name; + pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff; + pxa3xx_flash_ids[0].pagesize = f->page_size; + chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size; + pxa3xx_flash_ids[0].chipsize = chipsize >> 20; + pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block; + if (f->flash_width == 16) + pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16; +KEEP_CONFIG: + if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids)) + return -ENODEV; + /* calculate addressing information */ + info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1; + info->oob_buff = info->data_buff + mtd->writesize; + if ((mtd->size >> chip->page_shift) > 65536) + info->row_addr_cycles = 3; + else + info->row_addr_cycles = 2; + mtd->name = mtd_names[0]; chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = f->page_size; - chip->chipsize = (uint64_t)f->num_blocks * f->page_per_block - * f->page_size; - mtd->size = chip->chipsize; - - /* Calculate the address shift from the page size */ - chip->page_shift = ffs(mtd->writesize) - 1; - chip->pagemask = mtd_div_by_ws(chip->chipsize, mtd) - 1; - chip->numchips = 1; - chip->phys_erase_shift = ffs(mtd->erasesize) - 1; - chip->bbt_erase_shift = chip->phys_erase_shift; chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0; chip->options |= NAND_NO_AUTOINCR; -- cgit v1.2.3 From 36133869c4b5b70e6acf6ff7ce25df526a6d5cae Mon Sep 17 00:00:00 2001 From: Aaro Koskinen <aaro.koskinen@nokia.com> Date: Fri, 18 Mar 2011 16:53:19 -0700 Subject: arm: mach-omap2: devices: fix omap3_l3_init() return value Fix the return value for the successful case. Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 0d2d6a9c303c..d478f53f9084 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -65,7 +65,7 @@ static int __init omap3_l3_init(void) WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name); - return PTR_ERR(od); + return IS_ERR(od) ? PTR_ERR(od) : 0; } postcore_initcall(omap3_l3_init); -- cgit v1.2.3 From 18a81019b851dae83f7df3e72064de706788ff25 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen <aaro.koskinen@nokia.com> Date: Fri, 18 Mar 2011 16:53:20 -0700 Subject: arm: mach-omap2: omap_l3_smx: fix irq handler setup The handler function may be called from the point it is registered. Since the handler inspects IRQ numbers, we must set them up before registration. Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/omap_l3_smx.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c index 265bff3acb9e..5f2da7565b68 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.c +++ b/arch/arm/mach-omap2/omap_l3_smx.c @@ -226,7 +226,6 @@ static int __init omap3_l3_probe(struct platform_device *pdev) struct omap3_l3 *l3; struct resource *res; int ret; - int irq; l3 = kzalloc(sizeof(*l3), GFP_KERNEL); if (!l3) { @@ -249,18 +248,17 @@ static int __init omap3_l3_probe(struct platform_device *pdev) goto err2; } - irq = platform_get_irq(pdev, 0); - ret = request_irq(irq, omap3_l3_app_irq, + l3->debug_irq = platform_get_irq(pdev, 0); + ret = request_irq(l3->debug_irq, omap3_l3_app_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING, "l3-debug-irq", l3); if (ret) { dev_err(&pdev->dev, "couldn't request debug irq\n"); goto err3; } - l3->debug_irq = irq; - irq = platform_get_irq(pdev, 1); - ret = request_irq(irq, omap3_l3_app_irq, + l3->app_irq = platform_get_irq(pdev, 1); + ret = request_irq(l3->app_irq, omap3_l3_app_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING, "l3-app-irq", l3); @@ -269,7 +267,6 @@ static int __init omap3_l3_probe(struct platform_device *pdev) goto err4; } - l3->app_irq = irq; goto err0; err4: -- cgit v1.2.3 From 8b8e2ef328c3378c74fb4347f66df8e58feeaf46 Mon Sep 17 00:00:00 2001 From: David Anders <x0132446@ti.com> Date: Fri, 18 Mar 2011 16:53:20 -0700 Subject: OMAP4: PandaBoard: remove unused power regulators the pandaboard does not use the VUSIM or VAUX1 power regulators on the TWL6030 and are left floating. if the VUSIM and VAUX1 power regulators are initilized, noise on the unloaded regulators generates an overcurrent interrupt causing the system to power down. this patch removes the initialization of the unused power regulators of VUSIM and VAUX1. Signed-off-by: David Anders <x0132446@ti.com> Acked-by: Andy Green <andy.green@linaro.org> Acked-by: Anand Gadiyar <gadiyar@ti.com> Tested-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/board-omap4panda.c | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 1dd4401e6466..80b8860bc595 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -280,19 +280,6 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) return 0; } -static struct regulator_init_data omap4_panda_vaux1 = { - .constraints = { - .min_uV = 1000000, - .max_uV = 3000000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -}; - static struct regulator_init_data omap4_panda_vaux2 = { .constraints = { .min_uV = 1200000, @@ -348,19 +335,6 @@ static struct regulator_init_data omap4_panda_vpp = { }, }; -static struct regulator_init_data omap4_panda_vusim = { - .constraints = { - .min_uV = 1200000, - .max_uV = 2900000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -}; - static struct regulator_init_data omap4_panda_vana = { .constraints = { .min_uV = 2100000, @@ -413,12 +387,10 @@ static struct twl4030_platform_data omap4_panda_twldata = { /* Regulators */ .vmmc = &omap4_panda_vmmc, .vpp = &omap4_panda_vpp, - .vusim = &omap4_panda_vusim, .vana = &omap4_panda_vana, .vcxio = &omap4_panda_vcxio, .vdac = &omap4_panda_vdac, .vusb = &omap4_panda_vusb, - .vaux1 = &omap4_panda_vaux1, .vaux2 = &omap4_panda_vaux2, .vaux3 = &omap4_panda_vaux3, .usb = &omap4_usbphy_data, -- cgit v1.2.3 From 77aded2f523c6540f71b1f549373dd8046329a6b Mon Sep 17 00:00:00 2001 From: Balaji T K <balajitk@ti.com> Date: Fri, 18 Mar 2011 16:53:20 -0700 Subject: ARM: OMAP2+: Fix warnings for GPMC interrupt Commit db97eb7dfe13f6c04f0a0e77c32e2691f563ab8b (omap: gpmc: enable irq mode in gpmc) enabled interrupts for GPMC (General Purpose Memory Controller). However, looks like this patch only works on omap3. Fix the issues to avoid warnings on omap4 during the boot. GPMC: number of chip select is 8, CS0 to CS7. One less IRQ allocated throws below warning at boot: [ 0.429290] Trying to install type control for IRQ409 [ 0.429290] Trying to set irq flags for IRQ409 Resolve following warning messages in boot when irq chip is not set: [ 0.429229] Trying to install interrupt handler for IRQ402 [ 0.429229] Trying to install interrupt handler for IRQ403 [ 0.429229] Trying to install interrupt handler for IRQ404 [ 0.429260] Trying to install interrupt handler for IRQ405 [ 0.429260] Trying to install interrupt handler for IRQ406 [ 0.429260] Trying to install interrupt handler for IRQ407 [ 0.429290] Trying to install interrupt handler for IRQ408 Resolve following warning in OMAP4: [ 0.429290] gpmc: irq-20 could not claim: err -22 Signed-off-by: Balaji T K <balajitk@ti.com> [tony@atomide.com: combined patches into one, updated comments] Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/gpmc.c | 13 ++++++++----- arch/arm/plat-omap/include/plat/irqs.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 674174365f78..493505c3b2f5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -693,6 +693,7 @@ static int __init gpmc_init(void) { u32 l, irq; int cs, ret = -EINVAL; + int gpmc_irq; char *ck = NULL; if (cpu_is_omap24xx()) { @@ -701,12 +702,15 @@ static int __init gpmc_init(void) l = OMAP2420_GPMC_BASE; else l = OMAP34XX_GPMC_BASE; + gpmc_irq = INT_34XX_GPMC_IRQ; } else if (cpu_is_omap34xx()) { ck = "gpmc_fck"; l = OMAP34XX_GPMC_BASE; + gpmc_irq = INT_34XX_GPMC_IRQ; } else if (cpu_is_omap44xx()) { ck = "gpmc_ck"; l = OMAP44XX_GPMC_BASE; + gpmc_irq = OMAP44XX_IRQ_GPMC; } if (WARN_ON(!ck)) @@ -739,16 +743,17 @@ static int __init gpmc_init(void) /* initalize the irq_chained */ irq = OMAP_GPMC_IRQ_BASE; for (cs = 0; cs < GPMC_CS_NUM; cs++) { - set_irq_handler(irq, handle_simple_irq); + set_irq_chip_and_handler(irq, &dummy_irq_chip, + handle_simple_irq); set_irq_flags(irq, IRQF_VALID); irq++; } - ret = request_irq(INT_34XX_GPMC_IRQ, + ret = request_irq(gpmc_irq, gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); if (ret) pr_err("gpmc: irq-%d could not claim: err %d\n", - INT_34XX_GPMC_IRQ, ret); + gpmc_irq, ret); return ret; } postcore_initcall(gpmc_init); @@ -757,8 +762,6 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev) { u8 cs; - if (irq != INT_34XX_GPMC_IRQ) - return IRQ_HANDLED; /* check cs to invoke the irq */ cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index d77928370463..5a25098ea7ea 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -416,7 +416,7 @@ /* GPMC related */ #define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END) -#define OMAP_GPMC_NR_IRQS 7 +#define OMAP_GPMC_NR_IRQS 8 #define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS) -- cgit v1.2.3 From b15f052cb8c1ba2a55998707f29dc8a8e5cc40ca Mon Sep 17 00:00:00 2001 From: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 24 Mar 2011 21:27:35 +0000 Subject: arm/gpio: Remove three copies of broken and racy debug code gpiolib plus two gpio implementations in arm fiddle in the guts of irq_desc in a racy and buggy way. Remove the stuff. I already told the gpio folks that we can provide that information in a proper way if necessary. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Grant Likely <grant.likely@secretlab.ca> LKML-Reference: <20110324212508.931638262@linutronix.de> --- arch/arm/mach-ep93xx/gpio.c | 39 -------------------------------------- arch/arm/plat-nomadik/gpio.c | 45 -------------------------------------------- drivers/gpio/gpiolib.c | 45 -------------------------------------------- 3 files changed, 129 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index a889fa7c3ba1..e327fd107c3f 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c @@ -366,45 +366,6 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) gpiochip_is_requested(chip, i) ? : "", is_out ? "out" : "in ", (data_reg & (1 << i)) ? "hi" : "lo"); - - if (!is_out) { - int irq = gpio_to_irq(gpio); - struct irq_desc *desc = irq_desc + irq; - - if (irq >= 0 && desc->action) { - char *trigger; - - switch (desc->status & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_NONE: - trigger = "(default)"; - break; - case IRQ_TYPE_EDGE_FALLING: - trigger = "edge-falling"; - break; - case IRQ_TYPE_EDGE_RISING: - trigger = "edge-rising"; - break; - case IRQ_TYPE_EDGE_BOTH: - trigger = "edge-both"; - break; - case IRQ_TYPE_LEVEL_HIGH: - trigger = "level-high"; - break; - case IRQ_TYPE_LEVEL_LOW: - trigger = "level-low"; - break; - default: - trigger = "?trigger?"; - break; - } - - seq_printf(s, " irq-%d %s%s", - irq, trigger, - (desc->status & IRQ_WAKEUP) - ? " wakeup" : ""); - } - } - seq_printf(s, "\n"); } } diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 70620426ee55..80643bc38e10 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -832,51 +832,6 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) : "? ", (mode < 0) ? "unknown" : modes[mode], pull ? "pull" : "none"); - - if (!is_out) { - int irq = gpio_to_irq(gpio); - struct irq_desc *desc = irq_to_desc(irq); - - /* This races with request_irq(), set_irq_type(), - * and set_irq_wake() ... but those are "rare". - * - * More significantly, trigger type flags aren't - * currently maintained by genirq. - */ - if (irq >= 0 && desc->action) { - char *trigger; - - switch (desc->status & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_NONE: - trigger = "(default)"; - break; - case IRQ_TYPE_EDGE_FALLING: - trigger = "edge-falling"; - break; - case IRQ_TYPE_EDGE_RISING: - trigger = "edge-rising"; - break; - case IRQ_TYPE_EDGE_BOTH: - trigger = "edge-both"; - break; - case IRQ_TYPE_LEVEL_HIGH: - trigger = "level-high"; - break; - case IRQ_TYPE_LEVEL_LOW: - trigger = "level-low"; - break; - default: - trigger = "?trigger?"; - break; - } - - seq_printf(s, " irq-%d %s%s", - irq, trigger, - (desc->status & IRQ_WAKEUP) - ? " wakeup" : ""); - } - } - seq_printf(s, "\n"); } } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 649550e2cae9..36a2974815b7 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1656,51 +1656,6 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) chip->get ? (chip->get(chip, i) ? "hi" : "lo") : "? "); - - if (!is_out) { - int irq = gpio_to_irq(gpio); - struct irq_desc *desc = irq_to_desc(irq); - - /* This races with request_irq(), set_irq_type(), - * and set_irq_wake() ... but those are "rare". - * - * More significantly, trigger type flags aren't - * currently maintained by genirq. - */ - if (irq >= 0 && desc->action) { - char *trigger; - - switch (desc->status & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_NONE: - trigger = "(default)"; - break; - case IRQ_TYPE_EDGE_FALLING: - trigger = "edge-falling"; - break; - case IRQ_TYPE_EDGE_RISING: - trigger = "edge-rising"; - break; - case IRQ_TYPE_EDGE_BOTH: - trigger = "edge-both"; - break; - case IRQ_TYPE_LEVEL_HIGH: - trigger = "level-high"; - break; - case IRQ_TYPE_LEVEL_LOW: - trigger = "level-low"; - break; - default: - trigger = "?trigger?"; - break; - } - - seq_printf(s, " irq-%d %s%s", - irq, trigger, - (desc->status & IRQ_WAKEUP) - ? " wakeup" : ""); - } - } - seq_printf(s, "\n"); } } -- cgit v1.2.3 From 778b548ced16b4bdca7ee2b694796f22ac24437f Mon Sep 17 00:00:00 2001 From: Ryan Mallon <ryan@bluewatersys.com> Date: Thu, 24 Mar 2011 23:46:46 +0100 Subject: arm: ep93xx: Add basic interrupt info For the time being can we fix up the ep93xx gpio code with the amended patch below. It keeps the information that the pin is also configured as an interrupt and cleans the code up a bit. [ tglx: Rebased it on the removal patch ] Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- arch/arm/mach-ep93xx/gpio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index e327fd107c3f..34e071d79761 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c @@ -360,13 +360,14 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) gpio = ep93xx_chip->chip.base; for (i = 0; i < chip->ngpio; i++, gpio++) { int is_out = data_dir_reg & (1 << i); + int irq = gpio_to_irq(gpio); - seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s", + seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s %s\n", chip->label, i, gpio, gpiochip_is_requested(chip, i) ? : "", is_out ? "out" : "in ", - (data_reg & (1 << i)) ? "hi" : "lo"); - seq_printf(s, "\n"); + (data_reg & (1<< i)) ? "hi" : "lo", + (!is_out && irq>= 0) ? "(interrupt)" : ""); } } -- cgit v1.2.3 From b2b755b5f10eb32fbdc73a9907c07006b17f714b Mon Sep 17 00:00:00 2001 From: David Rientjes <rientjes@google.com> Date: Thu, 24 Mar 2011 15:18:15 -0700 Subject: lib, arch: add filter argument to show_mem and fix private implementations Commit ddd588b5dd55 ("oom: suppress nodes that are not allowed from meminfo on oom kill") moved lib/show_mem.o out of lib/lib.a, which resulted in build warnings on all architectures that implement their own versions of show_mem(): lib/lib.a(show_mem.o): In function `show_mem': show_mem.c:(.text+0x1f4): multiple definition of `show_mem' arch/sparc/mm/built-in.o:(.text+0xd70): first defined here The fix is to remove __show_mem() and add its argument to show_mem() in all implementations to prevent this breakage. Architectures that implement their own show_mem() actually don't do anything with the argument yet, but they could be made to filter nodes that aren't allowed in the current context in the future just like the generic implementation. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Reported-by: James Bottomley <James.Bottomley@hansenpartnership.com> Suggested-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David Rientjes <rientjes@google.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> --- arch/arm/mm/init.c | 2 +- arch/ia64/mm/contig.c | 2 +- arch/ia64/mm/discontig.c | 2 +- arch/parisc/mm/init.c | 2 +- arch/powerpc/xmon/xmon.c | 2 +- arch/sparc/mm/init_32.c | 2 +- arch/tile/mm/pgtable.c | 2 +- arch/unicore32/mm/init.c | 2 +- drivers/tty/sysrq.c | 2 +- drivers/tty/vt/keyboard.c | 2 +- include/linux/mm.h | 5 ++--- lib/show_mem.c | 7 +------ mm/oom_kill.c | 2 +- mm/page_alloc.c | 2 +- 14 files changed, 15 insertions(+), 21 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index b3b0f0f5053d..e5f6fc428348 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -78,7 +78,7 @@ __tagtable(ATAG_INITRD2, parse_tag_initrd2); */ struct meminfo meminfo; -void show_mem(void) +void show_mem(unsigned int filter) { int free = 0, total = 0, reserved = 0; int shared = 0, cached = 0, slab = 0, i; diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 54bf54059811..9a018cde5d84 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -36,7 +36,7 @@ static unsigned long max_gap; * Shows a simple page count of reserved and used pages in the system. * For discontig machines, it does this on a per-pgdat basis. */ -void show_mem(void) +void show_mem(unsigned int filter) { int i, total_reserved = 0; int total_shared = 0, total_cached = 0; diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 61620323bb60..82ab1bc6afb1 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -614,7 +614,7 @@ void __cpuinit *per_cpu_init(void) * Shows a simple page count of reserved and used pages in the system. * For discontig machines, it does this on a per-pgdat basis. */ -void show_mem(void) +void show_mem(unsigned int filter) { int i, total_reserved = 0; int total_shared = 0, total_cached = 0; diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index f4f4d700833a..b7ed8d7a9b33 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -544,7 +544,7 @@ void __init mem_init(void) unsigned long *empty_zero_page __read_mostly; EXPORT_SYMBOL(empty_zero_page); -void show_mem(void) +void show_mem(unsigned int filter) { int i,free = 0,total = 0,reserved = 0; int shared = 0, cached = 0; diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d17d04cfb2cd..33794c1d92c3 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -821,7 +821,7 @@ cmds(struct pt_regs *excp) memzcan(); break; case 'i': - show_mem(); + show_mem(0); break; default: termch = cmd; diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 6d0e02c4fe09..4c31e2b6e71b 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c @@ -75,7 +75,7 @@ void __init kmap_init(void) kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); } -void show_mem(void) +void show_mem(unsigned int filter) { printk("Mem-info:\n"); show_free_areas(); diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 1a2b36f8866d..de7d8e21e01d 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c @@ -41,7 +41,7 @@ * The normal show_free_areas() is too verbose on Tile, with dozens * of processors and often four NUMA zones each with high and lowmem. */ -void show_mem(void) +void show_mem(unsigned int filter) { struct zone *zone; diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c index 3dbe3709b69d..1fc02633f700 100644 --- a/arch/unicore32/mm/init.c +++ b/arch/unicore32/mm/init.c @@ -55,7 +55,7 @@ early_param("initrd", early_initrd); */ struct meminfo meminfo; -void show_mem(void) +void show_mem(unsigned int filter) { int free = 0, total = 0, reserved = 0; int shared = 0, cached = 0, slab = 0, i; diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 81f13958e751..43db715f1502 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -306,7 +306,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = { static void sysrq_handle_showmem(int key) { - show_mem(); + show_mem(0); } static struct sysrq_key_op sysrq_showmem_op = { .handler = sysrq_handle_showmem, diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 6dd3c68c13ad..d6b342b5b423 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -600,7 +600,7 @@ static void fn_scroll_back(struct vc_data *vc) static void fn_show_mem(struct vc_data *vc) { - show_mem(); + show_mem(0); } static void fn_show_state(struct vc_data *vc) diff --git a/include/linux/mm.h b/include/linux/mm.h index f9535b2c9558..7606d7db96c9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -861,7 +861,7 @@ extern void pagefault_out_of_memory(void); #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) /* - * Flags passed to __show_mem() and __show_free_areas() to suppress output in + * Flags passed to show_mem() and __show_free_areas() to suppress output in * various contexts. */ #define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ @@ -1360,8 +1360,7 @@ extern void setup_per_zone_wmarks(void); extern void calculate_zone_inactive_ratio(struct zone *zone); extern void mem_init(void); extern void __init mmap_init(void); -extern void show_mem(void); -extern void __show_mem(unsigned int flags); +extern void show_mem(unsigned int flags); extern void si_meminfo(struct sysinfo * val); extern void si_meminfo_node(struct sysinfo *val, int nid); extern int after_bootmem; diff --git a/lib/show_mem.c b/lib/show_mem.c index d8d602b58c31..90cbe4bb5960 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c @@ -9,7 +9,7 @@ #include <linux/nmi.h> #include <linux/quicklist.h> -void __show_mem(unsigned int filter) +void show_mem(unsigned int filter) { pg_data_t *pgdat; unsigned long total = 0, reserved = 0, shared = 0, @@ -61,8 +61,3 @@ void __show_mem(unsigned int filter) quicklist_total_size()); #endif } - -void show_mem(void) -{ - __show_mem(0); -} diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 62a5cec08a17..6a819d1b2c7d 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -406,7 +406,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, task_unlock(current); dump_stack(); mem_cgroup_print_oom_info(mem, p); - __show_mem(SHOW_MEM_FILTER_NODES); + show_mem(SHOW_MEM_FILTER_NODES); if (sysctl_oom_dump_tasks) dump_tasks(mem, nodemask); } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8e5726ab0d85..d6e7ba7373be 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2195,7 +2195,7 @@ nopage: current->comm, order, gfp_mask); dump_stack(); if (!should_suppress_show_mem()) - __show_mem(filter); + show_mem(filter); } return page; got_pg: -- cgit v1.2.3 From 79568b941277b5986a8a7f0fb8578b2ccfc3e87e Mon Sep 17 00:00:00 2001 From: Bengt Jonsson <bengt.g.jonsson@stericsson.com> Date: Fri, 11 Mar 2011 11:54:46 +0100 Subject: regulator: initialization for ab8500 regulators The regulators on the AB8500 have a lot of custom hardware control settings pertaining to 8 external signals, settings which are board-specific and need be provided from the platform at startup. Initialization added for regulators Vana, VextSupply1, VextSupply2, VextSupply3, Vaux1, Vaux2, Vaux3, VTVout, Vintcore12, Vaudio, Vdmic, Vamic1, Vamic2, VrefDDR. Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com> Reviewed-by: Rickard Andersson <rickard.andersson@stericsson.com> Reviewed-by: Jonas Aberg <jonas.aberg@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk> --- arch/arm/mach-ux500/board-mop500-regulators.h | 2 + arch/arm/mach-ux500/board-mop500.c | 1 + drivers/regulator/ab8500.c | 223 +++++++++++++++++++++++++- include/linux/mfd/ab8500.h | 6 + include/linux/regulator/ab8500.h | 50 +++++- 5 files changed, 279 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 2675fae52537..f979b892e4fa 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h @@ -14,6 +14,8 @@ #include <linux/regulator/machine.h> #include <linux/regulator/ab8500.h> +extern struct ab8500_regulator_reg_init +ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; #endif diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 8790d984cac8..d0076453d7ff 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -20,6 +20,7 @@ #include <linux/amba/serial.h> #include <linux/spi/spi.h> #include <linux/mfd/ab8500.h> +#include <linux/regulator/ab8500.h> #include <linux/mfd/tc3589x.h> #include <linux/leds-lp5521.h> #include <linux/input.h> diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 5a77630095d9..d157146c8655 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -526,6 +526,186 @@ static struct ab8500_regulator_info }; +struct ab8500_reg_init { + u8 bank; + u8 addr; + u8 mask; +}; + +#define REG_INIT(_id, _bank, _addr, _mask) \ + [_id] = { \ + .bank = _bank, \ + .addr = _addr, \ + .mask = _mask, \ + } + +static struct ab8500_reg_init ab8500_reg_init[] = { + /* + * 0x30, VanaRequestCtrl + * 0x0C, VpllRequestCtrl + * 0xc0, VextSupply1RequestCtrl + */ + REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc), + /* + * 0x03, VextSupply2RequestCtrl + * 0x0c, VextSupply3RequestCtrl + * 0x30, Vaux1RequestCtrl + * 0xc0, Vaux2RequestCtrl + */ + REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff), + /* + * 0x03, Vaux3RequestCtrl + * 0x04, SwHPReq + */ + REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), + /* + * 0x08, VanaSysClkReq1HPValid + * 0x20, Vaux1SysClkReq1HPValid + * 0x40, Vaux2SysClkReq1HPValid + * 0x80, Vaux3SysClkReq1HPValid + */ + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8), + /* + * 0x10, VextSupply1SysClkReq1HPValid + * 0x20, VextSupply2SysClkReq1HPValid + * 0x40, VextSupply3SysClkReq1HPValid + */ + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70), + /* + * 0x08, VanaHwHPReq1Valid + * 0x20, Vaux1HwHPReq1Valid + * 0x40, Vaux2HwHPReq1Valid + * 0x80, Vaux3HwHPReq1Valid + */ + REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8), + /* + * 0x01, VextSupply1HwHPReq1Valid + * 0x02, VextSupply2HwHPReq1Valid + * 0x04, VextSupply3HwHPReq1Valid + */ + REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), + /* + * 0x08, VanaHwHPReq2Valid + * 0x20, Vaux1HwHPReq2Valid + * 0x40, Vaux2HwHPReq2Valid + * 0x80, Vaux3HwHPReq2Valid + */ + REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8), + /* + * 0x01, VextSupply1HwHPReq2Valid + * 0x02, VextSupply2HwHPReq2Valid + * 0x04, VextSupply3HwHPReq2Valid + */ + REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), + /* + * 0x20, VanaSwHPReqValid + * 0x80, Vaux1SwHPReqValid + */ + REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0), + /* + * 0x01, Vaux2SwHPReqValid + * 0x02, Vaux3SwHPReqValid + * 0x04, VextSupply1SwHPReqValid + * 0x08, VextSupply2SwHPReqValid + * 0x10, VextSupply3SwHPReqValid + */ + REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), + /* + * 0x02, SysClkReq2Valid1 + * ... + * 0x80, SysClkReq8Valid1 + */ + REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe), + /* + * 0x02, SysClkReq2Valid2 + * ... + * 0x80, SysClkReq8Valid2 + */ + REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe), + /* + * 0x02, VTVoutEna + * 0x04, Vintcore12Ena + * 0x38, Vintcore12Sel + * 0x40, Vintcore12LP + * 0x80, VTVoutLP + */ + REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe), + /* + * 0x02, VaudioEna + * 0x04, VdmicEna + * 0x08, Vamic1Ena + * 0x10, Vamic2Ena + */ + REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e), + /* + * 0x01, Vamic1_dzout + * 0x02, Vamic2_dzout + */ + REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), + /* + * 0x0c, VanaRegu + * 0x03, VpllRegu + */ + REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f), + /* + * 0x01, VrefDDREna + * 0x02, VrefDDRSleepMode + */ + REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03), + /* + * 0x03, VextSupply1Regu + * 0x0c, VextSupply2Regu + * 0x30, VextSupply3Regu + * 0x40, ExtSupply2Bypass + * 0x80, ExtSupply3Bypass + */ + REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff), + /* + * 0x03, Vaux1Regu + * 0x0c, Vaux2Regu + */ + REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f), + /* + * 0x03, Vaux3Regu + */ + REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03), + /* + * 0x3f, Vsmps1Sel1 + */ + REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f), + /* + * 0x0f, Vaux1Sel + */ + REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f), + /* + * 0x0f, Vaux2Sel + */ + REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f), + /* + * 0x07, Vaux3Sel + */ + REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07), + /* + * 0x01, VextSupply12LP + */ + REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01), + /* + * 0x04, Vaux1Disch + * 0x08, Vaux2Disch + * 0x10, Vaux3Disch + * 0x20, Vintcore12Disch + * 0x40, VTVoutDisch + * 0x80, VaudioDisch + */ + REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc), + /* + * 0x02, VanaDisch + * 0x04, VdmicPullDownEna + * 0x10, VdmicDisch + */ + REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), +}; + static __devinit int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); @@ -544,10 +724,51 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) /* make sure the platform data has the correct size */ if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { - dev_err(&pdev->dev, "platform configuration error\n"); + dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); return -EINVAL; } + /* initialize registers */ + for (i = 0; i < pdata->num_regulator_reg_init; i++) { + int id; + u8 value; + + id = pdata->regulator_reg_init[i].id; + value = pdata->regulator_reg_init[i].value; + + /* check for configuration errors */ + if (id >= AB8500_NUM_REGULATOR_REGISTERS) { + dev_err(&pdev->dev, + "Configuration error: id outside range.\n"); + return -EINVAL; + } + if (value & ~ab8500_reg_init[id].mask) { + dev_err(&pdev->dev, + "Configuration error: value outside mask.\n"); + return -EINVAL; + } + + /* initialize register */ + err = abx500_mask_and_set_register_interruptible(&pdev->dev, + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + ab8500_reg_init[id].mask, + value); + if (err < 0) { + dev_err(&pdev->dev, + "Failed to initialize 0x%02x, 0x%02x.\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr); + return err; + } + dev_vdbg(&pdev->dev, + " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + ab8500_reg_init[id].mask, + value); + } + /* register all regulators */ for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { struct ab8500_regulator_info *info = NULL; diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index 56f8dea72152..6e4f77ef4d20 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h @@ -139,17 +139,23 @@ struct ab8500 { u8 oldmask[AB8500_NUM_IRQ_REGS]; }; +struct regulator_reg_init; struct regulator_init_data; /** * struct ab8500_platform_data - AB8500 platform data * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used * @init: board-specific initialization after detection of ab8500 + * @num_regulator_reg_init: number of regulator init registers + * @regulator_reg_init: regulator init registers + * @num_regulator: number of regulators * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; void (*init) (struct ab8500 *); + int num_regulator_reg_init; + struct ab8500_regulator_reg_init *regulator_reg_init; int num_regulator; struct regulator_init_data *regulator; }; diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index d4eacdef2017..76579f964a29 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -3,8 +3,8 @@ * * License Terms: GNU General Public License v2 * - * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson - * + * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson + * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson */ #ifndef __LINUX_MFD_AB8500_REGULATOR_H @@ -25,4 +25,50 @@ enum ab8500_regulator_id { AB8500_LDO_ANA, AB8500_NUM_REGULATORS, }; + +/* AB8500 register initialization */ +struct ab8500_regulator_reg_init { + int id; + u8 value; +}; + +#define INIT_REGULATOR_REGISTER(_id, _value) \ + { \ + .id = _id, \ + .value = _value, \ + } + +/* AB8500 registers */ +enum ab8500_regulator_reg { + AB8500_REGUREQUESTCTRL2, + AB8500_REGUREQUESTCTRL3, + AB8500_REGUREQUESTCTRL4, + AB8500_REGUSYSCLKREQ1HPVALID1, + AB8500_REGUSYSCLKREQ1HPVALID2, + AB8500_REGUHWHPREQ1VALID1, + AB8500_REGUHWHPREQ1VALID2, + AB8500_REGUHWHPREQ2VALID1, + AB8500_REGUHWHPREQ2VALID2, + AB8500_REGUSWHPREQVALID1, + AB8500_REGUSWHPREQVALID2, + AB8500_REGUSYSCLKREQVALID1, + AB8500_REGUSYSCLKREQVALID2, + AB8500_REGUMISC1, + AB8500_VAUDIOSUPPLY, + AB8500_REGUCTRL1VAMIC, + AB8500_VPLLVANAREGU, + AB8500_VREFDDR, + AB8500_EXTSUPPLYREGU, + AB8500_VAUX12REGU, + AB8500_VRF1VAUX3REGU, + AB8500_VAUX1SEL, + AB8500_VAUX2SEL, + AB8500_VRF1VAUX3SEL, + AB8500_REGUCTRL2SPARE, + AB8500_REGUCTRLDISCH, + AB8500_REGUCTRLDISCH2, + AB8500_VSMPS1SEL1, + AB8500_NUM_REGULATOR_REGISTERS, +}; + #endif -- cgit v1.2.3