w1: ds1wm: make endian clean and use standard io memory accessors
o Make endian clean, make HW-endianness configurable. o Use ioread*, iowrite* instead of __raw_readb,__raw_writeb to also use memory-barriers when accessing HW-registers. We do not want reordering to happen here. Both changes are tightly coupled, so I do them in one patch Signed-off-by: Johannes Poehlmann <johannes.poehlmann@izt-labs.de> Acked-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
242b476f82
commit
baa8055de0
|
@ -96,6 +96,7 @@ static struct {
|
|||
struct ds1wm_data {
|
||||
void __iomem *map;
|
||||
unsigned int bus_shift; /* # of shifts to calc register offsets */
|
||||
bool is_hw_big_endian;
|
||||
struct platform_device *pdev;
|
||||
const struct mfd_cell *cell;
|
||||
int irq;
|
||||
|
@ -115,12 +116,65 @@ struct ds1wm_data {
|
|||
static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
|
||||
u8 val)
|
||||
{
|
||||
__raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift));
|
||||
if (ds1wm_data->is_hw_big_endian) {
|
||||
switch (ds1wm_data->bus_shift) {
|
||||
case 0:
|
||||
iowrite8(val, ds1wm_data->map + (reg << 0));
|
||||
break;
|
||||
case 1:
|
||||
iowrite16be((u16)val, ds1wm_data->map + (reg << 1));
|
||||
break;
|
||||
case 2:
|
||||
iowrite32be((u32)val, ds1wm_data->map + (reg << 2));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (ds1wm_data->bus_shift) {
|
||||
case 0:
|
||||
iowrite8(val, ds1wm_data->map + (reg << 0));
|
||||
break;
|
||||
case 1:
|
||||
iowrite16((u16)val, ds1wm_data->map + (reg << 1));
|
||||
break;
|
||||
case 2:
|
||||
iowrite32((u32)val, ds1wm_data->map + (reg << 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
|
||||
{
|
||||
return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift));
|
||||
u32 val = 0;
|
||||
|
||||
if (ds1wm_data->is_hw_big_endian) {
|
||||
switch (ds1wm_data->bus_shift) {
|
||||
case 0:
|
||||
val = ioread8(ds1wm_data->map + (reg << 0));
|
||||
break;
|
||||
case 1:
|
||||
val = ioread16be(ds1wm_data->map + (reg << 1));
|
||||
break;
|
||||
case 2:
|
||||
val = ioread32be(ds1wm_data->map + (reg << 2));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (ds1wm_data->bus_shift) {
|
||||
case 0:
|
||||
val = ioread8(ds1wm_data->map + (reg << 0));
|
||||
break;
|
||||
case 1:
|
||||
val = ioread16(ds1wm_data->map + (reg << 1));
|
||||
break;
|
||||
case 2:
|
||||
val = ioread32(ds1wm_data->map + (reg << 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev_dbg(&ds1wm_data->pdev->dev,
|
||||
"ds1wm_read_register reg: %d, 32 bit val:%x\n", reg, val);
|
||||
return (u8)val;
|
||||
}
|
||||
|
||||
|
||||
|
@ -499,6 +553,8 @@ static int ds1wm_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ds1wm_data->is_hw_big_endian = plat->is_hw_big_endian;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
|
|
|
@ -16,6 +16,11 @@ struct ds1wm_driver_data {
|
|||
*/
|
||||
unsigned int reset_recover_delay;
|
||||
|
||||
/* Say 1 here for big endian Hardware
|
||||
* (only relevant with bus-shift > 0
|
||||
*/
|
||||
bool is_hw_big_endian;
|
||||
|
||||
/* left shift of register number to get register address offsett.
|
||||
* Only 0,1,2 allowed for 8,16 or 32 bit bus width respectively
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue