123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /*
- * RapidIO configuration space access support
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * 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/rio.h>
- #include <linux/module.h>
- /*
- * These interrupt-safe spinlocks protect all accesses to RIO
- * configuration space and doorbell access.
- */
- static DEFINE_SPINLOCK(rio_config_lock);
- static DEFINE_SPINLOCK(rio_doorbell_lock);
- /*
- * Wrappers for all RIO configuration access functions. They just check
- * alignment, do locking and call the low-level functions pointed to
- * by rio_mport->ops.
- */
- #define RIO_8_BAD 0
- #define RIO_16_BAD (offset & 1)
- #define RIO_32_BAD (offset & 3)
- /**
- * RIO_LOP_READ - Generate rio_local_read_config_* functions
- * @size: Size of configuration space read (8, 16, 32 bits)
- * @type: C type of value argument
- * @len: Length of configuration space read (1, 2, 4 bytes)
- *
- * Generates rio_local_read_config_* functions used to access
- * configuration space registers on the local device.
- */
- #define RIO_LOP_READ(size,type,len) \
- int __rio_local_read_config_##size \
- (struct rio_mport *mport, u32 offset, type *value) \
- { \
- int res; \
- unsigned long flags; \
- u32 data = 0; \
- if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
- spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
- *value = (type)data; \
- spin_unlock_irqrestore(&rio_config_lock, flags); \
- return res; \
- }
- /**
- * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
- * @size: Size of configuration space write (8, 16, 32 bits)
- * @type: C type of value argument
- * @len: Length of configuration space write (1, 2, 4 bytes)
- *
- * Generates rio_local_write_config_* functions used to access
- * configuration space registers on the local device.
- */
- #define RIO_LOP_WRITE(size,type,len) \
- int __rio_local_write_config_##size \
- (struct rio_mport *mport, u32 offset, type value) \
- { \
- int res; \
- unsigned long flags; \
- if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
- spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
- spin_unlock_irqrestore(&rio_config_lock, flags); \
- return res; \
- }
- RIO_LOP_READ(8, u8, 1)
- RIO_LOP_READ(16, u16, 2)
- RIO_LOP_READ(32, u32, 4)
- RIO_LOP_WRITE(8, u8, 1)
- RIO_LOP_WRITE(16, u16, 2)
- RIO_LOP_WRITE(32, u32, 4)
- EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
- EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
- EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
- EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
- EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
- EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
- /**
- * RIO_OP_READ - Generate rio_mport_read_config_* functions
- * @size: Size of configuration space read (8, 16, 32 bits)
- * @type: C type of value argument
- * @len: Length of configuration space read (1, 2, 4 bytes)
- *
- * Generates rio_mport_read_config_* functions used to access
- * configuration space registers on the local device.
- */
- #define RIO_OP_READ(size,type,len) \
- int rio_mport_read_config_##size \
- (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
- { \
- int res; \
- unsigned long flags; \
- u32 data = 0; \
- if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
- spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
- *value = (type)data; \
- spin_unlock_irqrestore(&rio_config_lock, flags); \
- return res; \
- }
- /**
- * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
- * @size: Size of configuration space write (8, 16, 32 bits)
- * @type: C type of value argument
- * @len: Length of configuration space write (1, 2, 4 bytes)
- *
- * Generates rio_mport_write_config_* functions used to access
- * configuration space registers on the local device.
- */
- #define RIO_OP_WRITE(size,type,len) \
- int rio_mport_write_config_##size \
- (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
- { \
- int res; \
- unsigned long flags; \
- if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
- spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
- spin_unlock_irqrestore(&rio_config_lock, flags); \
- return res; \
- }
- RIO_OP_READ(8, u8, 1)
- RIO_OP_READ(16, u16, 2)
- RIO_OP_READ(32, u32, 4)
- RIO_OP_WRITE(8, u8, 1)
- RIO_OP_WRITE(16, u16, 2)
- RIO_OP_WRITE(32, u32, 4)
- EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
- EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
- EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
- EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
- EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
- EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
- /**
- * rio_mport_send_doorbell - Send a doorbell message
- *
- * @mport: RIO master port
- * @destid: RIO device destination ID
- * @data: Doorbell message data
- *
- * Send a doorbell message to a RIO device. The doorbell message
- * has a 16-bit info field provided by the data argument.
- */
- int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
- {
- int res;
- unsigned long flags;
- spin_lock_irqsave(&rio_doorbell_lock, flags);
- res = mport->ops->dsend(mport, mport->id, destid, data);
- spin_unlock_irqrestore(&rio_doorbell_lock, flags);
- return res;
- }
- EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
|