Commit e59a698b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'i3c/for-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux

Pull i3c updates from Alexandre Belloni:
 "Core:
   - Fix SETDASA when static and dynamic adress are equal
   - Fix cmd_v1 DAA exit criteria

  Drivers:
   - svc: allow probing without any device"

* tag 'i3c/for-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
  i3c: master: svc: fix probe failure when no i3c device exist
  i3c: master: Fix SETDASA process
  dt-bindings: i3c: Fix description for assigned-address
  i3c: master: svc: Describe member 'saved_regs'
  i3c: master: svc: Do not check for 0 return after calling platform_get_irq()
  i3c/master: cmd_v1: Fix the exit criteria for the daa procedure
  i3c: Explicitly include correct DT includes
parents d9b9ea58 6e13d652
......@@ -135,9 +135,10 @@ patternProperties:
minimum: 0x1
maximum: 0xff
description: |
Dynamic address to be assigned to this device. This property is only
valid if the I3C device has a static address (first cell of the reg
property != 0).
Dynamic address to be assigned to this device. In case static address is
present (first cell of the reg property != 0), this address is assigned
through SETDASA. If static address is not present, this address is assigned
through SETNEWDA after assigning a temporary address via ENTDAA.
required:
- reg
......@@ -163,12 +164,18 @@ examples:
pagesize = <0x8>;
};
/* I3C device with a static I2C address. */
/* I3C device with a static I2C address and assigned address. */
thermal_sensor: sensor@68,39200144004 {
reg = <0x68 0x392 0x144004>;
assigned-address = <0xa>;
};
/* I3C device with only assigned address. */
pressure_sensor: sensor@0,39200124004 {
reg = <0x0 0x392 0x124000>;
assigned-address = <0xc>;
};
/*
* I3C device without a static I2C address but requiring
* resources described in the DT.
......
......@@ -1308,7 +1308,11 @@ static int i3c_master_get_i3c_addrs(struct i3c_dev_desc *dev)
if (dev->info.static_addr) {
status = i3c_bus_get_addr_slot_status(&master->bus,
dev->info.static_addr);
if (status != I3C_ADDR_SLOT_FREE)
/* Since static address and assigned dynamic address can be
* equal, allow this case to pass.
*/
if (status != I3C_ADDR_SLOT_FREE &&
dev->info.static_addr != dev->boardinfo->init_dyn_addr)
return -EBUSY;
i3c_bus_set_addr_slot_status(&master->bus,
......
......@@ -8,7 +8,6 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
......
......@@ -22,7 +22,6 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/of_device.h>
#define DEV_ID 0x0
#define DEV_ID_I3C_MASTER 0x5034
......
......@@ -339,7 +339,7 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci)
break;
}
if (RESP_STATUS(xfer[0].response) == RESP_ERR_NACK &&
RESP_STATUS(xfer[0].response) == 1) {
RESP_DATA_LENGTH(xfer->response) == 1) {
ret = 0; /* no more devices to be assigned */
break;
}
......
......@@ -156,6 +156,7 @@ struct svc_i3c_regs_save {
* @base: I3C master controller
* @dev: Corresponding device
* @regs: Memory mapping
* @saved_regs: Volatile values for PM operations
* @free_slots: Bit array of available slots
* @addrs: Array containing the dynamic addresses of each attached device
* @descs: Array of descriptors, one per attached device
......@@ -789,6 +790,10 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
*/
break;
} else if (SVC_I3C_MSTATUS_NACKED(reg)) {
/* No I3C devices attached */
if (dev_nb == 0)
break;
/*
* A slave device nacked the address, this is
* allowed only once, DAA will be stopped and
......@@ -1263,11 +1268,17 @@ static int svc_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
{
struct svc_i3c_master *master = to_svc_i3c_master(m);
bool broadcast = cmd->id < 0x80;
int ret;
if (broadcast)
return svc_i3c_master_send_bdcast_ccc_cmd(master, cmd);
ret = svc_i3c_master_send_bdcast_ccc_cmd(master, cmd);
else
return svc_i3c_master_send_direct_ccc_cmd(master, cmd);
ret = svc_i3c_master_send_direct_ccc_cmd(master, cmd);
if (ret)
cmd->err = I3C_ERROR_M2;
return ret;
}
static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev,
......@@ -1518,8 +1529,8 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
return PTR_ERR(master->sclk);
master->irq = platform_get_irq(pdev, 0);
if (master->irq <= 0)
return -ENOENT;
if (master->irq < 0)
return master->irq;
master->dev = dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment