aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ramips')
-rw-r--r--target/linux/ramips/files/drivers/net/ramips_esw.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/target/linux/ramips/files/drivers/net/ramips_esw.c b/target/linux/ramips/files/drivers/net/ramips_esw.c
index f82d662ac3..a27ed2d6a8 100644
--- a/target/linux/ramips/files/drivers/net/ramips_esw.c
+++ b/target/linux/ramips/files/drivers/net/ramips_esw.c
@@ -31,6 +31,7 @@
struct rt305x_esw {
void __iomem *base;
struct rt305x_esw_platform_data *pdata;
+ spinlock_t reg_rw_lock;
};
static inline void
@@ -45,6 +46,27 @@ rt305x_esw_rr(struct rt305x_esw *esw, unsigned reg)
return __raw_readl(esw->base + reg);
}
+static inline void
+rt305x_esw_rmw_raw(struct rt305x_esw *esw, unsigned reg, unsigned long mask,
+ unsigned long val)
+{
+ unsigned long t;
+
+ t = __raw_readl(esw->base + reg) & ~mask;
+ __raw_writel(t | val, esw->base + reg);
+}
+
+static void
+rt305x_esw_rmw(struct rt305x_esw *esw, unsigned reg, unsigned long mask,
+ unsigned long val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&esw->reg_rw_lock, flags);
+ rt305x_esw_rmw_raw(esw, reg, mask, val);
+ spin_unlock_irqrestore(&esw->reg_rw_lock, flags);
+}
+
static u32
rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr, u32 phy_register,
u32 write_data)
@@ -170,6 +192,7 @@ rt305x_esw_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, esw);
esw->pdata = pdata;
+ spin_lock_init(&esw->reg_rw_lock);
rt305x_esw_hw_init(esw);
return 0;