From patchwork Thu Nov 8 11:55:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1715151 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id BA1443FCDE for ; Thu, 8 Nov 2012 11:58:36 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TWQiL-0001IR-IV; Thu, 08 Nov 2012 11:56:05 +0000 Received: from eu1sys200aog118.obsmtp.com ([207.126.144.145]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1TWQiG-0001Hg-DP for linux-arm-kernel@lists.infradead.org; Thu, 08 Nov 2012 11:56:02 +0000 Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob118.postini.com ([207.126.147.11]) with SMTP ID DSNKUJudx4Rkb6b6tIYTuPYSCYLva4CMaGVW@postini.com; Thu, 08 Nov 2012 11:56:00 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 8516A50; Thu, 8 Nov 2012 11:55:13 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id B906665; Thu, 8 Nov 2012 07:12:08 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id B5CD624C2E5; Thu, 8 Nov 2012 12:55:40 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Thu, 8 Nov 2012 12:55:45 +0100 From: Linus Walleij To: , , Subject: [PATCH 2/2] pinctrl/nomadik: make independent of prcmu driver Date: Thu, 8 Nov 2012 12:55:42 +0100 Message-ID: <1352375742-29611-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121108_065600_936549_AFE4B102 X-CRM114-Status: GOOD ( 24.06 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.145 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Anmar Oueja , Linus Walleij , Stephen Warren , Loic Pallardy , Jonas Aaberg X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Jonas Aaberg Currently there are some unnecessary criss-cross dependencies between the PRCMU driver in MFD and a lot of other drivers, mainly because other drivers need to poke around in the PRCM register range. In cases like this there are actually just a few select registers that the pinctrl driver need to read/modify/write, and it turns out that no other driver is actually using these registers, so there are no concurrency issues whatsoever. So: don't let the location of the register range complicate things, just poke into these registers directly and skip a layer of indirection. Cc: Loic Pallardy Signed-off-by: Jonas Aaberg Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-db8500.c | 4 +-- drivers/pinctrl/pinctrl-nomadik-db8540.c | 4 +-- drivers/pinctrl/pinctrl-nomadik-stn8815.c | 4 +-- drivers/pinctrl/pinctrl-nomadik.c | 52 ++++++++++++++++++------------- drivers/pinctrl/pinctrl-nomadik.h | 14 +++++---- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index 6de52e7..e73d75e 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -1230,7 +1230,7 @@ static const u16 db8500_prcm_gpiocr_regs[] = { [PRCM_IDX_GPIOCR2] = 0x574, }; -static const struct nmk_pinctrl_soc_data nmk_db8500_soc = { +static struct nmk_pinctrl_soc_data nmk_db8500_soc = { .gpio_ranges = nmk_db8500_ranges, .gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges), .pins = nmk_db8500_pins, @@ -1245,7 +1245,7 @@ static const struct nmk_pinctrl_soc_data nmk_db8500_soc = { }; void __devinit -nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc) +nmk_pinctrl_db8500_init(struct nmk_pinctrl_soc_data **soc) { *soc = &nmk_db8500_soc; } diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c index 52fc301..1276ba3 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8540.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c @@ -1240,7 +1240,7 @@ static const u16 db8540_prcm_gpiocr_regs[] = { [PRCM_IDX_GPIOCR3] = 0x2bc, }; -static const struct nmk_pinctrl_soc_data nmk_db8540_soc = { +static struct nmk_pinctrl_soc_data nmk_db8540_soc = { .gpio_ranges = nmk_db8540_ranges, .gpio_num_ranges = ARRAY_SIZE(nmk_db8540_ranges), .pins = nmk_db8540_pins, @@ -1255,7 +1255,7 @@ static const struct nmk_pinctrl_soc_data nmk_db8540_soc = { }; void __devinit -nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc) +nmk_pinctrl_db8540_init(struct nmk_pinctrl_soc_data **soc) { *soc = &nmk_db8540_soc; } diff --git a/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/pinctrl-nomadik-stn8815.c index 7d432c3..ed5b144 100644 --- a/drivers/pinctrl/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/pinctrl-nomadik-stn8815.c @@ -339,7 +339,7 @@ static const struct nmk_function nmk_stn8815_functions[] = { FUNCTION(i2cusb), }; -static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = { +static struct nmk_pinctrl_soc_data nmk_stn8815_soc = { .gpio_ranges = nmk_stn8815_ranges, .gpio_num_ranges = ARRAY_SIZE(nmk_stn8815_ranges), .pins = nmk_stn8815_pins, @@ -351,7 +351,7 @@ static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = { }; void __devinit -nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc) +nmk_pinctrl_stn8815_init(struct nmk_pinctrl_soc_data **soc) { *soc = &nmk_stn8815_soc; } diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 22f6937..33c614e 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -30,20 +30,6 @@ #include /* Since we request GPIOs from ourself */ #include -/* - * For the U8500 archs, use the PRCMU register interface, for the older - * Nomadik, provide some stubs. The functions using these will only be - * called on the U8500 series. - */ -#ifdef CONFIG_ARCH_U8500 -#include -#else -static inline u32 prcmu_read(unsigned int reg) { - return 0; -} -static inline void prcmu_write(unsigned int reg, u32 value) {} -static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} -#endif #include #include @@ -85,7 +71,7 @@ struct nmk_gpio_chip { struct nmk_pinctrl { struct device *dev; struct pinctrl_dev *pctl; - const struct nmk_pinctrl_soc_data *soc; + struct nmk_pinctrl_soc_data *soc; }; static struct nmk_gpio_chip * @@ -247,6 +233,15 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); } +static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value) +{ + u32 val; + + val = readl(reg); + val = ((val & ~mask) | (value & mask)); + writel(val, reg); +} + static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, unsigned offset, unsigned alt_num) { @@ -285,8 +280,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (prcmu_read(reg) & BIT(bit)) { - prcmu_write_masked(reg, BIT(bit), 0); + if (readl(npct->soc->prcmu_base + reg) & BIT(bit)) { + nmk_write_masked(npct->soc->prcmu_base + reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", offset, i+1); @@ -314,8 +309,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (prcmu_read(reg) & BIT(bit)) { - prcmu_write_masked(reg, BIT(bit), 0); + if (readl(npct->soc->prcmu_base + reg) & BIT(bit)) { + nmk_write_masked(npct->soc->prcmu_base + reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", offset, i+1); @@ -327,7 +322,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, bit = pin_desc->altcx[alt_index].control_bit; dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", offset, alt_index+1); - prcmu_write_masked(reg, BIT(bit), BIT(bit)); + nmk_write_masked(npct->soc->prcmu_base + reg, BIT(bit), BIT(bit)); } static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, @@ -693,7 +688,7 @@ static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (prcmu_read(reg) & BIT(bit)) + if (readl(npct->soc->prcmu_base + reg) & BIT(bit)) return NMK_GPIO_ALT_C+i+1; } } @@ -1851,6 +1846,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) const struct platform_device_id *platid = platform_get_device_id(pdev); struct device_node *np = pdev->dev.of_node; struct nmk_pinctrl *npct; + struct resource *res; unsigned int version = 0; int i; @@ -1872,6 +1868,20 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) if (version == PINCTRL_NMK_DB8540) nmk_pinctrl_db8540_init(&npct->soc); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + npct->soc->prcmu_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!npct->soc->prcmu_base) { + dev_err(&pdev->dev, + "failed to ioremap prcmu registers\n"); + return -ENOMEM; + } + } else { + dev_info(&pdev->dev, + "No PRCMU base, assume no ALT-Cx control is available\n"); + } + /* * We need all the GPIO drivers to probe FIRST, or we will not be able * to obtain references to the struct gpio_chip * for them, and we diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h index bcd4191..9dd727a 100644 --- a/drivers/pinctrl/pinctrl-nomadik.h +++ b/drivers/pinctrl/pinctrl-nomadik.h @@ -125,6 +125,7 @@ struct nmk_pingroup { * @altcx_pins: The pins that support Other alternate-C function on this SoC * @npins_altcx: The number of Other alternate-C pins * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC + * @prcmu_base: PRCMU virtual base */ struct nmk_pinctrl_soc_data { struct pinctrl_gpio_range *gpio_ranges; @@ -138,16 +139,17 @@ struct nmk_pinctrl_soc_data { const struct prcm_gpiocr_altcx_pin_desc *altcx_pins; unsigned npins_altcx; const u16 *prcm_gpiocr_registers; + void __iomem *prcmu_base; }; #ifdef CONFIG_PINCTRL_STN8815 -void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc); +void nmk_pinctrl_stn8815_init(struct nmk_pinctrl_soc_data **soc); #else static inline void -nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc) +nmk_pinctrl_stn8815_init(struct nmk_pinctrl_soc_data **soc) { } @@ -155,12 +157,12 @@ nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc) #ifdef CONFIG_PINCTRL_DB8500 -void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc); +void nmk_pinctrl_db8500_init(struct nmk_pinctrl_soc_data **soc); #else static inline void -nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc) +nmk_pinctrl_db8500_init(struct nmk_pinctrl_soc_data **soc) { } @@ -168,12 +170,12 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc) #ifdef CONFIG_PINCTRL_DB8540 -void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc); +void nmk_pinctrl_db8540_init(struct nmk_pinctrl_soc_data **soc); #else static inline void -nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc) +nmk_pinctrl_db8540_init(struct nmk_pinctrl_soc_data **soc) { }