mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 23:42:43 +00:00
realtek: restructure rtl_table_read/write
These two functions are identical apart from writing different values to the read/write bit. Create a new function rtl_table_exec to reduce code duplication. Also replace the unbounded busy-waiting loop. The new implementation may sleep, but as the hardware typically responds before the first poll, any callers doing many table accesses still need to make sure not to block other kernel tasks themselves. So far, polling timeout errors are only handled by logging an error, but a return value is added to allow proper handling in the future. Signed-off-by: Jan Hoffmann <jan@3e8.eu>
This commit is contained in:
parent
9aa123d778
commit
ae0a3f88ac
@ -121,28 +121,45 @@ void rtl_table_release(struct table_reg *r)
|
|||||||
// pr_info("Unlock done\n");
|
// pr_info("Unlock done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtl_table_exec(struct table_reg *r, bool is_write, int idx)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 cmd, val;
|
||||||
|
|
||||||
|
/* Read/write bit has inverted meaning on RTL838x */
|
||||||
|
if (r->rmode)
|
||||||
|
cmd = is_write ? 0 : BIT(r->c_bit);
|
||||||
|
else
|
||||||
|
cmd = is_write ? BIT(r->c_bit) : 0;
|
||||||
|
|
||||||
|
cmd |= BIT(r->c_bit + 1); /* Execute bit */
|
||||||
|
cmd |= r->tbl << r->t_bit; /* Table type */
|
||||||
|
cmd |= idx & (BIT(r->t_bit) - 1); /* Index */
|
||||||
|
|
||||||
|
sw_w32(cmd, r->addr);
|
||||||
|
|
||||||
|
ret = readx_poll_timeout(sw_r32, r->addr, val,
|
||||||
|
!(val & BIT(r->c_bit + 1)), 20, 10000);
|
||||||
|
if (ret)
|
||||||
|
pr_err("%s: timeout\n", __func__);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads table index idx into the data registers of the table
|
* Reads table index idx into the data registers of the table
|
||||||
*/
|
*/
|
||||||
void rtl_table_read(struct table_reg *r, int idx)
|
int rtl_table_read(struct table_reg *r, int idx)
|
||||||
{
|
{
|
||||||
u32 cmd = r->rmode ? BIT(r->c_bit) : 0;
|
return rtl_table_exec(r, false, idx);
|
||||||
|
|
||||||
cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1));
|
|
||||||
sw_w32(cmd, r->addr);
|
|
||||||
do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes the content of the table data registers into the table at index idx
|
* Writes the content of the table data registers into the table at index idx
|
||||||
*/
|
*/
|
||||||
void rtl_table_write(struct table_reg *r, int idx)
|
int rtl_table_write(struct table_reg *r, int idx)
|
||||||
{
|
{
|
||||||
u32 cmd = r->rmode ? 0 : BIT(r->c_bit);
|
return rtl_table_exec(r, true, idx);
|
||||||
|
|
||||||
cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1));
|
|
||||||
sw_w32(cmd, r->addr);
|
|
||||||
do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,8 +67,8 @@ typedef enum {
|
|||||||
void rtl_table_init(void);
|
void rtl_table_init(void);
|
||||||
struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t);
|
struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t);
|
||||||
void rtl_table_release(struct table_reg *r);
|
void rtl_table_release(struct table_reg *r);
|
||||||
void rtl_table_read(struct table_reg *r, int idx);
|
int rtl_table_read(struct table_reg *r, int idx);
|
||||||
void rtl_table_write(struct table_reg *r, int idx);
|
int rtl_table_write(struct table_reg *r, int idx);
|
||||||
inline u16 rtl_table_data(struct table_reg *r, int i);
|
inline u16 rtl_table_data(struct table_reg *r, int i);
|
||||||
inline u32 rtl_table_data_r(struct table_reg *r, int i);
|
inline u32 rtl_table_data_r(struct table_reg *r, int i);
|
||||||
inline void rtl_table_data_w(struct table_reg *r, u32 v, int i);
|
inline void rtl_table_data_w(struct table_reg *r, u32 v, int i);
|
||||||
|
@ -121,28 +121,45 @@ void rtl_table_release(struct table_reg *r)
|
|||||||
// pr_info("Unlock done\n");
|
// pr_info("Unlock done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtl_table_exec(struct table_reg *r, bool is_write, int idx)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 cmd, val;
|
||||||
|
|
||||||
|
/* Read/write bit has inverted meaning on RTL838x */
|
||||||
|
if (r->rmode)
|
||||||
|
cmd = is_write ? 0 : BIT(r->c_bit);
|
||||||
|
else
|
||||||
|
cmd = is_write ? BIT(r->c_bit) : 0;
|
||||||
|
|
||||||
|
cmd |= BIT(r->c_bit + 1); /* Execute bit */
|
||||||
|
cmd |= r->tbl << r->t_bit; /* Table type */
|
||||||
|
cmd |= idx & (BIT(r->t_bit) - 1); /* Index */
|
||||||
|
|
||||||
|
sw_w32(cmd, r->addr);
|
||||||
|
|
||||||
|
ret = readx_poll_timeout(sw_r32, r->addr, val,
|
||||||
|
!(val & BIT(r->c_bit + 1)), 20, 10000);
|
||||||
|
if (ret)
|
||||||
|
pr_err("%s: timeout\n", __func__);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads table index idx into the data registers of the table
|
* Reads table index idx into the data registers of the table
|
||||||
*/
|
*/
|
||||||
void rtl_table_read(struct table_reg *r, int idx)
|
int rtl_table_read(struct table_reg *r, int idx)
|
||||||
{
|
{
|
||||||
u32 cmd = r->rmode ? BIT(r->c_bit) : 0;
|
return rtl_table_exec(r, false, idx);
|
||||||
|
|
||||||
cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1));
|
|
||||||
sw_w32(cmd, r->addr);
|
|
||||||
do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes the content of the table data registers into the table at index idx
|
* Writes the content of the table data registers into the table at index idx
|
||||||
*/
|
*/
|
||||||
void rtl_table_write(struct table_reg *r, int idx)
|
int rtl_table_write(struct table_reg *r, int idx)
|
||||||
{
|
{
|
||||||
u32 cmd = r->rmode ? 0 : BIT(r->c_bit);
|
return rtl_table_exec(r, true, idx);
|
||||||
|
|
||||||
cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1));
|
|
||||||
sw_w32(cmd, r->addr);
|
|
||||||
do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,8 +67,8 @@ typedef enum {
|
|||||||
void rtl_table_init(void);
|
void rtl_table_init(void);
|
||||||
struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t);
|
struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t);
|
||||||
void rtl_table_release(struct table_reg *r);
|
void rtl_table_release(struct table_reg *r);
|
||||||
void rtl_table_read(struct table_reg *r, int idx);
|
int rtl_table_read(struct table_reg *r, int idx);
|
||||||
void rtl_table_write(struct table_reg *r, int idx);
|
int rtl_table_write(struct table_reg *r, int idx);
|
||||||
inline u16 rtl_table_data(struct table_reg *r, int i);
|
inline u16 rtl_table_data(struct table_reg *r, int i);
|
||||||
inline u32 rtl_table_data_r(struct table_reg *r, int i);
|
inline u32 rtl_table_data_r(struct table_reg *r, int i);
|
||||||
inline void rtl_table_data_w(struct table_reg *r, u32 v, int i);
|
inline void rtl_table_data_w(struct table_reg *r, u32 v, int i);
|
||||||
|
Loading…
Reference in New Issue
Block a user