Back to home page

OSCL-LXR

 
 

    


0001 ===========================
0002 Hardware Spinlock Framework
0003 ===========================
0004 
0005 Introduction
0006 ============
0007 
0008 Hardware spinlock modules provide hardware assistance for synchronization
0009 and mutual exclusion between heterogeneous processors and those not operating
0010 under a single, shared operating system.
0011 
0012 For example, OMAP4 has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP,
0013 each of which is running a different Operating System (the master, A9,
0014 is usually running Linux and the slave processors, the M3 and the DSP,
0015 are running some flavor of RTOS).
0016 
0017 A generic hwspinlock framework allows platform-independent drivers to use
0018 the hwspinlock device in order to access data structures that are shared
0019 between remote processors, that otherwise have no alternative mechanism
0020 to accomplish synchronization and mutual exclusion operations.
0021 
0022 This is necessary, for example, for Inter-processor communications:
0023 on OMAP4, cpu-intensive multimedia tasks are offloaded by the host to the
0024 remote M3 and/or C64x+ slave processors (by an IPC subsystem called Syslink).
0025 
0026 To achieve fast message-based communications, a minimal kernel support
0027 is needed to deliver messages arriving from a remote processor to the
0028 appropriate user process.
0029 
0030 This communication is based on simple data structures that is shared between
0031 the remote processors, and access to it is synchronized using the hwspinlock
0032 module (remote processor directly places new messages in this shared data
0033 structure).
0034 
0035 A common hwspinlock interface makes it possible to have generic, platform-
0036 independent, drivers.
0037 
0038 User API
0039 ========
0040 
0041 ::
0042 
0043   struct hwspinlock *hwspin_lock_request(void);
0044 
0045 Dynamically assign an hwspinlock and return its address, or NULL
0046 in case an unused hwspinlock isn't available. Users of this
0047 API will usually want to communicate the lock's id to the remote core
0048 before it can be used to achieve synchronization.
0049 
0050 Should be called from a process context (might sleep).
0051 
0052 ::
0053 
0054   struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
0055 
0056 Assign a specific hwspinlock id and return its address, or NULL
0057 if that hwspinlock is already in use. Usually board code will
0058 be calling this function in order to reserve specific hwspinlock
0059 ids for predefined purposes.
0060 
0061 Should be called from a process context (might sleep).
0062 
0063 ::
0064 
0065   int of_hwspin_lock_get_id(struct device_node *np, int index);
0066 
0067 Retrieve the global lock id for an OF phandle-based specific lock.
0068 This function provides a means for DT users of a hwspinlock module
0069 to get the global lock id of a specific hwspinlock, so that it can
0070 be requested using the normal hwspin_lock_request_specific() API.
0071 
0072 The function returns a lock id number on success, -EPROBE_DEFER if
0073 the hwspinlock device is not yet registered with the core, or other
0074 error values.
0075 
0076 Should be called from a process context (might sleep).
0077 
0078 ::
0079 
0080   int hwspin_lock_free(struct hwspinlock *hwlock);
0081 
0082 Free a previously-assigned hwspinlock; returns 0 on success, or an
0083 appropriate error code on failure (e.g. -EINVAL if the hwspinlock
0084 is already free).
0085 
0086 Should be called from a process context (might sleep).
0087 
0088 ::
0089 
0090   int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
0091 
0092 Lock a previously-assigned hwspinlock with a timeout limit (specified in
0093 msecs). If the hwspinlock is already taken, the function will busy loop
0094 waiting for it to be released, but give up when the timeout elapses.
0095 Upon a successful return from this function, preemption is disabled so
0096 the caller must not sleep, and is advised to release the hwspinlock as
0097 soon as possible, in order to minimize remote cores polling on the
0098 hardware interconnect.
0099 
0100 Returns 0 when successful and an appropriate error code otherwise (most
0101 notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
0102 The function will never sleep.
0103 
0104 ::
0105 
0106   int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int timeout);
0107 
0108 Lock a previously-assigned hwspinlock with a timeout limit (specified in
0109 msecs). If the hwspinlock is already taken, the function will busy loop
0110 waiting for it to be released, but give up when the timeout elapses.
0111 Upon a successful return from this function, preemption and the local
0112 interrupts are disabled, so the caller must not sleep, and is advised to
0113 release the hwspinlock as soon as possible.
0114 
0115 Returns 0 when successful and an appropriate error code otherwise (most
0116 notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
0117 The function will never sleep.
0118 
0119 ::
0120 
0121   int hwspin_lock_timeout_irqsave(struct hwspinlock *hwlock, unsigned int to,
0122                                   unsigned long *flags);
0123 
0124 Lock a previously-assigned hwspinlock with a timeout limit (specified in
0125 msecs). If the hwspinlock is already taken, the function will busy loop
0126 waiting for it to be released, but give up when the timeout elapses.
0127 Upon a successful return from this function, preemption is disabled,
0128 local interrupts are disabled and their previous state is saved at the
0129 given flags placeholder. The caller must not sleep, and is advised to
0130 release the hwspinlock as soon as possible.
0131 
0132 Returns 0 when successful and an appropriate error code otherwise (most
0133 notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
0134 
0135 The function will never sleep.
0136 
0137 ::
0138 
0139   int hwspin_lock_timeout_raw(struct hwspinlock *hwlock, unsigned int timeout);
0140 
0141 Lock a previously-assigned hwspinlock with a timeout limit (specified in
0142 msecs). If the hwspinlock is already taken, the function will busy loop
0143 waiting for it to be released, but give up when the timeout elapses.
0144 
0145 Caution: User must protect the routine of getting hardware lock with mutex
0146 or spinlock to avoid dead-lock, that will let user can do some time-consuming
0147 or sleepable operations under the hardware lock.
0148 
0149 Returns 0 when successful and an appropriate error code otherwise (most
0150 notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
0151 
0152 The function will never sleep.
0153 
0154 ::
0155 
0156   int hwspin_lock_timeout_in_atomic(struct hwspinlock *hwlock, unsigned int to);
0157 
0158 Lock a previously-assigned hwspinlock with a timeout limit (specified in
0159 msecs). If the hwspinlock is already taken, the function will busy loop
0160 waiting for it to be released, but give up when the timeout elapses.
0161 
0162 This function shall be called only from an atomic context and the timeout
0163 value shall not exceed a few msecs.
0164 
0165 Returns 0 when successful and an appropriate error code otherwise (most
0166 notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
0167 
0168 The function will never sleep.
0169 
0170 ::
0171 
0172   int hwspin_trylock(struct hwspinlock *hwlock);
0173 
0174 
0175 Attempt to lock a previously-assigned hwspinlock, but immediately fail if
0176 it is already taken.
0177 
0178 Upon a successful return from this function, preemption is disabled so
0179 caller must not sleep, and is advised to release the hwspinlock as soon as
0180 possible, in order to minimize remote cores polling on the hardware
0181 interconnect.
0182 
0183 Returns 0 on success and an appropriate error code otherwise (most
0184 notably -EBUSY if the hwspinlock was already taken).
0185 The function will never sleep.
0186 
0187 ::
0188 
0189   int hwspin_trylock_irq(struct hwspinlock *hwlock);
0190 
0191 
0192 Attempt to lock a previously-assigned hwspinlock, but immediately fail if
0193 it is already taken.
0194 
0195 Upon a successful return from this function, preemption and the local
0196 interrupts are disabled so caller must not sleep, and is advised to
0197 release the hwspinlock as soon as possible.
0198 
0199 Returns 0 on success and an appropriate error code otherwise (most
0200 notably -EBUSY if the hwspinlock was already taken).
0201 
0202 The function will never sleep.
0203 
0204 ::
0205 
0206   int hwspin_trylock_irqsave(struct hwspinlock *hwlock, unsigned long *flags);
0207 
0208 Attempt to lock a previously-assigned hwspinlock, but immediately fail if
0209 it is already taken.
0210 
0211 Upon a successful return from this function, preemption is disabled,
0212 the local interrupts are disabled and their previous state is saved
0213 at the given flags placeholder. The caller must not sleep, and is advised
0214 to release the hwspinlock as soon as possible.
0215 
0216 Returns 0 on success and an appropriate error code otherwise (most
0217 notably -EBUSY if the hwspinlock was already taken).
0218 The function will never sleep.
0219 
0220 ::
0221 
0222   int hwspin_trylock_raw(struct hwspinlock *hwlock);
0223 
0224 Attempt to lock a previously-assigned hwspinlock, but immediately fail if
0225 it is already taken.
0226 
0227 Caution: User must protect the routine of getting hardware lock with mutex
0228 or spinlock to avoid dead-lock, that will let user can do some time-consuming
0229 or sleepable operations under the hardware lock.
0230 
0231 Returns 0 on success and an appropriate error code otherwise (most
0232 notably -EBUSY if the hwspinlock was already taken).
0233 The function will never sleep.
0234 
0235 ::
0236 
0237   int hwspin_trylock_in_atomic(struct hwspinlock *hwlock);
0238 
0239 Attempt to lock a previously-assigned hwspinlock, but immediately fail if
0240 it is already taken.
0241 
0242 This function shall be called only from an atomic context.
0243 
0244 Returns 0 on success and an appropriate error code otherwise (most
0245 notably -EBUSY if the hwspinlock was already taken).
0246 The function will never sleep.
0247 
0248 ::
0249 
0250   void hwspin_unlock(struct hwspinlock *hwlock);
0251 
0252 Unlock a previously-locked hwspinlock. Always succeed, and can be called
0253 from any context (the function never sleeps).
0254 
0255 .. note::
0256 
0257   code should **never** unlock an hwspinlock which is already unlocked
0258   (there is no protection against this).
0259 
0260 ::
0261 
0262   void hwspin_unlock_irq(struct hwspinlock *hwlock);
0263 
0264 Unlock a previously-locked hwspinlock and enable local interrupts.
0265 The caller should **never** unlock an hwspinlock which is already unlocked.
0266 
0267 Doing so is considered a bug (there is no protection against this).
0268 Upon a successful return from this function, preemption and local
0269 interrupts are enabled. This function will never sleep.
0270 
0271 ::
0272 
0273   void
0274   hwspin_unlock_irqrestore(struct hwspinlock *hwlock, unsigned long *flags);
0275 
0276 Unlock a previously-locked hwspinlock.
0277 
0278 The caller should **never** unlock an hwspinlock which is already unlocked.
0279 Doing so is considered a bug (there is no protection against this).
0280 Upon a successful return from this function, preemption is reenabled,
0281 and the state of the local interrupts is restored to the state saved at
0282 the given flags. This function will never sleep.
0283 
0284 ::
0285 
0286   void hwspin_unlock_raw(struct hwspinlock *hwlock);
0287 
0288 Unlock a previously-locked hwspinlock.
0289 
0290 The caller should **never** unlock an hwspinlock which is already unlocked.
0291 Doing so is considered a bug (there is no protection against this).
0292 This function will never sleep.
0293 
0294 ::
0295 
0296   void hwspin_unlock_in_atomic(struct hwspinlock *hwlock);
0297 
0298 Unlock a previously-locked hwspinlock.
0299 
0300 The caller should **never** unlock an hwspinlock which is already unlocked.
0301 Doing so is considered a bug (there is no protection against this).
0302 This function will never sleep.
0303 
0304 ::
0305 
0306   int hwspin_lock_get_id(struct hwspinlock *hwlock);
0307 
0308 Retrieve id number of a given hwspinlock. This is needed when an
0309 hwspinlock is dynamically assigned: before it can be used to achieve
0310 mutual exclusion with a remote cpu, the id number should be communicated
0311 to the remote task with which we want to synchronize.
0312 
0313 Returns the hwspinlock id number, or -EINVAL if hwlock is null.
0314 
0315 Typical usage
0316 =============
0317 
0318 ::
0319 
0320         #include <linux/hwspinlock.h>
0321         #include <linux/err.h>
0322 
0323         int hwspinlock_example1(void)
0324         {
0325                 struct hwspinlock *hwlock;
0326                 int ret;
0327 
0328                 /* dynamically assign a hwspinlock */
0329                 hwlock = hwspin_lock_request();
0330                 if (!hwlock)
0331                         ...
0332 
0333                 id = hwspin_lock_get_id(hwlock);
0334                 /* probably need to communicate id to a remote processor now */
0335 
0336                 /* take the lock, spin for 1 sec if it's already taken */
0337                 ret = hwspin_lock_timeout(hwlock, 1000);
0338                 if (ret)
0339                         ...
0340 
0341                 /*
0342                 * we took the lock, do our thing now, but do NOT sleep
0343                 */
0344 
0345                 /* release the lock */
0346                 hwspin_unlock(hwlock);
0347 
0348                 /* free the lock */
0349                 ret = hwspin_lock_free(hwlock);
0350                 if (ret)
0351                         ...
0352 
0353                 return ret;
0354         }
0355 
0356         int hwspinlock_example2(void)
0357         {
0358                 struct hwspinlock *hwlock;
0359                 int ret;
0360 
0361                 /*
0362                 * assign a specific hwspinlock id - this should be called early
0363                 * by board init code.
0364                 */
0365                 hwlock = hwspin_lock_request_specific(PREDEFINED_LOCK_ID);
0366                 if (!hwlock)
0367                         ...
0368 
0369                 /* try to take it, but don't spin on it */
0370                 ret = hwspin_trylock(hwlock);
0371                 if (!ret) {
0372                         pr_info("lock is already taken\n");
0373                         return -EBUSY;
0374                 }
0375 
0376                 /*
0377                 * we took the lock, do our thing now, but do NOT sleep
0378                 */
0379 
0380                 /* release the lock */
0381                 hwspin_unlock(hwlock);
0382 
0383                 /* free the lock */
0384                 ret = hwspin_lock_free(hwlock);
0385                 if (ret)
0386                         ...
0387 
0388                 return ret;
0389         }
0390 
0391 
0392 API for implementors
0393 ====================
0394 
0395 ::
0396 
0397   int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
0398                 const struct hwspinlock_ops *ops, int base_id, int num_locks);
0399 
0400 To be called from the underlying platform-specific implementation, in
0401 order to register a new hwspinlock device (which is usually a bank of
0402 numerous locks). Should be called from a process context (this function
0403 might sleep).
0404 
0405 Returns 0 on success, or appropriate error code on failure.
0406 
0407 ::
0408 
0409   int hwspin_lock_unregister(struct hwspinlock_device *bank);
0410 
0411 To be called from the underlying vendor-specific implementation, in order
0412 to unregister an hwspinlock device (which is usually a bank of numerous
0413 locks).
0414 
0415 Should be called from a process context (this function might sleep).
0416 
0417 Returns the address of hwspinlock on success, or NULL on error (e.g.
0418 if the hwspinlock is still in use).
0419 
0420 Important structs
0421 =================
0422 
0423 struct hwspinlock_device is a device which usually contains a bank
0424 of hardware locks. It is registered by the underlying hwspinlock
0425 implementation using the hwspin_lock_register() API.
0426 
0427 ::
0428 
0429         /**
0430         * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
0431         * @dev: underlying device, will be used to invoke runtime PM api
0432         * @ops: platform-specific hwspinlock handlers
0433         * @base_id: id index of the first lock in this device
0434         * @num_locks: number of locks in this device
0435         * @lock: dynamically allocated array of 'struct hwspinlock'
0436         */
0437         struct hwspinlock_device {
0438                 struct device *dev;
0439                 const struct hwspinlock_ops *ops;
0440                 int base_id;
0441                 int num_locks;
0442                 struct hwspinlock lock[0];
0443         };
0444 
0445 struct hwspinlock_device contains an array of hwspinlock structs, each
0446 of which represents a single hardware lock::
0447 
0448         /**
0449         * struct hwspinlock - this struct represents a single hwspinlock instance
0450         * @bank: the hwspinlock_device structure which owns this lock
0451         * @lock: initialized and used by hwspinlock core
0452         * @priv: private data, owned by the underlying platform-specific hwspinlock drv
0453         */
0454         struct hwspinlock {
0455                 struct hwspinlock_device *bank;
0456                 spinlock_t lock;
0457                 void *priv;
0458         };
0459 
0460 When registering a bank of locks, the hwspinlock driver only needs to
0461 set the priv members of the locks. The rest of the members are set and
0462 initialized by the hwspinlock core itself.
0463 
0464 Implementation callbacks
0465 ========================
0466 
0467 There are three possible callbacks defined in 'struct hwspinlock_ops'::
0468 
0469         struct hwspinlock_ops {
0470                 int (*trylock)(struct hwspinlock *lock);
0471                 void (*unlock)(struct hwspinlock *lock);
0472                 void (*relax)(struct hwspinlock *lock);
0473         };
0474 
0475 The first two callbacks are mandatory:
0476 
0477 The ->trylock() callback should make a single attempt to take the lock, and
0478 return 0 on failure and 1 on success. This callback may **not** sleep.
0479 
0480 The ->unlock() callback releases the lock. It always succeed, and it, too,
0481 may **not** sleep.
0482 
0483 The ->relax() callback is optional. It is called by hwspinlock core while
0484 spinning on a lock, and can be used by the underlying implementation to force
0485 a delay between two successive invocations of ->trylock(). It may **not** sleep.