From patchwork Thu Aug 18 07:58:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1075802 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p7I7xCJk016171 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 18 Aug 2011 07:59:33 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QtxVH-0000m4-Fi; Thu, 18 Aug 2011 07:59:03 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QtxVH-0003Xd-2L; Thu, 18 Aug 2011 07:59:03 +0000 Received: from eu1sys200aog101.obsmtp.com ([207.126.144.111]) by canuck.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1QtxVC-0003XI-5o for linux-arm-kernel@lists.infradead.org; Thu, 18 Aug 2011 07:59:00 +0000 Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob101.postini.com ([207.126.147.11]) with SMTP ID DSNKTkzGN8rQbCfF4WQVwLLuw2DrrTlQLIaN@postini.com; Thu, 18 Aug 2011 07:58:57 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 4C806123; Thu, 18 Aug 2011 07:58:39 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id D908F7B5; Thu, 18 Aug 2011 07:58:38 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 83F4524C075; Thu, 18 Aug 2011 09:58:33 +0200 (CEST) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Thu, 18 Aug 2011 09:58:37 +0200 From: Linus Walleij To: Subject: [PATCH v4] amba: consolidate PrimeCell magic Date: Thu, 18 Aug 2011 09:58:31 +0200 Message-ID: <1313654311-2283-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.3.2 MIME-Version: 1.0 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110818_035858_674531_B61EE254 X-CRM114-Status: GOOD ( 30.11 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.111 listed in list.dnswl.org] Cc: Linus Walleij , Kukjin Kim , Lee Jones X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 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 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 18 Aug 2011 07:59:33 +0000 (UTC) From: Linus Walleij Since two drivers use the PrimeCell scheme without using the amba_bus driver logic, let's break the magic lookups out as static inlines in the header so we get some consolidation anyway. Delete the primecell ID check in common/pl330.c since it is only used from the amba_bus driver in drivers/dma, which is already doing the same check when probing in drivers/amba/bus.c. Cc: Kukjin Kim Cc: Viresh Kumar Acked-by: H Hartley Sweeten Acked-by: Jassi Brar Acked-by: Boojin Kim Signed-off-by: Linus Walleij Acked-by: Viresh Kumar Acked-by: Kukjin Kim --- Changes V3->v4: - Fix up sparse warning due to inelegant cast to (u32) in vic.c, we cast to (unsigned long) and sparse is happy. --- arch/arm/common/pl330.c | 40 +++------------------------------------- arch/arm/common/vic.c | 15 ++++++++------- drivers/amba/bus.c | 19 +++---------------- drivers/dma/ste_dma40.c | 14 ++++---------- drivers/mtd/nand/fsmc_nand.c | 10 +++------- include/linux/amba/bus.h | 26 ++++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 77 deletions(-) diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c index 97912fa..623ce74 100644 --- a/arch/arm/common/pl330.c +++ b/arch/arm/common/pl330.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -111,9 +112,6 @@ #define CR4 0xe10 #define CRD 0xe14 -#define PERIPH_ID 0xfe0 -#define PCELL_ID 0xff0 - #define CR0_PERIPH_REQ_SET (1 << 0) #define CR0_BOOT_EN_SET (1 << 1) #define CR0_BOOT_MAN_NS (1 << 2) @@ -142,14 +140,6 @@ #define CRD_DATA_BUFF_SHIFT 20 #define CRD_DATA_BUFF_MASK 0x3ff -#define PART 0x330 -#define DESIGNER 0x41 -#define REVISION 0x0 -#define INTEG_CFG 0x0 -#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12)) - -#define PCELL_ID_VAL 0xb105f00d - #define PL330_STATE_STOPPED (1 << 0) #define PL330_STATE_EXECUTING (1 << 1) #define PL330_STATE_WFE (1 << 2) @@ -372,19 +362,6 @@ static inline bool _manager_ns(struct pl330_thread *thrd) return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false; } -static inline u32 get_id(struct pl330_info *pi, u32 off) -{ - void __iomem *regs = pi->base; - u32 id = 0; - - id |= (readb(regs + off + 0x0) << 0); - id |= (readb(regs + off + 0x4) << 8); - id |= (readb(regs + off + 0x8) << 16); - id |= (readb(regs + off + 0xc) << 24); - - return id; -} - static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], enum pl330_dst da, u16 val) { @@ -1747,8 +1724,8 @@ static void read_dmac_config(struct pl330_info *pi) pi->pcfg.irq_ns = readl(regs + CR3); - pi->pcfg.periph_id = get_id(pi, PERIPH_ID); - pi->pcfg.pcell_id = get_id(pi, PCELL_ID); + pi->pcfg.periph_id = amba_get_pid(pi->base, PCELL_SIZE); + pi->pcfg.pcell_id = amba_get_cid(pi->base, PCELL_SIZE); } static inline void _reset_thread(struct pl330_thread *thrd) @@ -1838,7 +1815,6 @@ static int dmac_alloc_resources(struct pl330_dmac *pl330) int pl330_add(struct pl330_info *pi) { struct pl330_dmac *pl330; - void __iomem *regs; int i, ret; if (!pi || !pi->dev) @@ -1855,16 +1831,6 @@ int pl330_add(struct pl330_info *pi) if (pi->dmac_reset) pi->dmac_reset(pi); - regs = pi->base; - - /* Check if we can handle this DMAC */ - if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL - || get_id(pi, PCELL_ID) != PCELL_ID_VAL) { - dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n", - get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID)); - return -EINVAL; - } - /* Read the configuration of the DMAC */ read_dmac_config(pi); diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 7aa4262..84a51ea 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -341,16 +341,17 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, void __init vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources) { - unsigned int i; u32 cellid = 0; enum amba_vendor vendor; - /* Identify which VIC cell this one is, by reading the ID */ - for (i = 0; i < 4; i++) { - u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4); - cellid |= (readl(addr) & 0xff) << (8 * i); - } - vendor = (cellid >> 12) & 0xff; + /* + * Identify which VIC cell this one is, by reading the ID - some + * implementations have two VICs in the same page but only one set + * of ID registers at the end, so we need to adjust the base to + * reference the page offset. All VIC:s are size 4K. + */ + cellid = amba_get_pid((void __iomem *)((unsigned long)base & PAGE_MASK), SZ_4K); + vendor = AMBA_MANF_BITS(cellid); printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n", base, cellid, vendor); diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index d74926e..7412671 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -579,7 +579,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; - int i, ret; + int ret; device_initialize(&dev->dev); @@ -620,24 +620,11 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) ret = amba_get_enable_pclk(dev); if (ret == 0) { - u32 pid, cid; - - /* - * Read pid and cid based on size of resource - * they are located at end of region - */ - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << - (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << - (i * 8); + if (amba_get_cid(tmp, size) == AMBA_CID) + dev->periphid = amba_get_pid(tmp, size); amba_put_disable_pclk(dev); - if (cid == AMBA_CID) - dev->periphid = pid; - if (!dev->periphid) ret = -ENODEV; } diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index cd3a7c7..6e11cef 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2569,7 +2569,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) int num_phy_chans; int i; u32 pid; - u32 cid; u8 rev; clk = clk_get(&pdev->dev, NULL); @@ -2594,18 +2593,13 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) if (!virtbase) goto failure; - /* This is just a regular AMBA PrimeCell ID actually */ - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(virtbase + resource_size(res) - 0x20 + 4 * i) - & 255) << (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(virtbase + resource_size(res) - 0x10 + 4 * i) - & 255) << (i * 8); - - if (cid != AMBA_CID) { + /* Device ID use the AMBA PrimeCell scheme */ + if (amba_get_cid(virtbase, resource_size(res)) != AMBA_CID) { d40_err(&pdev->dev, "Unknown hardware! No PrimeCell ID\n"); goto failure; } + + pid = amba_get_pid(virtbase, resource_size(res)); if (AMBA_MANF_BITS(pid) != AMBA_VENDOR_ST) { d40_err(&pdev->dev, "Unknown designer! Got %x wanted %x\n", AMBA_MANF_BITS(pid), diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index e9b275a..836de62 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -541,8 +541,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) struct fsmc_regs *regs; struct resource *res; int ret = 0; - u32 pid; - int i; if (!pdata) { dev_err(&pdev->dev, "platform data is NULL\n"); @@ -636,13 +634,11 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * This device ID is actually a common AMBA ID as used on the * AMBA PrimeCell bus. However it is not a PrimeCell. */ - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8); - host->pid = pid; + host->pid = amba_get_pid(host->regs_va, resource_size(res)); dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, " "revision %02x, config %02x\n", - AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid), - AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid)); + AMBA_PART_BITS(host->pid), AMBA_MANF_BITS(host->pid), + AMBA_REV_BITS(host->pid), AMBA_CONFIG_BITS(host->pid)); host->bank = pdata->bank; host->select_chip = pdata->select_bank; diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index fcbbe71..008cfcf 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -19,6 +19,7 @@ #include #include #include +#include #define AMBA_NR_IRQS 2 #define AMBA_CID 0xb105f00d @@ -94,4 +95,29 @@ void amba_release_regions(struct amba_device *); #define amba_manf(d) AMBA_MANF_BITS((d)->periphid) #define amba_part(d) AMBA_PART_BITS((d)->periphid) +/* + * Inlines to extract the PID and CID for a certain PrimeCell. These are at + * offset -0x20 and -0x10 from the end of the I/O region respectively. + */ +static inline u32 amba_get_magic(void __iomem *base, u32 size, u8 offset) +{ + u32 magic; + int i; + + for (magic = 0, i = 0; i < 4; i++) + magic |= (readl(base + size - offset + 4 * i) & 255) + << (i * 8); + return magic; +} + +static inline u32 amba_get_pid(void __iomem *base, u32 size) +{ + return amba_get_magic(base, size, 0x20); +} + +static inline u32 amba_get_cid(void __iomem *base, u32 size) +{ + return amba_get_magic(base, size, 0x10); +} + #endif