A number of devices are using a common register layout, this adds support code for it in lib/stmp_device.c so we do not need to duplicate it in each driver. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPuexlAAoJEIwa5zzehBx31P0P/jK7GC5Ln2gr/bV+4Kt9fStS VcGI/ARsyQtwaNTJQfPkg8Weg3DhbPRlUWeimVKMFo3uEle3VjnPBjdcMPUKtW3x SPka/W591LGEdKQRmXZrISm2OiQXVvM2zkhSJV89n/tJBdHd+tDWDDq4Y784F8Cj hWmcIi66G4RBPj5pplf80UhNAEg5HoZHQnlgrS1iLMpBTwXAesv7zyZpvnsMzdpg qSJTfcifgLULtM0WFbooNGojBn8ftuA67psrw78vgV2bz7bVBioZHYFyqPWK9Gr0 vtiKuyXqiDA65mueXA+E5RXXLCLQSyGdV8y0xiSYjilRVkziPcMKnQT07keb8SJN CCDpetjEULiQpgKvVWc7sDGlb5ePd/C5rs31S0fFOKjeRJNlfG5+OuqZPiobO7hk F2Fx3gq4LPLel7gwjK3T4XTmmL9kNt/y1sIfXx5WybJL8N5n6TdZIfWm6yOZYwfX jvG/CnvVvhgdWk/ebaTEOG1MaeNAY3uwGpSBuEEoXUDHatQdOYAsgLfJJv/H4zKp 2AY9qvXTDtFYys/hs2WhwmS7s1WFlIrA+voEPBDa3WT2qGup8HAL/C9kL3ms2zqk 8JL/yQ/IJpTHPb4bCGo9C08qdi1YtMbylHB0/ELvG1BNoHOnCDV3wZlVG3ZTQQb5 c/Lb2H8crk5HVbpCPLQU =VHLM -----END PGP SIGNATURE----- Merge tag 'stmp-dev' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull arm-soc stmp-dev library code from Olof Johansson: "A number of devices are using a common register layout, this adds support code for it in lib/stmp_device.c so we do not need to duplicate it in each driver." Fix up trivial conflicts in drivers/i2c/busses/i2c-mxs.c and lib/Makefile * tag 'stmp-dev' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: i2c: mxs: use global reset function lib: add support for stmp-style devicestirimbino
commit
39b6cc668c
@ -0,0 +1,20 @@ |
||||
/*
|
||||
* basic functions for devices following the "stmp" style register layout |
||||
* |
||||
* Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
*/ |
||||
|
||||
#ifndef __STMP_DEVICE_H__ |
||||
#define __STMP_DEVICE_H__ |
||||
|
||||
#define STMP_OFFSET_REG_SET 0x4 |
||||
#define STMP_OFFSET_REG_CLR 0x8 |
||||
#define STMP_OFFSET_REG_TOG 0xc |
||||
|
||||
extern int stmp_reset_block(void __iomem *); |
||||
#endif /* __STMP_DEVICE_H__ */ |
@ -0,0 +1,80 @@ |
||||
/*
|
||||
* Copyright (C) 1999 ARM Limited |
||||
* Copyright (C) 2000 Deep Blue Solutions Ltd |
||||
* Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved. |
||||
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de |
||||
* Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com |
||||
* Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
*/ |
||||
|
||||
#include <linux/io.h> |
||||
#include <linux/errno.h> |
||||
#include <linux/delay.h> |
||||
#include <linux/module.h> |
||||
#include <linux/stmp_device.h> |
||||
|
||||
#define STMP_MODULE_CLKGATE (1 << 30) |
||||
#define STMP_MODULE_SFTRST (1 << 31) |
||||
|
||||
/*
|
||||
* Clear the bit and poll it cleared. This is usually called with |
||||
* a reset address and mask being either SFTRST(bit 31) or CLKGATE |
||||
* (bit 30). |
||||
*/ |
||||
static int stmp_clear_poll_bit(void __iomem *addr, u32 mask) |
||||
{ |
||||
int timeout = 0x400; |
||||
|
||||
writel(mask, addr + STMP_OFFSET_REG_CLR); |
||||
udelay(1); |
||||
while ((readl(addr) & mask) && --timeout) |
||||
/* nothing */; |
||||
|
||||
return !timeout; |
||||
} |
||||
|
||||
int stmp_reset_block(void __iomem *reset_addr) |
||||
{ |
||||
int ret; |
||||
int timeout = 0x400; |
||||
|
||||
/* clear and poll SFTRST */ |
||||
ret = stmp_clear_poll_bit(reset_addr, STMP_MODULE_SFTRST); |
||||
if (unlikely(ret)) |
||||
goto error; |
||||
|
||||
/* clear CLKGATE */ |
||||
writel(STMP_MODULE_CLKGATE, reset_addr + STMP_OFFSET_REG_CLR); |
||||
|
||||
/* set SFTRST to reset the block */ |
||||
writel(STMP_MODULE_SFTRST, reset_addr + STMP_OFFSET_REG_SET); |
||||
udelay(1); |
||||
|
||||
/* poll CLKGATE becoming set */ |
||||
while ((!(readl(reset_addr) & STMP_MODULE_CLKGATE)) && --timeout) |
||||
/* nothing */; |
||||
if (unlikely(!timeout)) |
||||
goto error; |
||||
|
||||
/* clear and poll SFTRST */ |
||||
ret = stmp_clear_poll_bit(reset_addr, STMP_MODULE_SFTRST); |
||||
if (unlikely(ret)) |
||||
goto error; |
||||
|
||||
/* clear and poll CLKGATE */ |
||||
ret = stmp_clear_poll_bit(reset_addr, STMP_MODULE_CLKGATE); |
||||
if (unlikely(ret)) |
||||
goto error; |
||||
|
||||
return 0; |
||||
|
||||
error: |
||||
pr_err("%s(%p): module reset timeout\n", __func__, reset_addr); |
||||
return -ETIMEDOUT; |
||||
} |
||||
EXPORT_SYMBOL(stmp_reset_block); |
Loading…
Reference in new issue