Skip to content

Commit cf7b4a0

Browse files
Simon QueLuis Henriques
authored andcommitted
omap:hwspinlock-added hwspinlock driver
Created driver for OMAP hardware spinlock. This driver supports: - Reserved spinlocks for internal use - Dynamic allocation of unreserved locks - Lock, unlock, and trylock functions, with or without disabling irqs/preempt - Registered as a platform device driver The device initialization uses hwmod to configure the devices. One device will be created for each IP. It will pass spinlock register offset info to the driver. The device initialization file is: arch/arm/mach-omap2/hwspinlocks.c The driver takes in register offset info passed in device initialization. It uses hwmod to obtain the base address of the hardware spinlock module. Then it reads info from the registers. The function hwspinlock_probe() initializes the array of spinlock structures, each containing a spinlock register address calculated from the base address and lock offsets. The device driver file is: arch/arm/plat-omap/hwspinlock.c Here's an API summary: int hwspinlock_lock(struct hwspinlock *); Attempt to lock a hardware spinlock. If it is busy, the function will keep trying until it succeeds. This is a blocking function. int hwspinlock_trylock(struct hwspinlock *); Attempt to lock a hardware spinlock. If it is busy, the function will return BUSY. If it succeeds in locking, the function will return ACQUIRED. This is a non-blocking function. int hwspinlock_unlock(struct hwspinlock *); Unlock a hardware spinlock. struct hwspinlock *hwspinlock_request(void); Provides for "dynamic allocation" of a hardware spinlock. It returns the handle to the next available (unallocated) spinlock. If no more locks are available, it returns NULL. struct hwspinlock *hwspinlock_request_specific(unsigned int); Provides for "static allocation" of a specific hardware spinlock. This allows the system to use a specific spinlock, identified by an ID. If the ID is invalid or if the desired lock is already allocated, this will return NULL. Otherwise it returns a spinlock handle. int hwspinlock_free(struct hwspinlock *); Frees an allocated hardware spinlock (either reserved or unreserved). Signed-off-by: Simon Que <[email protected]> Signed-off-by: Hari Kanigeri <[email protected]>
1 parent 3e20861 commit cf7b4a0

File tree

3 files changed

+434
-0
lines changed

3 files changed

+434
-0
lines changed

arch/arm/mach-omap2/hwspinlocks.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* OMAP hardware spinlock device initialization
3+
*
4+
* Copyright (C) 2010 Texas Instruments. All rights reserved.
5+
*
6+
* Contact: Simon Que <[email protected]>
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License
10+
* version 2 as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful, but
13+
* WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20+
* 02110-1301 USA
21+
*
22+
*/
23+
24+
#include <linux/module.h>
25+
#include <linux/interrupt.h>
26+
#include <linux/device.h>
27+
#include <linux/delay.h>
28+
#include <linux/io.h>
29+
#include <linux/slab.h>
30+
31+
#include <plat/hwspinlock.h>
32+
#include <plat/omap_device.h>
33+
#include <plat/omap_hwmod.h>
34+
35+
/* Spinlock register offsets */
36+
#define REVISION_OFFSET 0x0000
37+
#define SYSCONFIG_OFFSET 0x0010
38+
#define SYSSTATUS_OFFSET 0x0014
39+
#define LOCK_BASE_OFFSET 0x0800
40+
#define LOCK_OFFSET(i) (LOCK_BASE_OFFSET + 0x4 * (i))
41+
42+
/* Initialization function */
43+
int __init hwspinlocks_init(void)
44+
{
45+
int retval = 0;
46+
47+
struct hwspinlock_plat_info *pdata;
48+
struct omap_hwmod *oh;
49+
char *oh_name, *pdev_name;
50+
51+
oh_name = "spinlock";
52+
oh = omap_hwmod_lookup(oh_name);
53+
if (WARN_ON(oh == NULL))
54+
return -EINVAL;
55+
56+
pdev_name = "hwspinlock";
57+
58+
/* Pass data to device initialization */
59+
pdata = kzalloc(sizeof(struct hwspinlock_plat_info), GFP_KERNEL);
60+
if (WARN_ON(pdata == NULL))
61+
return -ENOMEM;
62+
pdata->sysstatus_offset = SYSSTATUS_OFFSET;
63+
pdata->lock_base_offset = LOCK_BASE_OFFSET;
64+
65+
omap_device_build(pdev_name, 0, oh, pdata,
66+
sizeof(struct hwspinlock_plat_info), NULL, 0, false);
67+
68+
return retval;
69+
}
70+
module_init(hwspinlocks_init);

0 commit comments

Comments
 (0)