Loading soc/soundwire.c +9 −4 Original line number Diff line number Diff line Loading @@ -796,18 +796,24 @@ struct swr_device *get_matching_swr_slave_device(struct device_node *np) { struct swr_device *swr = NULL; struct swr_master *master; bool found = false; mutex_lock(&board_lock); list_for_each_entry(master, &swr_master_list, list) { mutex_lock(&master->mlock); list_for_each_entry(swr, &master->devices, dev_list) { if (swr->dev.of_node == np) break; if (swr->dev.of_node == np) { found = true; mutex_unlock(&master->mlock); goto exit; } } mutex_unlock(&master->mlock); } exit: mutex_unlock(&board_lock); if (!found) return NULL; return swr; } EXPORT_SYMBOL(get_matching_swr_slave_device); Loading Loading @@ -888,7 +894,6 @@ int swr_register_master(struct swr_master *master) id = idr_alloc(&master_idr, master, master->bus_num, master->bus_num + 1, GFP_KERNEL); mutex_unlock(&swr_lock); if (id < 0) return id; Loading soc/swr-mstr-ctrl.c +82 −25 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ enum { #define TRUE 1 #define FALSE 0 #define SWRM_MAX_PORT_REG 40 #define SWRM_MAX_INIT_REG 8 #define SWRM_MAX_PORT_REG 120 #define SWRM_MAX_INIT_REG 10 #define SWR_MSTR_MAX_REG_ADDR 0x1740 #define SWR_MSTR_START_REG_ADDR 0x00 Loading Loading @@ -304,11 +304,13 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, if (swrm->bulk_write) swrm->bulk_write(swrm->handle, reg_addr, val, length); else { mutex_lock(&swrm->iolock); for (i = 0; i < length; i++) { /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(100, 105); swr_master_write(swrm, reg_addr[i], val[i]); } mutex_unlock(&swrm->iolock); } return 0; } Loading Loading @@ -403,6 +405,7 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u32 val; u32 retry_attempt = 0; mutex_lock(&swrm->iolock); val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); Loading @@ -411,9 +414,9 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, usleep_range(250, 255); retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, dev_addr, *cmd_data); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->rcmd_id, dev_addr, *cmd_data); if ((((*cmd_data) & 0xF00) >> 8) != swrm->rcmd_id) { if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) { /* wait 500 us before retry on fifo read failure */ Loading @@ -421,10 +424,17 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, retry_attempt++; goto retry_read; } else { dev_err_ratelimited(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, \ rcmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->rcmd_id, dev_addr, *cmd_data); dev_err_ratelimited(swrm->dev, "%s: failed to read fifo\n", __func__); } } mutex_unlock(&swrm->iolock); return 0; } Loading @@ -434,15 +444,16 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, u32 val; int ret = 0; mutex_lock(&swrm->iolock); if (!cmd_id) val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data, dev_addr, reg_addr); else val = swrm_get_packed_reg_val(&cmd_id, cmd_data, dev_addr, reg_addr); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, val:0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, val, dev_addr, cmd_data); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(250, 255); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); Loading @@ -457,6 +468,7 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, wait_for_completion_timeout(&swrm->broadcast, (2 * HZ/10)); } mutex_unlock(&swrm->iolock); return ret; } Loading @@ -472,7 +484,7 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len); Loading @@ -482,8 +494,8 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, if (!ret) *reg_val = (u8)val; pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } Loading @@ -499,12 +511,14 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, return -EINVAL; } pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); else swr_master_write(swrm, reg_addr, reg_val); pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } Loading @@ -524,6 +538,7 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, if (len <= 0) return -EINVAL; pm_runtime_get_sync(swrm->dev); if (dev_num) { swr_fifo_reg = kcalloc(len, sizeof(u32), GFP_KERNEL); if (!swr_fifo_reg) { Loading Loading @@ -560,6 +575,7 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, mem_fail: kfree(swr_fifo_reg); err: pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } Loading Loading @@ -1022,6 +1038,26 @@ static int swrm_disconnect_port(struct swr_master *master, return 0; } static int swrm_find_alert_slave(struct swr_mstr_ctrl *swrm, int status, u8 *devnum) { int i; bool found = false; for (i = 0; i < (swrm->master.num_dev + 1); i++) { if ((status & SWRM_MCP_SLV_STATUS_MASK) == SWR_ALERT) { *devnum = i; found = true; break; } status >>= 2; } if (found) return 0; else return -EINVAL; } static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, int status, u8 *devnum) { Loading Loading @@ -1049,7 +1085,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) { struct swr_mstr_ctrl *swrm = dev; u32 value, intr_sts; int status, chg_sts, i; u32 temp = 0; u32 status, chg_sts, i; u8 devnum = 0; int ret = IRQ_HANDLED; struct swr_device *swr_dev; Loading @@ -1067,13 +1104,16 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) if (!value) continue; swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, value); switch (value) { case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ: dev_dbg(swrm->dev, "Trigger irq to slave device\n"); status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); swrm_check_slave_change_status(swrm, status, &devnum); ret = swrm_find_alert_slave(swrm, status, &devnum); if (ret) { dev_err(swrm->dev, "no slave alert found.\ spurious interrupt\n"); return ret; } list_for_each_entry(swr_dev, &mstr->devices, dev_list) { if (swr_dev->dev_num != devnum) continue; Loading @@ -1082,6 +1122,12 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) irq_find_mapping( swr_dev->slave_irq, 0)); } swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1, 1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x0, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); break; case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: dev_dbg(swrm->dev, "SWR new slave attached\n"); Loading Loading @@ -1160,7 +1206,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) break; } } swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts); swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); mutex_unlock(&swrm->reslock); Loading Loading @@ -1196,13 +1243,13 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, num_dev = swrm->num_dev; else num_dev = mstr->num_dev; pm_runtime_get_sync(swrm->dev); for (i = 1; i < (num_dev + 1); i++) { id = ((u64)(swr_master_read(swrm, SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); id |= swr_master_read(swrm, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i)); /* * As pm_runtime_get_sync() brings all slaves out of reset * update logical device number for all slaves. Loading @@ -1220,6 +1267,11 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n", __func__, i, swr_dev->addr); swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0xF, SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0xF, SWRS_SCP_INT_STATUS_MASK_1); } } } Loading Loading @@ -1256,10 +1308,6 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_ENUMERATOR_CFG_ADDR; value[len++] = 1; /* Mask soundwire interrupts */ reg[len] = SWRM_INTERRUPT_MASK_ADDR; value[len++] = 0x1FFFD; /* Configure No pings */ val = swr_master_read(swrm, SWRM_MCP_CFG_ADDR); val &= ~SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK; Loading @@ -1272,15 +1320,22 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_CMD_FIFO_CFG_ADDR; value[len++] = val; /* Set IRQ to PULSE */ reg[len] = SWRM_COMP_CFG_ADDR; value[len++] = 0x02; reg[len] = SWRM_MCP_BUS_CTRL_ADDR; value[len++] = 0x2; /* Set IRQ to PULSE */ reg[len] = SWRM_COMP_CFG_ADDR; value[len++] = 0x03; reg[len] = SWRM_INTERRUPT_CLEAR; value[len++] = 0x08; value[len++] = 0xFFFFFFFF; /* Mask soundwire interrupts */ reg[len] = SWRM_INTERRUPT_MASK_ADDR; value[len++] = 0x1FFFD; reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; value[len++] = 0x1; swr_master_bulk_write(swrm, reg, value, len); Loading Loading @@ -1430,6 +1485,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->mlock); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); mutex_init(&swrm->iolock); for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); Loading Loading @@ -1535,6 +1591,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->iolock); err_pdata_fail: err_memory_fail: return ret; Loading soc/swr-mstr-ctrl.h +1 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ struct swr_mstr_ctrl { int clk_ref_count; struct completion reset; struct completion broadcast; struct mutex iolock; struct mutex mlock; struct mutex reslock; u32 swrm_base_reg; Loading soc/swrm_registers.h +9 −3 Original line number Diff line number Diff line Loading @@ -114,6 +114,8 @@ #define SWRM_INTERRUPT_CLEAR (SWRM_BASE_ADDRESS+0x00000208) #define SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN (SWRM_BASE_ADDRESS+0x00000210) #define SWRM_CMD_FIFO_WR_CMD (SWRM_BASE_ADDRESS + 0x00000300) #define SWRM_CMD_FIFO_WR_CMD_MASK 0xFFFFFFFF #define SWRM_CMD_FIFO_RD_CMD (SWRM_BASE_ADDRESS + 0x00000304) Loading Loading @@ -185,7 +187,8 @@ 0x40*m) #define SWRM_DP_BLOCK_CTRL_1(n) (SWRM_BASE_ADDRESS + \ 0x0000112C + 0x100*n) 0x0000112C + \ 0x100*(n-1)) #define SWRM_DP_BLOCK_CTRL2_BANK(n, m) (SWRM_BASE_ADDRESS + \ 0x00001130 + \ Loading @@ -204,7 +207,7 @@ #define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (SWRM_BASE_ADDRESS + \ 0x00001054 + 0x100*n) 0x00001054 + 0x100*(n-1)) #define SWRM_MAX_REGISTER SWRM_DIN_DPn_PCM_PORT_CTRL(7) Loading @@ -214,8 +217,11 @@ #define SWRS_DP_REG_OFFSET(port, bank) ((0x100*port)+(0x10*bank)) #define SWRS_SCP_INT_STATUS_CLEAR_1 0x40 #define SWRS_SCP_INT_STATUS_MASK_1 0x41 #define SWRS_SCP_CONTROL 0x44 #define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x120 + \ #define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x103 + \ 0x100 * n) #define SWRS_DP_CHANNEL_ENABLE_BANK(n, m) (SWRS_BASE_ADDRESS + 0x120 + \ Loading Loading
soc/soundwire.c +9 −4 Original line number Diff line number Diff line Loading @@ -796,18 +796,24 @@ struct swr_device *get_matching_swr_slave_device(struct device_node *np) { struct swr_device *swr = NULL; struct swr_master *master; bool found = false; mutex_lock(&board_lock); list_for_each_entry(master, &swr_master_list, list) { mutex_lock(&master->mlock); list_for_each_entry(swr, &master->devices, dev_list) { if (swr->dev.of_node == np) break; if (swr->dev.of_node == np) { found = true; mutex_unlock(&master->mlock); goto exit; } } mutex_unlock(&master->mlock); } exit: mutex_unlock(&board_lock); if (!found) return NULL; return swr; } EXPORT_SYMBOL(get_matching_swr_slave_device); Loading Loading @@ -888,7 +894,6 @@ int swr_register_master(struct swr_master *master) id = idr_alloc(&master_idr, master, master->bus_num, master->bus_num + 1, GFP_KERNEL); mutex_unlock(&swr_lock); if (id < 0) return id; Loading
soc/swr-mstr-ctrl.c +82 −25 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ enum { #define TRUE 1 #define FALSE 0 #define SWRM_MAX_PORT_REG 40 #define SWRM_MAX_INIT_REG 8 #define SWRM_MAX_PORT_REG 120 #define SWRM_MAX_INIT_REG 10 #define SWR_MSTR_MAX_REG_ADDR 0x1740 #define SWR_MSTR_START_REG_ADDR 0x00 Loading Loading @@ -304,11 +304,13 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, if (swrm->bulk_write) swrm->bulk_write(swrm->handle, reg_addr, val, length); else { mutex_lock(&swrm->iolock); for (i = 0; i < length; i++) { /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(100, 105); swr_master_write(swrm, reg_addr[i], val[i]); } mutex_unlock(&swrm->iolock); } return 0; } Loading Loading @@ -403,6 +405,7 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u32 val; u32 retry_attempt = 0; mutex_lock(&swrm->iolock); val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); Loading @@ -411,9 +414,9 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, usleep_range(250, 255); retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, dev_addr, *cmd_data); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->rcmd_id, dev_addr, *cmd_data); if ((((*cmd_data) & 0xF00) >> 8) != swrm->rcmd_id) { if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) { /* wait 500 us before retry on fifo read failure */ Loading @@ -421,10 +424,17 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, retry_attempt++; goto retry_read; } else { dev_err_ratelimited(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, \ rcmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->rcmd_id, dev_addr, *cmd_data); dev_err_ratelimited(swrm->dev, "%s: failed to read fifo\n", __func__); } } mutex_unlock(&swrm->iolock); return 0; } Loading @@ -434,15 +444,16 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, u32 val; int ret = 0; mutex_lock(&swrm->iolock); if (!cmd_id) val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data, dev_addr, reg_addr); else val = swrm_get_packed_reg_val(&cmd_id, cmd_data, dev_addr, reg_addr); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, val:0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, val, dev_addr, cmd_data); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(250, 255); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); Loading @@ -457,6 +468,7 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, wait_for_completion_timeout(&swrm->broadcast, (2 * HZ/10)); } mutex_unlock(&swrm->iolock); return ret; } Loading @@ -472,7 +484,7 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len); Loading @@ -482,8 +494,8 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, if (!ret) *reg_val = (u8)val; pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } Loading @@ -499,12 +511,14 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, return -EINVAL; } pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); else swr_master_write(swrm, reg_addr, reg_val); pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } Loading @@ -524,6 +538,7 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, if (len <= 0) return -EINVAL; pm_runtime_get_sync(swrm->dev); if (dev_num) { swr_fifo_reg = kcalloc(len, sizeof(u32), GFP_KERNEL); if (!swr_fifo_reg) { Loading Loading @@ -560,6 +575,7 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, mem_fail: kfree(swr_fifo_reg); err: pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } Loading Loading @@ -1022,6 +1038,26 @@ static int swrm_disconnect_port(struct swr_master *master, return 0; } static int swrm_find_alert_slave(struct swr_mstr_ctrl *swrm, int status, u8 *devnum) { int i; bool found = false; for (i = 0; i < (swrm->master.num_dev + 1); i++) { if ((status & SWRM_MCP_SLV_STATUS_MASK) == SWR_ALERT) { *devnum = i; found = true; break; } status >>= 2; } if (found) return 0; else return -EINVAL; } static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, int status, u8 *devnum) { Loading Loading @@ -1049,7 +1085,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) { struct swr_mstr_ctrl *swrm = dev; u32 value, intr_sts; int status, chg_sts, i; u32 temp = 0; u32 status, chg_sts, i; u8 devnum = 0; int ret = IRQ_HANDLED; struct swr_device *swr_dev; Loading @@ -1067,13 +1104,16 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) if (!value) continue; swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, value); switch (value) { case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ: dev_dbg(swrm->dev, "Trigger irq to slave device\n"); status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); swrm_check_slave_change_status(swrm, status, &devnum); ret = swrm_find_alert_slave(swrm, status, &devnum); if (ret) { dev_err(swrm->dev, "no slave alert found.\ spurious interrupt\n"); return ret; } list_for_each_entry(swr_dev, &mstr->devices, dev_list) { if (swr_dev->dev_num != devnum) continue; Loading @@ -1082,6 +1122,12 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) irq_find_mapping( swr_dev->slave_irq, 0)); } swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1, 1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x0, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); break; case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: dev_dbg(swrm->dev, "SWR new slave attached\n"); Loading Loading @@ -1160,7 +1206,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) break; } } swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts); swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); mutex_unlock(&swrm->reslock); Loading Loading @@ -1196,13 +1243,13 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, num_dev = swrm->num_dev; else num_dev = mstr->num_dev; pm_runtime_get_sync(swrm->dev); for (i = 1; i < (num_dev + 1); i++) { id = ((u64)(swr_master_read(swrm, SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); id |= swr_master_read(swrm, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i)); /* * As pm_runtime_get_sync() brings all slaves out of reset * update logical device number for all slaves. Loading @@ -1220,6 +1267,11 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n", __func__, i, swr_dev->addr); swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0xF, SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0xF, SWRS_SCP_INT_STATUS_MASK_1); } } } Loading Loading @@ -1256,10 +1308,6 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_ENUMERATOR_CFG_ADDR; value[len++] = 1; /* Mask soundwire interrupts */ reg[len] = SWRM_INTERRUPT_MASK_ADDR; value[len++] = 0x1FFFD; /* Configure No pings */ val = swr_master_read(swrm, SWRM_MCP_CFG_ADDR); val &= ~SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK; Loading @@ -1272,15 +1320,22 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_CMD_FIFO_CFG_ADDR; value[len++] = val; /* Set IRQ to PULSE */ reg[len] = SWRM_COMP_CFG_ADDR; value[len++] = 0x02; reg[len] = SWRM_MCP_BUS_CTRL_ADDR; value[len++] = 0x2; /* Set IRQ to PULSE */ reg[len] = SWRM_COMP_CFG_ADDR; value[len++] = 0x03; reg[len] = SWRM_INTERRUPT_CLEAR; value[len++] = 0x08; value[len++] = 0xFFFFFFFF; /* Mask soundwire interrupts */ reg[len] = SWRM_INTERRUPT_MASK_ADDR; value[len++] = 0x1FFFD; reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; value[len++] = 0x1; swr_master_bulk_write(swrm, reg, value, len); Loading Loading @@ -1430,6 +1485,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->mlock); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); mutex_init(&swrm->iolock); for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); Loading Loading @@ -1535,6 +1591,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->iolock); err_pdata_fail: err_memory_fail: return ret; Loading
soc/swr-mstr-ctrl.h +1 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ struct swr_mstr_ctrl { int clk_ref_count; struct completion reset; struct completion broadcast; struct mutex iolock; struct mutex mlock; struct mutex reslock; u32 swrm_base_reg; Loading
soc/swrm_registers.h +9 −3 Original line number Diff line number Diff line Loading @@ -114,6 +114,8 @@ #define SWRM_INTERRUPT_CLEAR (SWRM_BASE_ADDRESS+0x00000208) #define SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN (SWRM_BASE_ADDRESS+0x00000210) #define SWRM_CMD_FIFO_WR_CMD (SWRM_BASE_ADDRESS + 0x00000300) #define SWRM_CMD_FIFO_WR_CMD_MASK 0xFFFFFFFF #define SWRM_CMD_FIFO_RD_CMD (SWRM_BASE_ADDRESS + 0x00000304) Loading Loading @@ -185,7 +187,8 @@ 0x40*m) #define SWRM_DP_BLOCK_CTRL_1(n) (SWRM_BASE_ADDRESS + \ 0x0000112C + 0x100*n) 0x0000112C + \ 0x100*(n-1)) #define SWRM_DP_BLOCK_CTRL2_BANK(n, m) (SWRM_BASE_ADDRESS + \ 0x00001130 + \ Loading @@ -204,7 +207,7 @@ #define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (SWRM_BASE_ADDRESS + \ 0x00001054 + 0x100*n) 0x00001054 + 0x100*(n-1)) #define SWRM_MAX_REGISTER SWRM_DIN_DPn_PCM_PORT_CTRL(7) Loading @@ -214,8 +217,11 @@ #define SWRS_DP_REG_OFFSET(port, bank) ((0x100*port)+(0x10*bank)) #define SWRS_SCP_INT_STATUS_CLEAR_1 0x40 #define SWRS_SCP_INT_STATUS_MASK_1 0x41 #define SWRS_SCP_CONTROL 0x44 #define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x120 + \ #define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x103 + \ 0x100 * n) #define SWRS_DP_CHANNEL_ENABLE_BANK(n, m) (SWRS_BASE_ADDRESS + 0x120 + \ Loading