superhyway: multiple block support and VCR rework.
PATCH 3/7 superhyway: multiple block support and VCR rework.
This extends the API somewhat to allow for platform-specific VCR reading and writing. Some platforms (like SH4-202) implement the VCR in a split VCRL and VCRH, but end up being in reverse order or have other quirks that need to be dealt with, so we add a set of superhyway_ops per-bus to accomodate this.
We also have to extend the per-device resources somewhat, as some devices now conveniently split control and data blocks. So we allow a platform to register its set of SuperHyway devices via superhyway_add_devices() with the control block always ordered as the first resource (as this is the one that userspace cares about).
---
drivers/sh/superhyway/superhyway-sysfs.c | 2 - drivers/sh/superhyway/superhyway.c | 75 ++++++++++++++++++++++-------- include/linux/superhyway.h | 38 +++++++++++++-- 3 files changed, 89 insertions(+), 26 deletions(-)
applies-to: 5fc5d4c409d79b3169d83d4c328594ee04d04e89 6953dc79aabf3938acfe2cb0860a3ea7da08dc54
drivers/sh/superhyway/superhyway-sysfs.c +1 -1
@@ -30,7 +30,7 @@ superhyway_ro_attr(bot_mb, "0x%02x\n", vsuperhyway_ro_attr (top_mb,"0x%02x\n" , vcr.top_mb);/* Misc */ -superhyway_ro_attr (resource,"0x%08lx\n" , resource.start); +superhyway_ro_attr (resource,"0x%08lx\n" , resource[0 ].start);struct device_attribute superhyway_dev_attrs[] = {__ATTR_RO (perr_flags),
drivers/sh/superhyway/superhyway.c +55 -20
118 lines not on this page · raw message
include/linux/superhyway.h +33 -5
@@ -19,7 +19,7 @@*/ #define SUPERHYWAY_DEVICE_ID_SH5_DMAC 0x0183 -struct vcr_info { +struct superhyway_vcr_info {u8 perr_flags;/* P-port Error flags */ u8 merr_flags;/* Module Error flags */ u16 mod_vers;/* Module Version */
@@ -28,6 +28,17 @@ struct vcr_info {u8 top_mb;/* Top Memory block */ }; +struct superhyway_ops { +int (*read_vcr)(unsigned long base,struct superhyway_vcr_info *vcr); +int (*write_vcr)(unsigned long base,struct superhyway_vcr_info vcr); +}; + +struct superhyway_bus { +struct superhyway_ops *ops; +}; + +extern struct superhyway_bus superhyway_channels[]; +struct superhyway_device_id {unsigned int id;unsigned long driver_data;
@@ -55,9 +66,11 @@ struct superhyway_device {struct superhyway_device_id id;struct superhyway_driver *drv; +struct superhyway_bus *bus; -struct resource resource; -struct vcr_info vcr; +int num_resources; +struct resource *resource; +struct superhyway_vcr_info vcr; };#define to_superhyway_device (d) container_of((d), struct superhyway_device, dev)
@@ -65,12 +78,27 @@ struct superhyway_device {#define superhyway_get_drvdata (d) dev_get_drvdata(&(d)->dev)#define superhyway_set_drvdata (d,p) dev_set_drvdata(&(d)->dev, (p)) -extern int superhyway_scan_bus (void ); +static inline int +superhyway_read_vcr (struct superhyway_device *dev,unsigned long base, +struct superhyway_vcr_info *vcr) +{ +return dev->bus->ops->read_vcr (base, vcr); +} + +static inline int +superhyway_write_vcr (struct superhyway_device *dev,unsigned long base, +struct superhyway_vcr_info vcr) +{ +return dev->bus->ops->write_vcr (base, vcr); +} + +extern int superhyway_scan_bus (struct superhyway_bus *);/* drivers/sh/superhyway/superhyway.c */ int superhyway_register_driver (struct superhyway_driver *);void superhyway_unregister_driver (struct superhyway_driver *); -int superhyway_add_device (unsigned int ,unsigned long ,unsigned long long ); +int superhyway_add_device (unsigned long base,struct superhyway_device *,struct superhyway_bus *); +int superhyway_add_devices (struct superhyway_bus *bus,struct superhyway_device **devices,int nr_devices);/* drivers/sh/superhyway/superhyway-sysfs.c */ extern struct device_attribute superhyway_dev_attrs[];
---
0.99.8.GIT