Skip to content

Commit 89a1e1b

Browse files
Luis OliveiraWolfram Sang
authored andcommitted
i2c: designware: refactoring of the i2c-designware
- Factor out all _master() part of code from i2c-designware-core and i2c-designware-platdrv to separate functions. - Standardize all code related with MASTER mode. - I have to take off DW_IC_INTR_TX_EMPTY from DW_IC_INTR_DEFAULT_MASK because it is master specific. The purpose of this is to prepare the controller to have is I2C MASTER flow in a separate driver. To do this first all the functions/definitions related to the MASTER flow were identified. Signed-off-by: Luis Oliveira <[email protected]> Acked-by: Andy Shevchenko <[email protected]> Acked-by: Jarkko Nikula <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent e393f67 commit 89a1e1b

File tree

2 files changed

+52
-35
lines changed

2 files changed

+52
-35
lines changed

drivers/i2c/busses/i2c-designware-core.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@
8787
#define DW_IC_INTR_GEN_CALL 0x800
8888

8989
#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
90-
DW_IC_INTR_TX_EMPTY | \
9190
DW_IC_INTR_TX_ABRT | \
9291
DW_IC_INTR_STOP_DET)
93-
92+
#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MASK | \
93+
DW_IC_INTR_TX_EMPTY)
9494
#define DW_IC_STATUS_ACTIVITY 0x1
9595

9696
#define DW_IC_SDA_HOLD_RX_SHIFT 16
@@ -202,6 +202,16 @@ static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
202202
}
203203
}
204204

205+
static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
206+
{
207+
/* Configure Tx/Rx FIFO threshold levels */
208+
dw_writel(dev, dev->tx_fifo_depth / 2, DW_IC_TX_TL);
209+
dw_writel(dev, 0, DW_IC_RX_TL);
210+
211+
/* Configure the I2C master */
212+
dw_writel(dev, dev->master_cfg, DW_IC_CON);
213+
}
214+
205215
static u32
206216
i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
207217
{
@@ -440,13 +450,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
440450
"Hardware too old to adjust SDA hold time.\n");
441451
}
442452

443-
/* Configure Tx/Rx FIFO threshold levels */
444-
dw_writel(dev, dev->tx_fifo_depth / 2, DW_IC_TX_TL);
445-
dw_writel(dev, 0, DW_IC_RX_TL);
446-
447-
/* Configure the I2C master */
448-
dw_writel(dev, dev->master_cfg , DW_IC_CON);
449-
453+
i2c_dw_configure_fifo_master(dev);
450454
i2c_dw_release_lock(dev);
451455

452456
return 0;
@@ -511,7 +515,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
511515

512516
/* Clear and enable interrupts */
513517
dw_readl(dev, DW_IC_CLR_INTR);
514-
dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK);
518+
dw_writel(dev, DW_IC_INTR_MASTER_MASK, DW_IC_INTR_MASK);
515519
}
516520

517521
/*
@@ -531,7 +535,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
531535
u8 *buf = dev->tx_buf;
532536
bool need_restart = false;
533537

534-
intr_mask = DW_IC_INTR_DEFAULT_MASK;
538+
intr_mask = DW_IC_INTR_MASTER_MASK;
535539

536540
for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
537541
u32 flags = msgs[dev->msg_write_idx].flags;
@@ -881,22 +885,14 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
881885
}
882886

883887
/*
884-
* Interrupt service routine. This gets called whenever an I2C interrupt
888+
* Interrupt service routine. This gets called whenever an I2C master interrupt
885889
* occurs.
886890
*/
887-
static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
891+
static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
888892
{
889-
struct dw_i2c_dev *dev = dev_id;
890-
u32 stat, enabled;
891-
892-
enabled = dw_readl(dev, DW_IC_ENABLE);
893-
stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
894-
dev_dbg(dev->dev, "%s: enabled=%#x stat=%#x\n", __func__, enabled, stat);
895-
if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY))
896-
return IRQ_NONE;
893+
u32 stat;
897894

898895
stat = i2c_dw_read_clear_intrbits(dev);
899-
900896
if (stat & DW_IC_INTR_TX_ABRT) {
901897
dev->cmd_err |= DW_IC_ERR_TX_ABRT;
902898
dev->status = STATUS_IDLE;
@@ -931,6 +927,22 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
931927
dw_writel(dev, stat, DW_IC_INTR_MASK);
932928
}
933929

930+
return 0;
931+
}
932+
933+
static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
934+
{
935+
struct dw_i2c_dev *dev = dev_id;
936+
u32 stat, enabled;
937+
938+
enabled = dw_readl(dev, DW_IC_ENABLE);
939+
stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
940+
dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat);
941+
if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY))
942+
return IRQ_NONE;
943+
944+
i2c_dw_irq_handler_master(dev);
945+
934946
return IRQ_HANDLED;
935947
}
936948

drivers/i2c/busses/i2c-designware-platdrv.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,23 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
172172
}
173173
#endif
174174

175+
static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
176+
{
177+
dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
178+
DW_IC_CON_RESTART_EN;
179+
180+
switch (dev->clk_freq) {
181+
case 100000:
182+
dev->master_cfg |= DW_IC_CON_SPEED_STD;
183+
break;
184+
case 3400000:
185+
dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
186+
break;
187+
default:
188+
dev->master_cfg |= DW_IC_CON_SPEED_FAST;
189+
}
190+
}
191+
175192
static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare)
176193
{
177194
if (IS_ERR(i_dev->clk))
@@ -287,19 +304,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
287304

288305
dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
289306

290-
dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
291-
DW_IC_CON_RESTART_EN;
292-
293-
switch (dev->clk_freq) {
294-
case 100000:
295-
dev->master_cfg |= DW_IC_CON_SPEED_STD;
296-
break;
297-
case 3400000:
298-
dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
299-
break;
300-
default:
301-
dev->master_cfg |= DW_IC_CON_SPEED_FAST;
302-
}
307+
i2c_dw_configure_master(dev);
303308

304309
dev->clk = devm_clk_get(&pdev->dev, NULL);
305310
if (!i2c_dw_plat_prepare_clk(dev, true)) {

0 commit comments

Comments
 (0)