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: ...@@ -135,9 +135,10 @@ patternProperties:
minimum: 0x1 minimum: 0x1
maximum: 0xff maximum: 0xff
description: | description: |
Dynamic address to be assigned to this device. This property is only Dynamic address to be assigned to this device. In case static address is
valid if the I3C device has a static address (first cell of the reg present (first cell of the reg property != 0), this address is assigned
property != 0). through SETDASA. If static address is not present, this address is assigned
through SETNEWDA after assigning a temporary address via ENTDAA.
required: required:
- reg - reg
...@@ -163,12 +164,18 @@ examples: ...@@ -163,12 +164,18 @@ examples:
pagesize = <0x8>; pagesize = <0x8>;
}; };
/* I3C device with a static I2C address. */ /* I3C device with a static I2C address and assigned address. */
thermal_sensor: sensor@68,39200144004 { thermal_sensor: sensor@68,39200144004 {
reg = <0x68 0x392 0x144004>; reg = <0x68 0x392 0x144004>;
assigned-address = <0xa>; 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 * I3C device without a static I2C address but requiring
* resources described in the DT. * resources described in the DT.
......
...@@ -1308,7 +1308,11 @@ static int i3c_master_get_i3c_addrs(struct i3c_dev_desc *dev) ...@@ -1308,7 +1308,11 @@ static int i3c_master_get_i3c_addrs(struct i3c_dev_desc *dev)
if (dev->info.static_addr) { if (dev->info.static_addr) {
status = i3c_bus_get_addr_slot_status(&master->bus, status = i3c_bus_get_addr_slot_status(&master->bus,
dev->info.static_addr); 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; return -EBUSY;
i3c_bus_set_addr_slot_status(&master->bus, i3c_bus_set_addr_slot_status(&master->bus,
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/of_device.h>
#define DEV_ID 0x0 #define DEV_ID 0x0
#define DEV_ID_I3C_MASTER 0x5034 #define DEV_ID_I3C_MASTER 0x5034
......
...@@ -339,7 +339,7 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci) ...@@ -339,7 +339,7 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci)
break; break;
} }
if (RESP_STATUS(xfer[0].response) == RESP_ERR_NACK && 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 */ ret = 0; /* no more devices to be assigned */
break; break;
} }
......
...@@ -156,6 +156,7 @@ struct svc_i3c_regs_save { ...@@ -156,6 +156,7 @@ struct svc_i3c_regs_save {
* @base: I3C master controller * @base: I3C master controller
* @dev: Corresponding device * @dev: Corresponding device
* @regs: Memory mapping * @regs: Memory mapping
* @saved_regs: Volatile values for PM operations
* @free_slots: Bit array of available slots * @free_slots: Bit array of available slots
* @addrs: Array containing the dynamic addresses of each attached device * @addrs: Array containing the dynamic addresses of each attached device
* @descs: Array of descriptors, one per 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, ...@@ -789,6 +790,10 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
*/ */
break; break;
} else if (SVC_I3C_MSTATUS_NACKED(reg)) { } else if (SVC_I3C_MSTATUS_NACKED(reg)) {
/* No I3C devices attached */
if (dev_nb == 0)
break;
/* /*
* A slave device nacked the address, this is * A slave device nacked the address, this is
* allowed only once, DAA will be stopped and * 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, ...@@ -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); struct svc_i3c_master *master = to_svc_i3c_master(m);
bool broadcast = cmd->id < 0x80; bool broadcast = cmd->id < 0x80;
int ret;
if (broadcast) if (broadcast)
return svc_i3c_master_send_bdcast_ccc_cmd(master, cmd); ret = svc_i3c_master_send_bdcast_ccc_cmd(master, cmd);
else 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, 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) ...@@ -1518,8 +1529,8 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
return PTR_ERR(master->sclk); return PTR_ERR(master->sclk);
master->irq = platform_get_irq(pdev, 0); master->irq = platform_get_irq(pdev, 0);
if (master->irq <= 0) if (master->irq < 0)
return -ENOENT; return master->irq;
master->dev = dev; 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