diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 18:40:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 18:40:39 -0500 |
commit | ea14fad0d416354a4e9bb1a04f32acba706f9548 (patch) | |
tree | 2c8acc5331f189aef1d40ddce3f40d6be9314e77 /drivers/amba/bus.c | |
parent | 6ee7e78e7c78d871409ad4df30551c9355be7d0e (diff) | |
parent | 6705cda24fad1cb0ac82ac4f312df8ec735b39b0 (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (76 commits)
[ARM] 4002/1: S3C24XX: leave parent IRQs unmasked
[ARM] 4001/1: S3C24XX: shorten reboot time
[ARM] 3983/2: remove unused argument to __bug()
[ARM] 4000/1: Osiris: add third serial port in
[ARM] 3999/1: RX3715: suspend to RAM support
[ARM] 3998/1: VR1000: LED platform devices
[ARM] 3995/1: iop13xx: add iop13xx support
[ARM] 3968/1: iop13xx: add iop13xx_defconfig
[ARM] Update mach-types
[ARM] Allow gcc to optimise arm_add_memory a little more
[ARM] 3991/1: i.MX/MX1 high resolution time source
[ARM] 3990/1: i.MX/MX1 more precise PLL decode
[ARM] 3986/1: H1940: suspend to RAM support
[ARM] 3985/1: ixp4xx clocksource cleanup
[ARM] 3984/1: ixp4xx/nslu2: Fix disk LED numbering (take 2)
[ARM] 3994/1: ixp23xx: fix handling of pci master aborts
[ARM] 3981/1: sched_clock for PXA2xx
[ARM] 3980/1: extend the ARM Versatile sched_clock implementation from 32 to 63 bit
[ARM] 3979/1: extend the SA11x0 sched_clock implementation from 32 to 63 bit period
[ARM] 3978/1: macro to provide a 63-bit value from a 32-bit hardware counter
...
Diffstat (limited to 'drivers/amba/bus.c')
-rw-r--r-- | drivers/amba/bus.c | 113 |
1 files changed, 65 insertions, 48 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) | |||
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
82 | 82 | ||
83 | #define amba_attr_func(name,fmt,arg...) \ | ||
84 | static ssize_t name##_show(struct device *_dev, \ | ||
85 | struct device_attribute *attr, char *buf) \ | ||
86 | { \ | ||
87 | struct amba_device *dev = to_amba_device(_dev); \ | ||
88 | return sprintf(buf, fmt, arg); \ | ||
89 | } | ||
90 | |||
91 | #define amba_attr(name,fmt,arg...) \ | ||
92 | amba_attr_func(name,fmt,arg) \ | ||
93 | static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL) | ||
94 | |||
95 | amba_attr_func(id, "%08x\n", dev->periphid); | ||
96 | amba_attr(irq0, "%u\n", dev->irq[0]); | ||
97 | amba_attr(irq1, "%u\n", dev->irq[1]); | ||
98 | amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n", | ||
99 | (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, | ||
100 | dev->res.flags); | ||
101 | |||
102 | static struct device_attribute amba_dev_attrs[] = { | ||
103 | __ATTR_RO(id), | ||
104 | __ATTR_RO(resource), | ||
105 | __ATTR_NULL, | ||
106 | }; | ||
107 | |||
83 | /* | 108 | /* |
84 | * Primecells are part of the Advanced Microcontroller Bus Architecture, | 109 | * Primecells are part of the Advanced Microcontroller Bus Architecture, |
85 | * so we call the bus "amba". | 110 | * so we call the bus "amba". |
86 | */ | 111 | */ |
87 | static struct bus_type amba_bustype = { | 112 | static struct bus_type amba_bustype = { |
88 | .name = "amba", | 113 | .name = "amba", |
114 | .dev_attrs = amba_dev_attrs, | ||
89 | .match = amba_match, | 115 | .match = amba_match, |
90 | .uevent = amba_uevent, | 116 | .uevent = amba_uevent, |
91 | .suspend = amba_suspend, | 117 | .suspend = amba_suspend, |
@@ -169,21 +195,6 @@ static void amba_device_release(struct device *dev) | |||
169 | kfree(d); | 195 | kfree(d); |
170 | } | 196 | } |
171 | 197 | ||
172 | #define amba_attr(name,fmt,arg...) \ | ||
173 | static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf) \ | ||
174 | { \ | ||
175 | struct amba_device *dev = to_amba_device(_dev); \ | ||
176 | return sprintf(buf, fmt, arg); \ | ||
177 | } \ | ||
178 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | ||
179 | |||
180 | amba_attr(id, "%08x\n", dev->periphid); | ||
181 | amba_attr(irq0, "%u\n", dev->irq[0]); | ||
182 | amba_attr(irq1, "%u\n", dev->irq[1]); | ||
183 | amba_attr(resource, "\t%016llx\t%016llx\t%016lx\n", | ||
184 | (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, | ||
185 | dev->res.flags); | ||
186 | |||
187 | /** | 198 | /** |
188 | * amba_device_register - register an AMBA device | 199 | * amba_device_register - register an AMBA device |
189 | * @dev: AMBA device to register | 200 | * @dev: AMBA device to register |
@@ -208,40 +219,46 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
208 | dev_warn(&dev->dev, "coherent dma mask is unset\n"); | 219 | dev_warn(&dev->dev, "coherent dma mask is unset\n"); |
209 | 220 | ||
210 | ret = request_resource(parent, &dev->res); | 221 | ret = request_resource(parent, &dev->res); |
211 | if (ret == 0) { | 222 | if (ret) |
212 | tmp = ioremap(dev->res.start, SZ_4K); | 223 | goto err_out; |
213 | if (!tmp) { | 224 | |
214 | ret = -ENOMEM; | 225 | tmp = ioremap(dev->res.start, SZ_4K); |
215 | goto out; | 226 | if (!tmp) { |
216 | } | 227 | ret = -ENOMEM; |
217 | 228 | goto err_release; | |
218 | for (pid = 0, i = 0; i < 4; i++) | ||
219 | pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); | ||
220 | for (cid = 0, i = 0; i < 4; i++) | ||
221 | cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); | ||
222 | |||
223 | iounmap(tmp); | ||
224 | |||
225 | if (cid == 0xb105f00d) | ||
226 | dev->periphid = pid; | ||
227 | |||
228 | if (dev->periphid) | ||
229 | ret = device_register(&dev->dev); | ||
230 | else | ||
231 | ret = -ENODEV; | ||
232 | |||
233 | if (ret == 0) { | ||
234 | device_create_file(&dev->dev, &dev_attr_id); | ||
235 | if (dev->irq[0] != NO_IRQ) | ||
236 | device_create_file(&dev->dev, &dev_attr_irq0); | ||
237 | if (dev->irq[1] != NO_IRQ) | ||
238 | device_create_file(&dev->dev, &dev_attr_irq1); | ||
239 | device_create_file(&dev->dev, &dev_attr_resource); | ||
240 | } else { | ||
241 | out: | ||
242 | release_resource(&dev->res); | ||
243 | } | ||
244 | } | 229 | } |
230 | |||
231 | for (pid = 0, i = 0; i < 4; i++) | ||
232 | pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); | ||
233 | for (cid = 0, i = 0; i < 4; i++) | ||
234 | cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); | ||
235 | |||
236 | iounmap(tmp); | ||
237 | |||
238 | if (cid == 0xb105f00d) | ||
239 | dev->periphid = pid; | ||
240 | |||
241 | if (!dev->periphid) { | ||
242 | ret = -ENODEV; | ||
243 | goto err_release; | ||
244 | } | ||
245 | |||
246 | ret = device_register(&dev->dev); | ||
247 | if (ret) | ||
248 | goto err_release; | ||
249 | |||
250 | if (dev->irq[0] != NO_IRQ) | ||
251 | ret = device_create_file(&dev->dev, &dev_attr_irq0); | ||
252 | if (ret == 0 && dev->irq[1] != NO_IRQ) | ||
253 | ret = device_create_file(&dev->dev, &dev_attr_irq1); | ||
254 | if (ret == 0) | ||
255 | return ret; | ||
256 | |||
257 | device_unregister(&dev->dev); | ||
258 | |||
259 | err_release: | ||
260 | release_resource(&dev->res); | ||
261 | err_out: | ||
245 | return ret; | 262 | return ret; |
246 | } | 263 | } |
247 | 264 | ||