summaryrefslogtreecommitdiff
path: root/device.c
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2010-11-18 13:55:30 +0100
committerTobias Klauser <tklauser@distanz.ch>2010-11-18 13:55:30 +0100
commit498763e178b5d8f51c17057630779cd48393e6f6 (patch)
tree4937a7e8b76898e150fce43b69ca8bcd9aa05a92 /device.c
parent105d2c8f1436a91867ce352144baae5c390a32e1 (diff)
Generic device handling updates
Diffstat (limited to 'device.c')
-rw-r--r--device.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/device.c b/device.c
index 249d778..bec5a1a 100644
--- a/device.c
+++ b/device.c
@@ -22,6 +22,14 @@ static struct device *devices[] = {
};
#define DEVICES_COUNT ARRAY_SIZE(devices)
+bool device_generic_is_dev_addr(struct device *dev, uint32_t addr)
+{
+ if (addr >= dev->base && addr < dev->base + dev->size)
+ return true;
+
+ return false;
+}
+
int device_init_all(void)
{
unsigned int i;
@@ -30,7 +38,7 @@ int device_init_all(void)
for (i = 0; i < DEVICES_COUNT; i++) {
struct device *dev = devices[i];
- if (dev->init == NULL)
+ if (unlikely(dev->init == NULL))
continue;
ret = dev->init(dev);
@@ -39,8 +47,66 @@ int device_init_all(void)
break;
}
- vinfo("%s at 0x%08x\n", dev->name, dev->base);
+ if (dev->is_dev_addr == NULL)
+ dev->is_dev_addr = device_generic_is_dev_addr;
+
+ vinfo("%s at 0x%08x - 0x%08x\n", dev->name, dev->base,
+ (uint32_t)(dev->base + dev->size));
}
return ret;
}
+
+/**
+ * Get device mapped at a specific address.
+ *
+ * @param addr address to get the mapped device for
+ * @return pointer to the device mapped at addr, NULL if no device is
+ * mapped there
+ */
+struct device *device_get_by_addr(uint32_t addr)
+{
+ unsigned int i;
+ struct device *dev = NULL;
+
+ for (i = 0; i < DEVICES_COUNT; i++) {
+ dev = devices[i];
+ if (unlikely(dev->is_dev_addr == NULL))
+ continue;
+ if (dev->is_dev_addr(dev, addr))
+ return dev;
+ }
+
+ return NULL;
+}
+
+void device_simulate_all(void)
+{
+ unsigned int i;
+ struct device *dev;
+
+ for (i = 0; i < DEVICES_COUNT; i++) {
+ dev = devices[i];
+ if (likely(dev->simulate != NULL))
+ dev->simulate(dev);
+ }
+}
+
+void io_register_init(struct io_register *reg, uint32_t addr,
+ uint32_t valid, uint32_t readonly, uint32_t value)
+{
+ reg->addr = addr;
+ reg->valid_mask = valid;
+ reg->readonly_mask = readonly;
+ reg->value = value;
+}
+
+uint32_t io_register_read(struct io_register *reg)
+{
+ return reg->value & reg->valid_mask;
+}
+
+void io_register_write(struct io_register *reg, uint32_t value)
+{
+ reg->value = value & ~(reg->readonly_mask);
+}