diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/amba/bus.c | 113 | ||||
-rw-r--r-- | drivers/i2c/busses/Kconfig | 6 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 131 |
3 files changed, 69 insertions, 181 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 9e3e2a69c03a..fd5475071acc 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -80,12 +80,38 @@ static int amba_resume(struct device *dev) return ret; } +#define amba_attr_func(name,fmt,arg...) \ +static ssize_t name##_show(struct device *_dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct amba_device *dev = to_amba_device(_dev); \ + return sprintf(buf, fmt, arg); \ +} + +#define amba_attr(name,fmt,arg...) \ +amba_attr_func(name,fmt,arg) \ +static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL) + +amba_attr_func(id, "%08x\n", dev->periphid); +amba_attr(irq0, "%u\n", dev->irq[0]); +amba_attr(irq1, "%u\n", dev->irq[1]); +amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n", + (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, + dev->res.flags); + +static struct device_attribute amba_dev_attrs[] = { + __ATTR_RO(id), + __ATTR_RO(resource), + __ATTR_NULL, +}; + /* * Primecells are part of the Advanced Microcontroller Bus Architecture, * so we call the bus "amba". */ static struct bus_type amba_bustype = { .name = "amba", + .dev_attrs = amba_dev_attrs, .match = amba_match, .uevent = amba_uevent, .suspend = amba_suspend, @@ -169,21 +195,6 @@ static void amba_device_release(struct device *dev) kfree(d); } -#define amba_attr(name,fmt,arg...) \ -static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf) \ -{ \ - struct amba_device *dev = to_amba_device(_dev); \ - return sprintf(buf, fmt, arg); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) - -amba_attr(id, "%08x\n", dev->periphid); -amba_attr(irq0, "%u\n", dev->irq[0]); -amba_attr(irq1, "%u\n", dev->irq[1]); -amba_attr(resource, "\t%016llx\t%016llx\t%016lx\n", - (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, - dev->res.flags); - /** * amba_device_register - register an AMBA device * @dev: AMBA device to register @@ -208,40 +219,46 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) dev_warn(&dev->dev, "coherent dma mask is unset\n"); ret = request_resource(parent, &dev->res); - if (ret == 0) { - tmp = ioremap(dev->res.start, SZ_4K); - if (!tmp) { - ret = -ENOMEM; - goto out; - } - - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); - - iounmap(tmp); - - if (cid == 0xb105f00d) - dev->periphid = pid; - - if (dev->periphid) - ret = device_register(&dev->dev); - else - ret = -ENODEV; - - if (ret == 0) { - device_create_file(&dev->dev, &dev_attr_id); - if (dev->irq[0] != NO_IRQ) - device_create_file(&dev->dev, &dev_attr_irq0); - if (dev->irq[1] != NO_IRQ) - device_create_file(&dev->dev, &dev_attr_irq1); - device_create_file(&dev->dev, &dev_attr_resource); - } else { - out: - release_resource(&dev->res); - } + if (ret) + goto err_out; + + tmp = ioremap(dev->res.start, SZ_4K); + if (!tmp) { + ret = -ENOMEM; + goto err_release; } + + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); + for (cid = 0, i = 0; i < 4; i++) + cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); + + iounmap(tmp); + + if (cid == 0xb105f00d) + dev->periphid = pid; + + if (!dev->periphid) { + ret = -ENODEV; + goto err_release; + } + + ret = device_register(&dev->dev); + if (ret) + goto err_release; + + if (dev->irq[0] != NO_IRQ) + ret = device_create_file(&dev->dev, &dev_attr_irq0); + if (ret == 0 && dev->irq[1] != NO_IRQ) + ret = device_create_file(&dev->dev, &dev_attr_irq1); + if (ret == 0) + return ret; + + device_unregister(&dev->dev); + + err_release: + release_resource(&dev->res); + err_out: return ret; } diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 510816c16da3..5cbf8b9d5141 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -195,11 +195,11 @@ config I2C_IBM_IIC will be called i2c-ibm_iic. config I2C_IOP3XX - tristate "Intel IOP3xx and IXP4xx on-chip I2C interface" - depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX) && I2C + tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" + depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX) && I2C help Say Y here if you want to use the IIC bus controller on - the Intel IOP3xx I/O Processors or IXP4xx Network Processors. + the Intel IOPx3xx I/O Processors or IXP4xx Network Processors. This driver can also be built as a module. If so, the module will be called i2c-iop3xx. diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index c95a6c154165..c3b1567c852a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -358,133 +358,6 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c) #ifdef CONFIG_I2C_PXA_SLAVE /* - * I2C EEPROM emulation. - */ -static struct i2c_eeprom_emu eeprom = { - .size = I2C_EEPROM_EMU_SIZE, - .watch = LIST_HEAD_INIT(eeprom.watch), -}; - -struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void) -{ - return &eeprom; -} - -int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *emu, void *data, - unsigned int addr, unsigned int size, - struct i2c_eeprom_emu_watcher *watcher) -{ - struct i2c_eeprom_emu_watch *watch; - unsigned long flags; - - if (addr + size > emu->size) - return -EINVAL; - - watch = kmalloc(sizeof(struct i2c_eeprom_emu_watch), GFP_KERNEL); - if (watch) { - watch->start = addr; - watch->end = addr + size - 1; - watch->ops = watcher; - watch->data = data; - - local_irq_save(flags); - list_add(&watch->node, &emu->watch); - local_irq_restore(flags); - } - - return watch ? 0 : -ENOMEM; -} - -void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *emu, void *data, - struct i2c_eeprom_emu_watcher *watcher) -{ - struct i2c_eeprom_emu_watch *watch, *n; - unsigned long flags; - - list_for_each_entry_safe(watch, n, &emu->watch, node) { - if (watch->ops == watcher && watch->data == data) { - local_irq_save(flags); - list_del(&watch->node); - local_irq_restore(flags); - kfree(watch); - } - } -} - -static void i2c_eeprom_emu_event(void *ptr, i2c_slave_event_t event) -{ - struct i2c_eeprom_emu *emu = ptr; - - eedbg(3, "i2c_eeprom_emu_event: %d\n", event); - - switch (event) { - case I2C_SLAVE_EVENT_START_WRITE: - emu->seen_start = 1; - eedbg(2, "i2c_eeprom: write initiated\n"); - break; - - case I2C_SLAVE_EVENT_START_READ: - emu->seen_start = 0; - eedbg(2, "i2c_eeprom: read initiated\n"); - break; - - case I2C_SLAVE_EVENT_STOP: - emu->seen_start = 0; - eedbg(2, "i2c_eeprom: received stop\n"); - break; - - default: - eedbg(0, "i2c_eeprom: unhandled event\n"); - break; - } -} - -static int i2c_eeprom_emu_read(void *ptr) -{ - struct i2c_eeprom_emu *emu = ptr; - int ret; - - ret = emu->bytes[emu->ptr]; - emu->ptr = (emu->ptr + 1) % emu->size; - - return ret; -} - -static void i2c_eeprom_emu_write(void *ptr, unsigned int val) -{ - struct i2c_eeprom_emu *emu = ptr; - struct i2c_eeprom_emu_watch *watch; - - if (emu->seen_start != 0) { - eedbg(2, "i2c_eeprom_emu_write: setting ptr %02x\n", val); - emu->ptr = val; - emu->seen_start = 0; - return; - } - - emu->bytes[emu->ptr] = val; - - eedbg(1, "i2c_eeprom_emu_write: ptr=0x%02x, val=0x%02x\n", - emu->ptr, val); - - list_for_each_entry(watch, &emu->watch, node) { - if (!watch->ops || !watch->ops->write) - continue; - if (watch->start <= emu->ptr && watch->end >= emu->ptr) - watch->ops->write(watch->data, emu->ptr, val); - } - - emu->ptr = (emu->ptr + 1) % emu->size; -} - -struct i2c_slave_client eeprom_client = { - .data = &eeprom, - .event = i2c_eeprom_emu_event, - .read = i2c_eeprom_emu_read, - .write = i2c_eeprom_emu_write -}; - -/* * PXA I2C Slave mode */ @@ -963,11 +836,9 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->slave_addr = I2C_PXA_SLAVE_ADDR; #ifdef CONFIG_I2C_PXA_SLAVE - i2c->slave = &eeprom_client; if (plat) { i2c->slave_addr = plat->slave_addr; - if (plat->slave) - i2c->slave = plat->slave; + i2c->slave = plat->slave; } #endif |