[PATCH v4 29/37] regulator: scmi: port driver to the new scmi_voltage_proto_ops interface

2021-01-06 Thread Cristian Marussi
Port driver to the new SCMI Voltage interface based on protocol handles
and common devm_get_ops().

Signed-off-by: Cristian Marussi 
---
 drivers/regulator/scmi-regulator.c | 39 --
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/regulator/scmi-regulator.c 
b/drivers/regulator/scmi-regulator.c
index 0e8b3caa8146..4689937ebbfa 100644
--- a/drivers/regulator/scmi-regulator.c
+++ b/drivers/regulator/scmi-regulator.c
@@ -33,9 +33,12 @@
 #include 
 #include 
 
+static const struct scmi_voltage_proto_ops *voltage_ops;
+
 struct scmi_regulator {
u32 id;
struct scmi_device *sdev;
+   struct scmi_protocol_handle *ph;
struct regulator_dev *rdev;
struct device_node *of_node;
struct regulator_desc desc;
@@ -50,19 +53,17 @@ struct scmi_regulator_info {
 static int scmi_reg_enable(struct regulator_dev *rdev)
 {
struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
-   const struct scmi_handle *handle = sreg->sdev->handle;
 
-   return handle->voltage_ops->config_set(handle, sreg->id,
-  SCMI_VOLTAGE_ARCH_STATE_ON);
+   return voltage_ops->config_set(sreg->ph, sreg->id,
+  SCMI_VOLTAGE_ARCH_STATE_ON);
 }
 
 static int scmi_reg_disable(struct regulator_dev *rdev)
 {
struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
-   const struct scmi_handle *handle = sreg->sdev->handle;
 
-   return handle->voltage_ops->config_set(handle, sreg->id,
-  SCMI_VOLTAGE_ARCH_STATE_OFF);
+   return voltage_ops->config_set(sreg->ph, sreg->id,
+  SCMI_VOLTAGE_ARCH_STATE_OFF);
 }
 
 static int scmi_reg_is_enabled(struct regulator_dev *rdev)
@@ -70,10 +71,8 @@ static int scmi_reg_is_enabled(struct regulator_dev *rdev)
int ret;
u32 config;
struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
-   const struct scmi_handle *handle = sreg->sdev->handle;
 
-   ret = handle->voltage_ops->config_get(handle, sreg->id,
- );
+   ret = voltage_ops->config_get(sreg->ph, sreg->id, );
if (ret) {
dev_err(>sdev->dev,
"Error %d reading regulator %s status.\n",
@@ -89,9 +88,8 @@ static int scmi_reg_get_voltage_sel(struct regulator_dev 
*rdev)
int ret;
s32 volt_uV;
struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
-   const struct scmi_handle *handle = sreg->sdev->handle;
 
-   ret = handle->voltage_ops->level_get(handle, sreg->id, _uV);
+   ret = voltage_ops->level_get(sreg->ph, sreg->id, _uV);
if (ret)
return ret;
 
@@ -103,13 +101,12 @@ static int scmi_reg_set_voltage_sel(struct regulator_dev 
*rdev,
 {
s32 volt_uV;
struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
-   const struct scmi_handle *handle = sreg->sdev->handle;
 
volt_uV = sreg->desc.ops->list_voltage(rdev, selector);
if (volt_uV <= 0)
return -EINVAL;
 
-   return handle->voltage_ops->level_set(handle, sreg->id, 0x0, volt_uV);
+   return voltage_ops->level_set(sreg->ph, sreg->id, 0x0, volt_uV);
 }
 
 static const struct regulator_ops scmi_reg_fixed_ops = {
@@ -204,11 +201,10 @@ scmi_config_discrete_regulator_mappings(struct 
scmi_regulator *sreg,
 static int scmi_regulator_common_init(struct scmi_regulator *sreg)
 {
int ret;
-   const struct scmi_handle *handle = sreg->sdev->handle;
struct device *dev = >sdev->dev;
const struct scmi_voltage_info *vinfo;
 
-   vinfo = handle->voltage_ops->info_get(handle, sreg->id);
+   vinfo = voltage_ops->info_get(sreg->ph, sreg->id);
if (!vinfo) {
dev_warn(dev, "Failure to get voltage domain %d\n",
 sreg->id);
@@ -257,6 +253,7 @@ static int scmi_regulator_common_init(struct scmi_regulator 
*sreg)
 }
 
 static int process_scmi_regulator_of_node(struct scmi_device *sdev,
+ struct scmi_protocol_handle *ph,
  struct device_node *np,
  struct scmi_regulator_info *rinfo)
 {
@@ -284,6 +281,7 @@ static int process_scmi_regulator_of_node(struct 
scmi_device *sdev,
 
rinfo->sregv[dom]->id = dom;
rinfo->sregv[dom]->sdev = sdev;
+   rinfo->sregv[dom]->ph = ph;
 
/* get hold of good nodes */
of_node_get(np);
@@ -302,11 +300,16 @@ static int scmi_regulator_probe(struct scmi_device *sdev)
struct device_node *np, *child;
const struct scmi_handle *handle = sdev->handle;
struct scmi_regulator_info *rinfo;
+   struct scmi_protocol_handle *ph;
 
-   if (!handle || !handle->voltage_ops)
+   if (!handle)
return -ENODEV;
 
-   num_doms = 

[PATCH v2 4/5] ibmvfc: complete commands outside the host/queue lock

2021-01-06 Thread Tyrel Datwyler
Drain the command queue and place all commands on a completion list.
Perform command completion on that list outside the host/queue locks.
Further, move purged command compeletions outside the host_lock as well.

Signed-off-by: Tyrel Datwyler 
Reviewed-by: Brian King 
---
 drivers/scsi/ibmvscsi/ibmvfc.c | 58 ++
 drivers/scsi/ibmvscsi/ibmvfc.h |  3 +-
 2 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 69a6401ca504..f680f96d5d06 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -894,7 +894,7 @@ static void ibmvfc_scsi_eh_done(struct ibmvfc_event *evt)
  * @purge_list:list head of failed commands
  *
  * This function runs completions on commands to fail as a result of a
- * host reset or platform migration. Caller must hold host_lock.
+ * host reset or platform migration.
  **/
 static void ibmvfc_complete_purge(struct list_head *purge_list)
 {
@@ -1407,6 +1407,23 @@ static struct ibmvfc_event *ibmvfc_get_event(struct 
ibmvfc_queue *queue)
return evt;
 }
 
+/**
+ * ibmvfc_locked_done - Calls evt completion with host_lock held
+ * @evt:   ibmvfc evt to complete
+ *
+ * All non-scsi command completion callbacks have the expectation that the
+ * host_lock is held. This callback is used by ibmvfc_init_event to wrap a
+ * MAD evt with the host_lock.
+ **/
+static void ibmvfc_locked_done(struct ibmvfc_event *evt)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(evt->vhost->host->host_lock, flags);
+   evt->_done(evt);
+   spin_unlock_irqrestore(evt->vhost->host->host_lock, flags);
+}
+
 /**
  * ibmvfc_init_event - Initialize fields in an event struct that are always
  * required.
@@ -1419,9 +1436,14 @@ static void ibmvfc_init_event(struct ibmvfc_event *evt,
 {
evt->cmnd = NULL;
evt->sync_iu = NULL;
-   evt->crq.format = format;
-   evt->done = done;
evt->eh_comp = NULL;
+   evt->crq.format = format;
+   if (format == IBMVFC_CMD_FORMAT)
+   evt->done = done;
+   else {
+   evt->_done = done;
+   evt->done = ibmvfc_locked_done;
+   }
 }
 
 /**
@@ -1640,7 +1662,9 @@ static void ibmvfc_relogin(struct scsi_device *sdev)
struct ibmvfc_host *vhost = shost_priv(sdev->host);
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
struct ibmvfc_target *tgt;
+   unsigned long flags;
 
+   spin_lock_irqsave(vhost->host->host_lock, flags);
list_for_each_entry(tgt, >targets, queue) {
if (rport == tgt->rport) {
ibmvfc_del_tgt(tgt);
@@ -1649,6 +1673,7 @@ static void ibmvfc_relogin(struct scsi_device *sdev)
}
 
ibmvfc_reinit_host(vhost);
+   spin_unlock_irqrestore(vhost->host->host_lock, flags);
 }
 
 /**
@@ -2901,7 +2926,8 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq 
*crq,
  * @vhost: ibmvfc host struct
  *
  **/
-static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host 
*vhost)
+static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host 
*vhost,
+ struct list_head *evt_doneq)
 {
long rc;
struct ibmvfc_event *evt = (struct ibmvfc_event 
*)be64_to_cpu(crq->ioba);
@@ -2972,12 +2998,9 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, 
struct ibmvfc_host *vhost)
return;
}
 
-   del_timer(>timer);
spin_lock(>queue->l_lock);
-   list_del(>queue_list);
+   list_move_tail(>queue_list, evt_doneq);
spin_unlock(>queue->l_lock);
-   ibmvfc_trc_end(evt);
-   evt->done(evt);
 }
 
 /**
@@ -3364,8 +3387,10 @@ static void ibmvfc_tasklet(void *data)
struct vio_dev *vdev = to_vio_dev(vhost->dev);
struct ibmvfc_crq *crq;
struct ibmvfc_async_crq *async;
+   struct ibmvfc_event *evt, *temp;
unsigned long flags;
int done = 0;
+   LIST_HEAD(evt_doneq);
 
spin_lock_irqsave(vhost->host->host_lock, flags);
spin_lock(vhost->crq.q_lock);
@@ -3379,7 +3404,7 @@ static void ibmvfc_tasklet(void *data)
 
/* Pull all the valid messages off the CRQ */
while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
-   ibmvfc_handle_crq(crq, vhost);
+   ibmvfc_handle_crq(crq, vhost, _doneq);
crq->valid = 0;
wmb();
}
@@ -3392,7 +3417,7 @@ static void ibmvfc_tasklet(void *data)
wmb();
} else if ((crq = ibmvfc_next_crq(vhost)) != NULL) {
vio_disable_interrupts(vdev);
-   ibmvfc_handle_crq(crq, vhost);
+   ibmvfc_handle_crq(crq, vhost, _doneq);
crq->valid = 0;
wmb();
   

[PATCH v2 5/5] ibmvfc: relax locking around ibmvfc_queuecommand

2021-01-06 Thread Tyrel Datwyler
The drivers queuecommand routine is still wrapped to hold the host lock
for the duration of the call. This will become problematic when moving
to multiple queues due to the lock contention preventing asynchronous
submissions to mulitple queues. There is no real legatimate reason to
hold the host lock, and previous patches have insured proper protection
of moving ibmvfc_event objects between free and sent lists.

Signed-off-by: Tyrel Datwyler 
Reviewed-by: Brian King 
---
 drivers/scsi/ibmvscsi/ibmvfc.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index f680f96d5d06..ff86c43b4b33 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1793,10 +1793,9 @@ static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct 
ibmvfc_event *evt, struct s
  * Returns:
  * 0 on success / other on failure
  **/
-static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
-  void (*done) (struct scsi_cmnd *))
+static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
 {
-   struct ibmvfc_host *vhost = shost_priv(cmnd->device->host);
+   struct ibmvfc_host *vhost = shost_priv(shost);
struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
struct ibmvfc_cmd *vfc_cmd;
struct ibmvfc_fcp_cmd_iu *iu;
@@ -1806,7 +1805,7 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
if (unlikely((rc = fc_remote_port_chkready(rport))) ||
unlikely((rc = ibmvfc_host_chkready(vhost {
cmnd->result = rc;
-   done(cmnd);
+   cmnd->scsi_done(cmnd);
return 0;
}
 
@@ -1814,7 +1813,6 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
evt = ibmvfc_get_event(>crq);
ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT);
evt->cmnd = cmnd;
-   cmnd->scsi_done = done;
 
vfc_cmd = ibmvfc_init_vfc_cmd(evt, cmnd->device);
iu = ibmvfc_get_fcp_iu(vhost, vfc_cmd);
@@ -1841,12 +1839,10 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd 
*cmnd,
"Failed to map DMA buffer for command. rc=%d\n", 
rc);
 
cmnd->result = DID_ERROR << 16;
-   done(cmnd);
+   cmnd->scsi_done(cmnd);
return 0;
 }
 
-static DEF_SCSI_QCMD(ibmvfc_queuecommand)
-
 /**
  * ibmvfc_sync_completion - Signal that a synchronous command has completed
  * @evt:   ibmvfc event struct
-- 
2.27.0



[PATCH v2 0/5] ibmvfc: MQ preparatory locking work

2021-01-06 Thread Tyrel Datwyler
The ibmvfc driver in its current form relies heavily on the host_lock. This
patchset introduces a genric queue with its own queue lock and sent/free event
list locks. This generic queue allows the driver to decouple the primary queue
and future subordinate queues from the host lock reducing lock contention while
also relaxing locking for submissions and completions to simply the list lock of
the queue in question.

changes in v2:
* Patch 4: Made ibmvfc_locked_done() static fixing a no-prototype warning

Tyrel Datwyler (5):
  ibmvfc: define generic queue structure for CRQs
  ibmvfc: make command event pool queue specific
  ibmvfc: define per-queue state/list locks
  ibmvfc: complete commands outside the host/queue lock
  ibmvfc: relax locking around ibmvfc_queuecommand

 drivers/scsi/ibmvscsi/ibmvfc.c | 379 ++---
 drivers/scsi/ibmvscsi/ibmvfc.h |  54 +++--
 2 files changed, 286 insertions(+), 147 deletions(-)

-- 
2.27.0



Re: [PATCH] mm/mmap: replace if (cond) BUG() with BUG_ON()

2021-01-06 Thread Hugh Dickins
On Wed, 6 Jan 2021, Andrea Arcangeli wrote:
> 
> I'd be surprised if the kernel can boot with BUG_ON() defined as "do
> {}while(0)" so I guess it doesn't make any difference.

I had been afraid of that too, when CONFIG_BUG is not set:
but I think it's actually "if (cond) do {} while (0)".


[PATCH v4 31/37] firmware: arm_scmi: make references to handle const

2021-01-06 Thread Cristian Marussi
Now that all the protocol private variable data have been moved out of
struct scmi_handle, mark all of its references as const.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/common.h |  4 ++--
 drivers/firmware/arm_scmi/driver.c | 12 ++--
 include/linux/scmi_protocol.h  |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h 
b/drivers/firmware/arm_scmi/common.h
index c7b48f1e5fe0..45387a32d79e 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -274,8 +274,8 @@ void __exit scmi_##name##_unregister(void) \
 
 const struct scmi_protocol *scmi_get_protocol(int protocol_id);
 
-int scmi_acquire_protocol(struct scmi_handle *handle, u8 protocol_id);
-void scmi_release_protocol(struct scmi_handle *handle, u8 protocol_id);
+int scmi_acquire_protocol(const struct scmi_handle *handle, u8 protocol_id);
+void scmi_release_protocol(const struct scmi_handle *handle, u8 protocol_id);
 
 /* SCMI Transport */
 /**
diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index b76c06b8bbc3..68a40d83325c 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -729,7 +729,7 @@ scmi_get_revision_area(const struct scmi_protocol_handle 
*ph)
  * Return: A reference to an initialized protocol instance or error on failure.
  */
 static struct scmi_protocol_instance * __must_check
-scmi_get_protocol_instance(struct scmi_handle *handle, u8 protocol_id)
+scmi_get_protocol_instance(const struct scmi_handle *handle, u8 protocol_id)
 {
int ret = -ENOMEM;
void *gid;
@@ -808,7 +808,7 @@ scmi_get_protocol_instance(struct scmi_handle *handle, u8 
protocol_id)
  *
  * Return: 0 if protocol was acquired successfully.
  */
-int scmi_acquire_protocol(struct scmi_handle *handle, u8 protocol_id)
+int scmi_acquire_protocol(const struct scmi_handle *handle, u8 protocol_id)
 {
return PTR_ERR_OR_ZERO(scmi_get_protocol_instance(handle, protocol_id));
 }
@@ -821,7 +821,7 @@ int scmi_acquire_protocol(struct scmi_handle *handle, u8 
protocol_id)
  * Remove one user for the specified protocol and triggers de-initialization
  * and resources de-allocation once the last user has gone.
  */
-void scmi_release_protocol(struct scmi_handle *handle, u8 protocol_id)
+void scmi_release_protocol(const struct scmi_handle *handle, u8 protocol_id)
 {
struct scmi_info *info = handle_to_scmi_info(handle);
struct scmi_protocol_instance *pi;
@@ -866,7 +866,7 @@ void scmi_release_protocol(struct scmi_handle *handle, u8 
protocol_id)
  *Must be checked for errors by caller.
  */
 static const void __must_check *
-scmi_get_protocol_operations(struct scmi_handle *handle, u8 protocol_id,
+scmi_get_protocol_operations(const struct scmi_handle *handle, u8 protocol_id,
 struct scmi_protocol_handle **ph)
 {
struct scmi_protocol_instance *pi;
@@ -908,7 +908,7 @@ scmi_is_protocol_implemented(const struct scmi_handle 
*handle, u8 prot_id)
 }
 
 struct scmi_protocol_devres {
-   struct scmi_handle *handle;
+   const struct scmi_handle *handle;
u8 protocol_id;
 };
 
@@ -943,7 +943,7 @@ scmi_devm_get_protocol_ops(struct scmi_device *sdev, u8 
protocol_id,
 {
struct scmi_protocol_instance *pi;
struct scmi_protocol_devres *dres;
-   struct scmi_handle *handle = sdev->handle;
+   const struct scmi_handle *handle = sdev->handle;
 
if (!ph)
return ERR_PTR(-EINVAL);
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index c16455cff6a9..6c05e8acafac 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -622,9 +622,9 @@ struct scmi_handle {
void (*devm_put_ops)(struct scmi_device *sdev, u8 proto);
 
const void __must_check *
-   (*get_ops)(struct scmi_handle *handle, u8 proto,
+   (*get_ops)(const struct scmi_handle *handle, u8 proto,
   struct scmi_protocol_handle **ph);
-   void (*put_ops)(struct scmi_handle *handle, u8 proto);
+   void (*put_ops)(const struct scmi_handle *handle, u8 proto);
 
const struct scmi_notify_ops *notify_ops;
void *notify_priv;
-- 
2.17.1



[PATCH v4 34/37] firmware: arm_scmi: cleanup events registration transient code

2021-01-06 Thread Cristian Marussi
Remove all the events registration code used to ease the transition to the
new interface based on protocol handles..

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/base.c|  4 ++--
 drivers/firmware/arm_scmi/notify.h  |  6 +++---
 drivers/firmware/arm_scmi/perf.c|  9 -
 drivers/firmware/arm_scmi/power.c   | 16 
 drivers/firmware/arm_scmi/reset.c   | 16 
 drivers/firmware/arm_scmi/sensors.c | 19 +--
 drivers/firmware/arm_scmi/system.c  | 11 ++-
 7 files changed, 40 insertions(+), 41 deletions(-)

diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index c9e5e451b377..f2d10c5a55ae 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -264,7 +264,7 @@ static int scmi_base_error_notify(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int scmi_base_set_notify_enabled(const void *ph,
+static int scmi_base_set_notify_enabled(const struct scmi_protocol_handle *ph,
u8 evt_id, u32 src_id, bool enable)
 {
int ret;
@@ -276,7 +276,7 @@ static int scmi_base_set_notify_enabled(const void *ph,
return ret;
 }
 
-static void *scmi_base_fill_custom_report(const void *ph,
+static void *scmi_base_fill_custom_report(const struct scmi_protocol_handle 
*ph,
  u8 evt_id, ktime_t timestamp,
  const void *payld, size_t payld_sz,
  void *report, u32 *src_id)
diff --git a/drivers/firmware/arm_scmi/notify.h 
b/drivers/firmware/arm_scmi/notify.h
index 2281a740ae96..3915bcd76242 100644
--- a/drivers/firmware/arm_scmi/notify.h
+++ b/drivers/firmware/arm_scmi/notify.h
@@ -50,10 +50,10 @@ struct scmi_protocol_handle;
  * process context.
  */
 struct scmi_event_ops {
-   int (*get_num_sources)(const void *handle);
-   int (*set_notify_enabled)(const void *handle,
+   int (*get_num_sources)(const struct scmi_protocol_handle *ph);
+   int (*set_notify_enabled)(const struct scmi_protocol_handle *ph,
  u8 evt_id, u32 src_id, bool enabled);
-   void *(*fill_custom_report)(const void *handle,
+   void *(*fill_custom_report)(const struct scmi_protocol_handle *ph,
u8 evt_id, ktime_t timestamp,
const void *payld, size_t payld_sz,
void *report, u32 *src_id);
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index b2e1bdad2b3a..c87a390463d9 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -769,7 +769,7 @@ static const struct scmi_perf_proto_ops perf_proto_ops = {
.power_scale_mw_get = scmi_power_scale_mw_get,
 };
 
-static int scmi_perf_set_notify_enabled(const void *ph,
+static int scmi_perf_set_notify_enabled(const struct scmi_protocol_handle *ph,
u8 evt_id, u32 src_id, bool enable)
 {
int ret, cmd_id;
@@ -786,7 +786,7 @@ static int scmi_perf_set_notify_enabled(const void *ph,
return ret;
 }
 
-static void *scmi_perf_fill_custom_report(const void *ph,
+static void *scmi_perf_fill_custom_report(const struct scmi_protocol_handle 
*ph,
  u8 evt_id, ktime_t timestamp,
  const void *payld, size_t payld_sz,
  void *report, u32 *src_id)
@@ -834,10 +834,9 @@ static void *scmi_perf_fill_custom_report(const void *ph,
return rep;
 }
 
-static int scmi_perf_get_num_sources(const void *ph)
+static int scmi_perf_get_num_sources(const struct scmi_protocol_handle *ph)
 {
-   struct scmi_perf_info *pi =
-   ((const struct scmi_protocol_handle *)ph)->get_priv(ph);
+   struct scmi_perf_info *pi = ph->get_priv(ph);
 
if (!pi)
return -EINVAL;
diff --git a/drivers/firmware/arm_scmi/power.c 
b/drivers/firmware/arm_scmi/power.c
index 06e3ab17a0eb..3e453d9bcbc8 100644
--- a/drivers/firmware/arm_scmi/power.c
+++ b/drivers/firmware/arm_scmi/power.c
@@ -211,7 +211,7 @@ static int scmi_power_request_notify(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int scmi_power_set_notify_enabled(const void *ph,
+static int scmi_power_set_notify_enabled(const struct scmi_protocol_handle *ph,
 u8 evt_id, u32 src_id, bool enable)
 {
int ret;
@@ -224,10 +224,11 @@ static int scmi_power_set_notify_enabled(const void *ph,
return ret;
 }
 
-static void *scmi_power_fill_custom_report(const void *ph,
-  u8 evt_id, ktime_t timestamp,
-  const void *payld, size_t payld_sz,
-  void 

[PATCH v4 26/37] firmware: arm_scmi: remove legacy scmi_sensor_ops protocol interface

2021-01-06 Thread Cristian Marussi
Now that all the SCMI driver users have been migrated to the new interface
remove the legacy interface and all the transient code.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/sensors.c | 82 -
 include/linux/scmi_protocol.h   | 19 ---
 2 files changed, 101 deletions(-)

diff --git a/drivers/firmware/arm_scmi/sensors.c 
b/drivers/firmware/arm_scmi/sensors.c
index 5d2da4f78108..478585f644fa 100644
--- a/drivers/firmware/arm_scmi/sensors.c
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -624,17 +624,6 @@ scmi_sensor_trip_point_config(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int
-__scmi_sensor_trip_point_config(const struct scmi_handle *handle,
-   u32 sensor_id, u8 trip_id, u64 trip_value)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_trip_point_config(ph, sensor_id, trip_id,
-trip_value);
-}
-
 static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
  u32 sensor_id, u32 *sensor_config)
 {
@@ -660,15 +649,6 @@ static int scmi_sensor_config_get(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int __scmi_sensor_config_get(const struct scmi_handle *handle,
-   u32 sensor_id, u32 *sensor_config)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_config_get(ph, sensor_id, sensor_config);
-}
-
 static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
  u32 sensor_id, u32 sensor_config)
 {
@@ -697,15 +677,6 @@ static int scmi_sensor_config_set(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int __scmi_sensor_config_set(const struct scmi_handle *handle,
-   u32 sensor_id, u32 sensor_config)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_config_set(ph, sensor_id, sensor_config);
-}
-
 /**
  * scmi_sensor_reading_get  - Read scalar sensor value
  * @ph: Protocol handle
@@ -760,15 +731,6 @@ static int scmi_sensor_reading_get(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int __scmi_sensor_reading_get(const struct scmi_handle *handle,
-u32 sensor_id, u64 *value)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_reading_get(ph, sensor_id, value);
-}
-
 static inline void
 scmi_parse_sensor_readings(struct scmi_sensor_reading *out,
   const struct scmi_sensor_reading_resp *in)
@@ -847,18 +809,6 @@ scmi_sensor_reading_get_timestamped(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int
-__scmi_sensor_reading_get_timestamped(const struct scmi_handle *handle,
- u32 sensor_id, u8 count,
- struct scmi_sensor_reading *readings)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_reading_get_timestamped(ph, sensor_id, count,
-  readings);
-}
-
 static const struct scmi_sensor_info *
 scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id)
 {
@@ -867,15 +817,6 @@ scmi_sensor_info_get(const struct scmi_protocol_handle 
*ph, u32 sensor_id)
return si->sensors + sensor_id;
 }
 
-static const struct scmi_sensor_info *
-__scmi_sensor_info_get(const struct scmi_handle *handle, u32 sensor_id)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_info_get(ph, sensor_id);
-}
-
 static int scmi_sensor_count_get(const struct scmi_protocol_handle *ph)
 {
struct sensors_info *si = ph->get_priv(ph);
@@ -883,24 +824,6 @@ static int scmi_sensor_count_get(const struct 
scmi_protocol_handle *ph)
return si->num_sensors;
 }
 
-static int __scmi_sensor_count_get(const struct scmi_handle *handle)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_SENSOR);
-
-   return scmi_sensor_count_get(ph);
-}
-
-static const struct scmi_sensor_ops sensor_ops = {
-   .count_get = __scmi_sensor_count_get,
-   .info_get = __scmi_sensor_info_get,
-   .trip_point_config = __scmi_sensor_trip_point_config,
-   .reading_get = __scmi_sensor_reading_get,
-   .reading_get_timestamped = __scmi_sensor_reading_get_timestamped,
-   .config_get = 

[PATCH v4 18/37] firmware: arm_scmi: port Clock protocol to new protocols interface

2021-01-06 Thread Cristian Marussi
Convert internals of protocol implementation to use protocol handles and
expose a new protocol operations interface for SCMI driver using the new
get/put common operations, while keeping the old handle->clk_ops still
around to ease transition.

Remove handle->clock_priv now unused.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/clock.c | 182 --
 include/linux/scmi_protocol.h |  20 +++-
 2 files changed, 139 insertions(+), 63 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c 
b/drivers/firmware/arm_scmi/clock.c
index e8c84cff9922..bf7dcd537fce 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -74,52 +74,53 @@ struct clock_info {
struct scmi_clock_info *clk;
 };
 
-static int scmi_clock_protocol_attributes_get(const struct scmi_handle *handle,
- struct clock_info *ci)
+static int
+scmi_clock_protocol_attributes_get(const struct scmi_protocol_handle *ph,
+  struct clock_info *ci)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_clock_protocol_attributes *attr;
 
-   ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
-SCMI_PROTOCOL_CLOCK, 0, sizeof(*attr), );
+   ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
+ 0, sizeof(*attr), );
if (ret)
return ret;
 
attr = t->rx.buf;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
ci->num_clocks = le16_to_cpu(attr->num_clocks);
ci->max_async_req = attr->max_async_req;
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
-static int scmi_clock_attributes_get(const struct scmi_handle *handle,
+static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
 u32 clk_id, struct scmi_clock_info *clk)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_clock_attributes *attr;
 
-   ret = scmi_xfer_get_init(handle, CLOCK_ATTRIBUTES, SCMI_PROTOCOL_CLOCK,
-sizeof(clk_id), sizeof(*attr), );
+   ret = ph->xops->xfer_get_init(ph, CLOCK_ATTRIBUTES,
+ sizeof(clk_id), sizeof(*attr), );
if (ret)
return ret;
 
put_unaligned_le32(clk_id, t->tx.buf);
attr = t->rx.buf;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret)
strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
else
clk->name[0] = '\0';
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
@@ -136,7 +137,7 @@ static int rate_cmp_func(const void *_r1, const void *_r2)
 }
 
 static int
-scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
+scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 
clk_id,
  struct scmi_clock_info *clk)
 {
u64 *rate = NULL;
@@ -148,8 +149,8 @@ scmi_clock_describe_rates_get(const struct scmi_handle 
*handle, u32 clk_id,
struct scmi_msg_clock_describe_rates *clk_desc;
struct scmi_msg_resp_clock_describe_rates *rlist;
 
-   ret = scmi_xfer_get_init(handle, CLOCK_DESCRIBE_RATES,
-SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, );
+   ret = ph->xops->xfer_get_init(ph, CLOCK_DESCRIBE_RATES,
+ sizeof(*clk_desc), 0, );
if (ret)
return ret;
 
@@ -161,7 +162,7 @@ scmi_clock_describe_rates_get(const struct scmi_handle 
*handle, u32 clk_id,
/* Set the number of rates to be skipped/already read */
clk_desc->rate_index = cpu_to_le32(tot_rate_cnt);
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (ret)
goto err;
 
@@ -171,7 +172,7 @@ scmi_clock_describe_rates_get(const struct scmi_handle 
*handle, u32 clk_id,
num_returned = NUM_RETURNED(rates_flag);
 
if (tot_rate_cnt + num_returned > SCMI_MAX_NUM_RATES) {
-   dev_err(handle->dev, "No. of rates > MAX_NUM_RATES");
+   dev_err(ph->dev, "No. of rates > MAX_NUM_RATES");
break;
}
 
@@ -179,7 +180,7 @@ scmi_clock_describe_rates_get(const struct scmi_handle 
*handle, u32 clk_id,
clk->range.min_rate = RATE_TO_U64(rlist->rate[0]);
clk->range.max_rate = RATE_TO_U64(rlist->rate[1]);
clk->range.step_size = RATE_TO_U64(rlist->rate[2]);
-   dev_dbg(handle->dev, "Min %llu Max %llu Step %llu Hz\n",
+  

[PATCH v4 14/37] firmware: arm_scmi: remove legacy scmi_perf_ops protocol interface

2021-01-06 Thread Cristian Marussi
Now that all the SCMI driver users have been migrated to the new interface
remove the legacy interface and all the transient code.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/perf.c | 120 ---
 include/linux/scmi_protocol.h|  27 ---
 2 files changed, 147 deletions(-)

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 99144a70ded6..b2e1bdad2b3a 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -391,15 +391,6 @@ static int scmi_perf_limits_set(const struct 
scmi_protocol_handle *ph,
return scmi_perf_mb_limits_set(ph, domain, max_perf, min_perf);
 }
 
-static int __scmi_perf_limits_set(const struct scmi_handle *handle,
- u32 domain, u32 max_perf, u32 min_perf)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_perf_limits_set(ph, domain, max_perf, min_perf);
-}
-
 static int scmi_perf_mb_limits_get(const struct scmi_protocol_handle *ph,
   u32 domain, u32 *max_perf, u32 *min_perf)
 {
@@ -441,15 +432,6 @@ static int scmi_perf_limits_get(const struct 
scmi_protocol_handle *ph,
return scmi_perf_mb_limits_get(ph, domain, max_perf, min_perf);
 }
 
-static int __scmi_perf_limits_get(const struct scmi_handle *handle,
- u32 domain, u32 *max_perf, u32 *min_perf)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_perf_limits_get(ph, domain, max_perf, min_perf);
-}
-
 static int scmi_perf_mb_level_set(const struct scmi_protocol_handle *ph,
  u32 domain, u32 level, bool poll)
 {
@@ -487,15 +469,6 @@ static int scmi_perf_level_set(const struct 
scmi_protocol_handle *ph,
return scmi_perf_mb_level_set(ph, domain, level, poll);
 }
 
-static int __scmi_perf_level_set(const struct scmi_handle *handle,
-u32 domain, u32 level, bool poll)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_perf_level_set(ph, domain, level, poll);
-}
-
 static int scmi_perf_mb_level_get(const struct scmi_protocol_handle *ph,
  u32 domain, u32 *level, bool poll)
 {
@@ -532,15 +505,6 @@ static int scmi_perf_level_get(const struct 
scmi_protocol_handle *ph,
return scmi_perf_mb_level_get(ph, domain, level, poll);
 }
 
-static int __scmi_perf_level_get(const struct scmi_handle *handle,
-u32 domain, u32 *level, bool poll)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_perf_level_get(ph, domain, level, poll);
-}
-
 static int scmi_perf_level_limits_notify(const struct scmi_protocol_handle *ph,
 u32 domain, int message_id,
 bool enable)
@@ -704,15 +668,6 @@ static int scmi_dvfs_device_opps_add(const struct 
scmi_protocol_handle *ph,
return 0;
 }
 
-static int __scmi_dvfs_device_opps_add(const struct scmi_handle *handle,
-  struct device *dev)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_dvfs_device_opps_add(ph, dev);
-}
-
 static int
 scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph,
 struct device *dev)
@@ -729,16 +684,6 @@ scmi_dvfs_transition_latency_get(const struct 
scmi_protocol_handle *ph,
return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
 }
 
-static int
-__scmi_dvfs_transition_latency_get(const struct scmi_handle *handle,
-  struct device *dev)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_dvfs_transition_latency_get(ph, dev);
-}
-
 static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 
domain,
  unsigned long freq, bool poll)
 {
@@ -748,15 +693,6 @@ static int scmi_dvfs_freq_set(const struct 
scmi_protocol_handle *ph, u32 domain,
return scmi_perf_level_set(ph, domain, freq / dom->mult_factor, poll);
 }
 
-static int __scmi_dvfs_freq_set(const struct scmi_handle *handle,
-   u32 domain, unsigned long freq, bool poll)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_PERF);
-
-   return scmi_dvfs_freq_set(ph, domain, freq, poll);
-}
-
 static int scmi_dvfs_freq_get(const struct scmi_protocol_handle *ph, u32 
domain,

[PATCH v4 17/37] firmware: arm_scmi: remove legacy scmi_power_ops protocol interface

2021-01-06 Thread Cristian Marussi
Now that all the SCMI driver users have been migrated to the new interface
remove the legacy interface and all the transient code.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/power.c | 47 ---
 include/linux/scmi_protocol.h | 11 
 2 files changed, 58 deletions(-)

diff --git a/drivers/firmware/arm_scmi/power.c 
b/drivers/firmware/arm_scmi/power.c
index b3d1c032218c..06e3ab17a0eb 100644
--- a/drivers/firmware/arm_scmi/power.c
+++ b/drivers/firmware/arm_scmi/power.c
@@ -146,15 +146,6 @@ static int scmi_power_state_set(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int __scmi_power_state_set(const struct scmi_handle *handle,
- u32 domain, u32 state)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_POWER);
-
-   return scmi_power_state_set(ph, domain, state);
-}
-
 static int scmi_power_state_get(const struct scmi_protocol_handle *ph,
u32 domain, u32 *state)
 {
@@ -175,15 +166,6 @@ static int scmi_power_state_get(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int __scmi_power_state_get(const struct scmi_handle *handle,
- u32 domain, u32 *state)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_POWER);
-
-   return scmi_power_state_get(ph, domain, state);
-}
-
 static int scmi_power_num_domains_get(const struct scmi_protocol_handle *ph)
 {
struct scmi_power_info *pi = ph->get_priv(ph);
@@ -191,14 +173,6 @@ static int scmi_power_num_domains_get(const struct 
scmi_protocol_handle *ph)
return pi->num_domains;
 }
 
-static int __scmi_power_num_domains_get(const struct scmi_handle *handle)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_POWER);
-
-   return scmi_power_num_domains_get(ph);
-}
-
 static char *scmi_power_name_get(const struct scmi_protocol_handle *ph,
 u32 domain)
 {
@@ -208,22 +182,6 @@ static char *scmi_power_name_get(const struct 
scmi_protocol_handle *ph,
return dom->name;
 }
 
-static char *__scmi_power_name_get(const struct scmi_handle *handle,
-  u32 domain)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_POWER);
-
-   return scmi_power_name_get(ph, domain);
-}
-
-static const struct scmi_power_ops power_ops = {
-   .num_domains_get = __scmi_power_num_domains_get,
-   .name_get = __scmi_power_name_get,
-   .state_set = __scmi_power_state_set,
-   .state_get = __scmi_power_state_get,
-};
-
 static const struct scmi_power_proto_ops power_proto_ops = {
.num_domains_get = scmi_power_num_domains_get,
.name_get = scmi_power_name_get,
@@ -324,7 +282,6 @@ static int scmi_power_protocol_init(const struct 
scmi_protocol_handle *ph)
int domain;
u32 version;
struct scmi_power_info *pinfo;
-   struct scmi_handle *handle;
 
ph->xops->version_get(ph, );
 
@@ -350,10 +307,6 @@ static int scmi_power_protocol_init(const struct 
scmi_protocol_handle *ph)
 
pinfo->version = version;
 
-   /* Transient code for legacy ops interface */
-   handle = scmi_map_scmi_handle(ph);
-   handle->power_ops = _ops;
-
return ph->set_priv(ph, pinfo);
 }
 
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index c038994e8adc..73d734eda954 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -152,15 +152,6 @@ struct scmi_power_proto_ops {
 u32 *state);
 };
 
-struct scmi_power_ops {
-   int (*num_domains_get)(const struct scmi_handle *handle);
-   char *(*name_get)(const struct scmi_handle *handle, u32 domain);
-   int (*state_set)(const struct scmi_handle *handle, u32 domain,
-u32 state);
-   int (*state_get)(const struct scmi_handle *handle, u32 domain,
-u32 *state);
-};
-
 /**
  * scmi_sensor_reading  - represent a timestamped read
  *
@@ -611,7 +602,6 @@ struct scmi_notify_ops {
  *
  * @dev: pointer to the SCMI device
  * @version: pointer to the structure containing SCMI version information
- * @power_ops: pointer to set of power protocol operations
  * @clk_ops: pointer to set of clock protocol operations
  * @sensor_ops: pointer to set of sensor protocol operations
  * @reset_ops: pointer to set of reset protocol operations
@@ -638,7 +628,6 @@ struct scmi_handle {
struct device *dev;
struct scmi_revision_info *version;
const struct scmi_clk_ops *clk_ops;
-   const struct scmi_power_ops *power_ops;
const struct scmi_sensor_ops *sensor_ops;
const struct scmi_reset_ops *reset_ops;

[PATCH v4 32/37] firmware: arm_scmi: cleanup legacy protocol init code

2021-01-06 Thread Cristian Marussi
Now that all protocols and drivers have been ported to the new interface
based on protocol handles and get/put operations, remove all the legacy
transient initialization code.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/bus.c| 26 +-
 drivers/firmware/arm_scmi/common.h |  5 +
 2 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 044aa9e3ebb0..9fbf618b9c4b 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -66,27 +66,11 @@ const struct scmi_protocol *scmi_get_protocol(int 
protocol_id)
return proto;
 }
 
-static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
-{
-   const struct scmi_protocol *proto;
-
-   proto = scmi_get_protocol(protocol_id);
-   if (!proto)
-   return -EINVAL;
-   return proto->init(handle);
-}
-
-static int scmi_protocol_dummy_init(struct scmi_handle *handle)
-{
-   return 0;
-}
-
 static int scmi_dev_probe(struct device *dev)
 {
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
struct scmi_device *scmi_dev = to_scmi_dev(dev);
const struct scmi_device_id *id;
-   int ret;
 
id = scmi_dev_match_id(scmi_dev, scmi_drv);
if (!id)
@@ -95,14 +79,6 @@ static int scmi_dev_probe(struct device *dev)
if (!scmi_dev->handle)
return -EPROBE_DEFER;
 
-   ret = scmi_protocol_init(scmi_dev->protocol_id, scmi_dev->handle);
-   if (ret)
-   return ret;
-
-   /* Skip protocol initialisation for additional devices */
-   idr_replace(_available_protocols, _protocol_dummy_init,
-   scmi_dev->protocol_id);
-
return scmi_drv->probe(scmi_dev);
 }
 
@@ -219,7 +195,7 @@ int scmi_protocol_register(const struct scmi_protocol 
*proto)
return -EINVAL;
}
 
-   if (!proto->init && !proto->init_instance) {
+   if (!proto->init_instance) {
pr_err("missing .init() for protocol 0x%x\n", proto->id);
return -EINVAL;
}
diff --git a/drivers/firmware/arm_scmi/common.h 
b/drivers/firmware/arm_scmi/common.h
index 45387a32d79e..86f4fb707145 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -224,14 +224,12 @@ int scmi_version_get(const struct scmi_handle *h, u8 
protocol, u32 *version);
 void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
 u8 *prot_imp);
 
-typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *);
 typedef int (*scmi_prot_init_ph_fn_t)(const struct scmi_protocol_handle *);
 
 /**
  * struct scmi_protocol  - Protocol descriptor
  * @id: Protocol ID.
- * @init: Mandatory protocol initialization function.
- * @init_instance: Optional protocol instance initialization function.
+ * @init_instance: Mandatory protocol initialization function.
  * @deinit_instance: Optional protocol de-initialization function.
  * @ops: Optional reference to the operations provided by the protocol and
  *  exposed in scmi_protocol.h.
@@ -239,7 +237,6 @@ typedef int (*scmi_prot_init_ph_fn_t)(const struct 
scmi_protocol_handle *);
  */
 struct scmi_protocol {
const u8id;
-   const scmi_prot_init_fn_t   init;
const scmi_prot_init_ph_fn_tinit_instance;
const scmi_prot_init_ph_fn_tdeinit_instance;
const void  *ops;
-- 
2.17.1



[PATCH v4 28/37] firmware: arm_scmi: port Voltage protocol to new protocols interface

2021-01-06 Thread Cristian Marussi
Convert internals of protocol implementation to use protocol handles and
expose a new protocol operations interface for SCMI driver using the new
get/put common operations, while keeping the old handle->voltage_ops still
around to ease transition.

Remove handle->voltage_priv now unused.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/voltage.c | 179 ++--
 include/linux/scmi_protocol.h   |  24 ++--
 2 files changed, 136 insertions(+), 67 deletions(-)

diff --git a/drivers/firmware/arm_scmi/voltage.c 
b/drivers/firmware/arm_scmi/voltage.c
index 8145ee79bb19..7b390426028e 100644
--- a/drivers/firmware/arm_scmi/voltage.c
+++ b/drivers/firmware/arm_scmi/voltage.c
@@ -59,23 +59,23 @@ struct voltage_info {
struct scmi_voltage_info *domains;
 };
 
-static int scmi_protocol_attributes_get(const struct scmi_handle *handle,
+static int scmi_protocol_attributes_get(const struct scmi_protocol_handle *ph,
struct voltage_info *vinfo)
 {
int ret;
struct scmi_xfer *t;
 
-   ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
-SCMI_PROTOCOL_VOLTAGE, 0, sizeof(__le32), );
+   ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
+ sizeof(__le32), );
if (ret)
return ret;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret)
vinfo->num_domains =
NUM_VOLTAGE_DOMAINS(get_unaligned_le32(t->rx.buf));
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
@@ -109,24 +109,23 @@ static int scmi_init_voltage_levels(struct device *dev,
return 0;
 }
 
-static int scmi_voltage_descriptors_get(const struct scmi_handle *handle,
+static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph,
struct voltage_info *vinfo)
 {
int ret, dom;
struct scmi_xfer *td, *tl;
-   struct device *dev = handle->dev;
+   struct device *dev = ph->dev;
struct scmi_msg_resp_domain_attributes *resp_dom;
struct scmi_msg_resp_describe_levels *resp_levels;
 
-   ret = scmi_xfer_get_init(handle, VOLTAGE_DOMAIN_ATTRIBUTES,
-SCMI_PROTOCOL_VOLTAGE, sizeof(__le32),
-sizeof(*resp_dom), );
+   ret = ph->xops->xfer_get_init(ph, VOLTAGE_DOMAIN_ATTRIBUTES,
+ sizeof(__le32), sizeof(*resp_dom), );
if (ret)
return ret;
resp_dom = td->rx.buf;
 
-   ret = scmi_xfer_get_init(handle, VOLTAGE_DESCRIBE_LEVELS,
-SCMI_PROTOCOL_VOLTAGE, sizeof(__le64), 0, );
+   ret = ph->xops->xfer_get_init(ph, VOLTAGE_DESCRIBE_LEVELS,
+ sizeof(__le64), 0, );
if (ret)
goto outd;
resp_levels = tl->rx.buf;
@@ -139,7 +138,7 @@ static int scmi_voltage_descriptors_get(const struct 
scmi_handle *handle,
 
/* Retrieve domain attributes at first ... */
put_unaligned_le32(dom, td->tx.buf);
-   ret = scmi_do_xfer(handle, td);
+   ret = ph->xops->do_xfer(ph, td);
/* Skip domain on comms error */
if (ret)
continue;
@@ -157,7 +156,7 @@ static int scmi_voltage_descriptors_get(const struct 
scmi_handle *handle,
 
cmd->domain_id = cpu_to_le32(v->id);
cmd->level_index = desc_index;
-   ret = scmi_do_xfer(handle, tl);
+   ret = ph->xops->do_xfer(ph, tl);
if (ret)
break;
 
@@ -176,7 +175,7 @@ static int scmi_voltage_descriptors_get(const struct 
scmi_handle *handle,
}
 
if (desc_index + num_returned > v->num_levels) {
-   dev_err(handle->dev,
+   dev_err(ph->dev,
"No. of voltage levels can't exceed 
%d\n",
v->num_levels);
ret = -EINVAL;
@@ -195,7 +194,7 @@ static int scmi_voltage_descriptors_get(const struct 
scmi_handle *handle,
 
desc_index += num_returned;
 
-   scmi_reset_rx_to_maxsz(handle, tl);
+   ph->xops->reset_rx_to_maxsz(ph, tl);
/* check both to avoid infinite loop due to buggy fw */
} while (num_returned && num_remaining);
 
@@ -204,55 +203,52 @@ static int scmi_voltage_descriptors_get(const struct 
scmi_handle *handle,
devm_kfree(dev, v->levels_uv);
}
 
-   scmi_reset_rx_to_maxsz(handle, td);
+   

[PATCH v4 25/37] hwmon: (scmi) port driver to the new scmi_sensor_proto_ops interface

2021-01-06 Thread Cristian Marussi
Port driver to the new SCMI Sensor interface based on protocol handles
and common devm_get_ops().

Signed-off-by: Cristian Marussi 
---
 drivers/hwmon/scmi-hwmon.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
index 17d064e58938..399011740b00 100644
--- a/drivers/hwmon/scmi-hwmon.c
+++ b/drivers/hwmon/scmi-hwmon.c
@@ -2,7 +2,7 @@
 /*
  * System Control and Management Interface(SCMI) based hwmon sensor driver
  *
- * Copyright (C) 2018 ARM Ltd.
+ * Copyright (C) 2018-2020 ARM Ltd.
  * Sudeep Holla 
  */
 
@@ -13,8 +13,10 @@
 #include 
 #include 
 
+static const struct scmi_sensor_proto_ops *sensor_ops;
+
 struct scmi_sensors {
-   const struct scmi_handle *handle;
+   const struct scmi_protocol_handle *ph;
const struct scmi_sensor_info **info[hwmon_max];
 };
 
@@ -69,10 +71,9 @@ static int scmi_hwmon_read(struct device *dev, enum 
hwmon_sensor_types type,
u64 value;
const struct scmi_sensor_info *sensor;
struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev);
-   const struct scmi_handle *h = scmi_sensors->handle;
 
sensor = *(scmi_sensors->info[type] + channel);
-   ret = h->sensor_ops->reading_get(h, sensor->id, );
+   ret = sensor_ops->reading_get(scmi_sensors->ph, sensor->id, );
if (ret)
return ret;
 
@@ -169,11 +170,16 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
struct hwmon_channel_info *scmi_hwmon_chan;
const struct hwmon_channel_info **ptr_scmi_ci;
const struct scmi_handle *handle = sdev->handle;
+   struct scmi_protocol_handle *ph;
 
-   if (!handle || !handle->sensor_ops)
+   if (!handle)
return -ENODEV;
 
-   nr_sensors = handle->sensor_ops->count_get(handle);
+   sensor_ops = handle->devm_get_ops(sdev, SCMI_PROTOCOL_SENSOR, );
+   if (IS_ERR(sensor_ops))
+   return PTR_ERR(sensor_ops);
+
+   nr_sensors = sensor_ops->count_get(ph);
if (!nr_sensors)
return -EIO;
 
@@ -181,10 +187,10 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
if (!scmi_sensors)
return -ENOMEM;
 
-   scmi_sensors->handle = handle;
+   scmi_sensors->ph = ph;
 
for (i = 0; i < nr_sensors; i++) {
-   sensor = handle->sensor_ops->info_get(handle, i);
+   sensor = sensor_ops->info_get(ph, i);
if (!sensor)
return -EINVAL;
 
@@ -236,7 +242,7 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
}
 
for (i = nr_sensors - 1; i >= 0 ; i--) {
-   sensor = handle->sensor_ops->info_get(handle, i);
+   sensor = sensor_ops->info_get(ph, i);
if (!sensor)
continue;
 
-- 
2.17.1



[PATCH v4 33/37] firmware: arm_scmi: cleanup unused core xfer wrappers

2021-01-06 Thread Cristian Marussi
Remove unused core scmi_xfer wrappers now that we have migrated all
protocols to the new interface based on protocol handles.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/common.h | 15 -
 drivers/firmware/arm_scmi/driver.c | 91 --
 2 files changed, 106 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h 
b/drivers/firmware/arm_scmi/common.h
index 86f4fb707145..65db0aefc489 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -143,15 +143,6 @@ struct scmi_xfer {
struct completion *async_done;
 };
 
-void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer);
-int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer);
-int scmi_do_xfer_with_response(const struct scmi_handle *h,
-  struct scmi_xfer *xfer);
-int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
-  size_t tx_size, size_t rx_size, struct scmi_xfer **p);
-void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
-   struct scmi_xfer *xfer);
-
 struct scmi_xfer_ops;
 
 /**
@@ -181,11 +172,6 @@ struct scmi_protocol_handle {
void *(*get_priv)(const struct scmi_protocol_handle *ph);
 };
 
-const struct scmi_protocol_handle *
-scmi_map_protocol_handle(const struct scmi_handle *handle, u8 prot_id);
-
-struct scmi_handle *scmi_map_scmi_handle(const struct scmi_protocol_handle 
*ph);
-
 /**
  * struct scmi_xfer_ops  - References to the core SCMI xfer operations.
  * @version_get: Get this version protocol.
@@ -220,7 +206,6 @@ scmi_get_revision_area(const struct scmi_protocol_handle 
*ph);
 int scmi_handle_put(const struct scmi_handle *handle);
 struct scmi_handle *scmi_handle_get(struct device *dev);
 void scmi_set_handle(struct scmi_device *scmi_dev);
-int scmi_version_get(const struct scmi_handle *h, u8 protocol, u32 *version);
 void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
 u8 *prot_imp);
 
diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index 68a40d83325c..77e108475aea 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -349,28 +349,6 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 
msg_hdr)
}
 }
 
-/* Transient code wrapper to ease API migration */
-const struct scmi_protocol_handle *
-scmi_map_protocol_handle(const struct scmi_handle *handle, u8 prot_id)
-{
-   struct scmi_info *info = handle_to_scmi_info(handle);
-   const struct scmi_protocol_instance *pi;
-
-   mutex_lock(>protocols_mtx);
-   pi = idr_find(>protocols, prot_id);
-   mutex_unlock(>protocols_mtx);
-
-   return pi ? >ph : NULL;
-}
-
-/* Transient code wrapper to ease API migration */
-struct scmi_handle *scmi_map_scmi_handle(const struct scmi_protocol_handle *ph)
-{
-   const struct scmi_protocol_instance *pi = ph_to_pi(ph);
-
-   return (struct scmi_handle *)pi->handle;
-}
-
 /**
  * xfer_put() - Release a transmit message
  *
@@ -386,17 +364,6 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
__scmi_xfer_put(>tx_minfo, xfer);
 }
 
-void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer)
-{
-   const struct scmi_protocol_handle *ph;
-
-   ph = scmi_map_protocol_handle(h, xfer->hdr.protocol_id);
-   if (!ph)
-   return;
-
-   return xfer_put(ph, xfer);
-}
-
 #define SCMI_MAX_POLL_TO_NS(100 * NSEC_PER_USEC)
 
 static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
@@ -480,17 +447,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
return ret;
 }
 
-int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer)
-{
-   const struct scmi_protocol_handle *ph;
-
-   ph = scmi_map_protocol_handle(h, xfer->hdr.protocol_id);
-   if (!ph)
-   return -EINVAL;
-
-   return do_xfer(ph, xfer);
-}
-
 static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
  struct scmi_xfer *xfer)
 {
@@ -500,18 +456,6 @@ static void reset_rx_to_maxsz(const struct 
scmi_protocol_handle *ph,
xfer->rx.len = info->desc->max_msg_size;
 }
 
-void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
-   struct scmi_xfer *xfer)
-{
-   const struct scmi_protocol_handle *ph;
-
-   ph = scmi_map_protocol_handle(handle, xfer->hdr.protocol_id);
-   if (!ph)
-   return;
-
-   return reset_rx_to_maxsz(ph, xfer);
-}
-
 #define SCMI_MAX_RESPONSE_TIMEOUT  (2 * MSEC_PER_SEC)
 
 /**
@@ -543,18 +487,6 @@ static int do_xfer_with_response(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-int scmi_do_xfer_with_response(const struct scmi_handle *h,
-  struct scmi_xfer *xfer)
-{
-   const struct scmi_protocol_handle *ph;
-
-  

[PATCH v4 20/37] firmware: arm_scmi: remove legacy scmi_clk_ops protocol interface

2021-01-06 Thread Cristian Marussi
Now that all the SCMI driver users have been migrated to the new interface
remove the legacy interface and all the transient code.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/clock.c | 67 ---
 include/linux/scmi_protocol.h | 15 ---
 2 files changed, 82 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c 
b/drivers/firmware/arm_scmi/clock.c
index bf7dcd537fce..a0a6593f464f 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -235,16 +235,6 @@ scmi_clock_rate_get(const struct scmi_protocol_handle *ph,
return ret;
 }
 
-static int
-__scmi_clock_rate_get(const struct scmi_handle *handle,
- u32 clk_id, u64 *value)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_CLOCK);
-
-   return scmi_clock_rate_get(ph, clk_id, value);
-}
-
 static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
   u32 clk_id, u64 rate)
 {
@@ -280,15 +270,6 @@ static int scmi_clock_rate_set(const struct 
scmi_protocol_handle *ph,
return ret;
 }
 
-static int __scmi_clock_rate_set(const struct scmi_handle *handle,
-u32 clk_id, u64 rate)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_CLOCK);
-
-   return scmi_clock_rate_set(ph, clk_id, rate);
-}
-
 static int
 scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
  u32 config)
@@ -317,27 +298,11 @@ static int scmi_clock_enable(const struct 
scmi_protocol_handle *ph, u32 clk_id)
return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE);
 }
 
-static int __scmi_clock_enable(const struct scmi_handle *handle, u32 clk_id)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_CLOCK);
-
-   return scmi_clock_enable(ph, clk_id);
-}
-
 static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 
clk_id)
 {
return scmi_clock_config_set(ph, clk_id, 0);
 }
 
-static int __scmi_clock_disable(const struct scmi_handle *handle, u32 clk_id)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_CLOCK);
-
-   return scmi_clock_disable(ph, clk_id);
-}
-
 static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
 {
struct clock_info *ci = ph->get_priv(ph);
@@ -345,14 +310,6 @@ static int scmi_clock_count_get(const struct 
scmi_protocol_handle *ph)
return ci->num_clocks;
 }
 
-static int __scmi_clock_count_get(const struct scmi_handle *handle)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_CLOCK);
-
-   return scmi_clock_count_get(ph);
-}
-
 static const struct scmi_clock_info *
 scmi_clock_info_get(const struct scmi_protocol_handle *ph, u32 clk_id)
 {
@@ -365,24 +322,6 @@ scmi_clock_info_get(const struct scmi_protocol_handle *ph, 
u32 clk_id)
return clk;
 }
 
-static const struct scmi_clock_info *
-__scmi_clock_info_get(const struct scmi_handle *handle, u32 clk_id)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_CLOCK);
-
-   return scmi_clock_info_get(ph, clk_id);
-}
-
-static const struct scmi_clk_ops clk_ops = {
-   .count_get = __scmi_clock_count_get,
-   .info_get = __scmi_clock_info_get,
-   .rate_get = __scmi_clock_rate_get,
-   .rate_set = __scmi_clock_rate_set,
-   .enable = __scmi_clock_enable,
-   .disable = __scmi_clock_disable,
-};
-
 static const struct scmi_clk_proto_ops clk_proto_ops = {
.count_get = scmi_clock_count_get,
.info_get = scmi_clock_info_get,
@@ -397,7 +336,6 @@ static int scmi_clock_protocol_init(const struct 
scmi_protocol_handle *ph)
u32 version;
int clkid, ret;
struct clock_info *cinfo;
-   struct scmi_handle *handle;
 
ph->xops->version_get(ph, );
 
@@ -424,11 +362,6 @@ static int scmi_clock_protocol_init(const struct 
scmi_protocol_handle *ph)
}
 
cinfo->version = version;
-
-   /* Transient code for legacy ops interface */
-   handle = scmi_map_scmi_handle(ph);
-   handle->clk_ops = _ops;
-
return ph->set_priv(ph, cinfo);
 }
 
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index a403035df0ef..6605b75f4577 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -84,19 +84,6 @@ struct scmi_clk_proto_ops {
int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
 };
 
-struct scmi_clk_ops {
-   int (*count_get)(const struct scmi_handle *hamdle);
-
-   const struct scmi_clock_info *(*info_get)
-   (const struct scmi_handle *handle, u32 clk_id);
-   int 

[PATCH v4 23/37] firmware: arm_scmi: remove legacy scmi_reset_ops protocol interface

2021-01-06 Thread Cristian Marussi
Now that all the SCMI driver users have been migrated to the new interface
remove the legacy interface and all the transient code.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/reset.c | 68 ---
 include/linux/scmi_protocol.h | 11 -
 2 files changed, 79 deletions(-)

diff --git a/drivers/firmware/arm_scmi/reset.c 
b/drivers/firmware/arm_scmi/reset.c
index 9c808f5add7e..3856ceed2bd7 100644
--- a/drivers/firmware/arm_scmi/reset.c
+++ b/drivers/firmware/arm_scmi/reset.c
@@ -125,14 +125,6 @@ static int scmi_reset_num_domains_get(const struct 
scmi_protocol_handle *ph)
return pi->num_domains;
 }
 
-static int __scmi_reset_num_domains_get(const struct scmi_handle *handle)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_RESET);
-
-   return scmi_reset_num_domains_get(ph);
-}
-
 static char *scmi_reset_name_get(const struct scmi_protocol_handle *ph,
 u32 domain)
 {
@@ -143,15 +135,6 @@ static char *scmi_reset_name_get(const struct 
scmi_protocol_handle *ph,
return dom->name;
 }
 
-static char *__scmi_reset_name_get(const struct scmi_handle *handle,
-  u32 domain)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_RESET);
-
-   return scmi_reset_name_get(ph, domain);
-}
-
 static int scmi_reset_latency_get(const struct scmi_protocol_handle *ph,
  u32 domain)
 {
@@ -161,15 +144,6 @@ static int scmi_reset_latency_get(const struct 
scmi_protocol_handle *ph,
return dom->latency_us;
 }
 
-static int __scmi_reset_latency_get(const struct scmi_handle *handle,
-   u32 domain)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_RESET);
-
-   return scmi_reset_latency_get(ph, domain);
-}
-
 static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
 u32 flags, u32 state)
 {
@@ -207,15 +181,6 @@ static int scmi_reset_domain_reset(const struct 
scmi_protocol_handle *ph,
 ARCH_COLD_RESET);
 }
 
-static int __scmi_reset_domain_reset(const struct scmi_handle *handle,
-u32 domain)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_RESET);
-
-   return scmi_reset_domain_reset(ph, domain);
-}
-
 static int
 scmi_reset_domain_assert(const struct scmi_protocol_handle *ph, u32 domain)
 {
@@ -223,39 +188,12 @@ scmi_reset_domain_assert(const struct 
scmi_protocol_handle *ph, u32 domain)
 ARCH_COLD_RESET);
 }
 
-static int
-__scmi_reset_domain_assert(const struct scmi_handle *handle, u32 domain)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_RESET);
-
-   return scmi_reset_domain_assert(ph, domain);
-}
-
 static int
 scmi_reset_domain_deassert(const struct scmi_protocol_handle *ph, u32 domain)
 {
return scmi_domain_reset(ph, domain, 0, ARCH_COLD_RESET);
 }
 
-static int
-__scmi_reset_domain_deassert(const struct scmi_handle *handle, u32 domain)
-{
-   const struct scmi_protocol_handle *ph =
-   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_RESET);
-
-   return scmi_reset_domain_deassert(ph, domain);
-}
-
-static const struct scmi_reset_ops reset_ops = {
-   .num_domains_get = __scmi_reset_num_domains_get,
-   .name_get = __scmi_reset_name_get,
-   .latency_get = __scmi_reset_latency_get,
-   .reset = __scmi_reset_domain_reset,
-   .assert = __scmi_reset_domain_assert,
-   .deassert = __scmi_reset_domain_deassert,
-};
-
 static const struct scmi_reset_proto_ops reset_proto_ops = {
.num_domains_get = scmi_reset_num_domains_get,
.name_get = scmi_reset_name_get,
@@ -357,7 +295,6 @@ static int scmi_reset_protocol_init(const struct 
scmi_protocol_handle *ph)
int domain;
u32 version;
struct scmi_reset_info *pinfo;
-   struct scmi_handle *handle;
 
ph->xops->version_get(ph, );
 
@@ -382,11 +319,6 @@ static int scmi_reset_protocol_init(const struct 
scmi_protocol_handle *ph)
}
 
pinfo->version = version;
-
-   /* Transient code for legacy ops interface */
-   handle = scmi_map_scmi_handle(ph);
-   handle->reset_ops = _ops;
-
return ph->set_priv(ph, pinfo);
 }
 
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 58a33d0b6f90..d1a052cc5162 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -483,15 +483,6 @@ struct scmi_reset_proto_ops {
int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain);
 };
 
-struct scmi_reset_ops {
-   int 

[PATCH v4 16/37] firmware: arm_scmi: port GenPD driver to the new scmi_power_proto_ops interface

2021-01-06 Thread Cristian Marussi
Port driver to the new SCMI Power interface based on protocol handles
and common devm_get_ops().

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/scmi_pm_domain.c | 26 +-
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c 
b/drivers/firmware/arm_scmi/scmi_pm_domain.c
index 9e44479f0284..564bb4d56d9a 100644
--- a/drivers/firmware/arm_scmi/scmi_pm_domain.c
+++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c
@@ -2,7 +2,7 @@
 /*
  * SCMI Generic power domain support.
  *
- * Copyright (C) 2018 ARM Ltd.
+ * Copyright (C) 2018-2020 ARM Ltd.
  */
 
 #include 
@@ -11,9 +11,11 @@
 #include 
 #include 
 
+static const struct scmi_power_proto_ops *power_ops;
+
 struct scmi_pm_domain {
struct generic_pm_domain genpd;
-   const struct scmi_handle *handle;
+   const struct scmi_protocol_handle *ph;
const char *name;
u32 domain;
 };
@@ -25,16 +27,15 @@ static int scmi_pd_power(struct generic_pm_domain *domain, 
bool power_on)
int ret;
u32 state, ret_state;
struct scmi_pm_domain *pd = to_scmi_pd(domain);
-   const struct scmi_power_ops *ops = pd->handle->power_ops;
 
if (power_on)
state = SCMI_POWER_STATE_GENERIC_ON;
else
state = SCMI_POWER_STATE_GENERIC_OFF;
 
-   ret = ops->state_set(pd->handle, pd->domain, state);
+   ret = power_ops->state_set(pd->ph, pd->domain, state);
if (!ret)
-   ret = ops->state_get(pd->handle, pd->domain, _state);
+   ret = power_ops->state_get(pd->ph, pd->domain, _state);
if (!ret && state != ret_state)
return -EIO;
 
@@ -60,11 +61,16 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
struct genpd_onecell_data *scmi_pd_data;
struct generic_pm_domain **domains;
const struct scmi_handle *handle = sdev->handle;
+   struct scmi_protocol_handle *ph;
 
-   if (!handle || !handle->power_ops)
+   if (!handle)
return -ENODEV;
 
-   num_domains = handle->power_ops->num_domains_get(handle);
+   power_ops = handle->devm_get_ops(sdev, SCMI_PROTOCOL_POWER, );
+   if (IS_ERR(power_ops))
+   return PTR_ERR(power_ops);
+
+   num_domains = power_ops->num_domains_get(ph);
if (num_domains < 0) {
dev_err(dev, "number of domains not found\n");
return num_domains;
@@ -85,14 +91,14 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
for (i = 0; i < num_domains; i++, scmi_pd++) {
u32 state;
 
-   if (handle->power_ops->state_get(handle, i, )) {
+   if (power_ops->state_get(ph, i, )) {
dev_warn(dev, "failed to get state for domain %d\n", i);
continue;
}
 
scmi_pd->domain = i;
-   scmi_pd->handle = handle;
-   scmi_pd->name = handle->power_ops->name_get(handle, i);
+   scmi_pd->ph = ph;
+   scmi_pd->name = power_ops->name_get(ph, i);
scmi_pd->genpd.name = scmi_pd->name;
scmi_pd->genpd.power_off = scmi_pd_power_off;
scmi_pd->genpd.power_on = scmi_pd_power_on;
-- 
2.17.1



[PATCH v4 19/37] clk: scmi: port driver to the new scmi_clk_proto_ops interface

2021-01-06 Thread Cristian Marussi
Port driver to the new SCMI Clock interface based on protocol handles
and common devm_get_ops().

Signed-off-by: Cristian Marussi 
---
 drivers/clk/clk-scmi.c | 27 +--
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index c754dfbb73fd..9d5e1262673b 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -2,7 +2,7 @@
 /*
  * System Control and Power Interface (SCMI) Protocol based clock driver
  *
- * Copyright (C) 2018 ARM Ltd.
+ * Copyright (C) 2018-2020 ARM Ltd.
  */
 
 #include 
@@ -13,11 +13,13 @@
 #include 
 #include 
 
+static const struct scmi_clk_proto_ops *clk_ops;
+
 struct scmi_clk {
u32 id;
struct clk_hw hw;
const struct scmi_clock_info *info;
-   const struct scmi_handle *handle;
+   const struct scmi_protocol_handle *ph;
 };
 
 #define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
@@ -29,7 +31,7 @@ static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
u64 rate;
struct scmi_clk *clk = to_scmi_clk(hw);
 
-   ret = clk->handle->clk_ops->rate_get(clk->handle, clk->id, );
+   ret = clk_ops->rate_get(clk->ph, clk->id, );
if (ret)
return 0;
return rate;
@@ -69,21 +71,21 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned 
long rate,
 {
struct scmi_clk *clk = to_scmi_clk(hw);
 
-   return clk->handle->clk_ops->rate_set(clk->handle, clk->id, rate);
+   return clk_ops->rate_set(clk->ph, clk->id, rate);
 }
 
 static int scmi_clk_enable(struct clk_hw *hw)
 {
struct scmi_clk *clk = to_scmi_clk(hw);
 
-   return clk->handle->clk_ops->enable(clk->handle, clk->id);
+   return clk_ops->enable(clk->ph, clk->id);
 }
 
 static void scmi_clk_disable(struct clk_hw *hw)
 {
struct scmi_clk *clk = to_scmi_clk(hw);
 
-   clk->handle->clk_ops->disable(clk->handle, clk->id);
+   clk_ops->disable(clk->ph, clk->id);
 }
 
 static const struct clk_ops scmi_clk_ops = {
@@ -142,11 +144,16 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
struct device *dev = >dev;
struct device_node *np = dev->of_node;
const struct scmi_handle *handle = sdev->handle;
+   struct scmi_protocol_handle *ph;
 
-   if (!handle || !handle->clk_ops)
+   if (!handle)
return -ENODEV;
 
-   count = handle->clk_ops->count_get(handle);
+   clk_ops = handle->devm_get_ops(sdev, SCMI_PROTOCOL_CLOCK, );
+   if (IS_ERR(clk_ops))
+   return PTR_ERR(clk_ops);
+
+   count = clk_ops->count_get(ph);
if (count < 0) {
dev_err(dev, "%pOFn: invalid clock output count\n", np);
return -EINVAL;
@@ -167,14 +174,14 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
if (!sclk)
return -ENOMEM;
 
-   sclk->info = handle->clk_ops->info_get(handle, idx);
+   sclk->info = clk_ops->info_get(ph, idx);
if (!sclk->info) {
dev_dbg(dev, "invalid clock info for idx %d\n", idx);
continue;
}
 
sclk->id = idx;
-   sclk->handle = handle;
+   sclk->ph = ph;
 
err = scmi_clk_ops_init(dev, sclk);
if (err) {
-- 
2.17.1



[PATCH v4 12/37] firmware: arm_scmi: port Perf protocol to new protocols interface

2021-01-06 Thread Cristian Marussi
Convert internals of protocol implementation to use protocol handles and
expose a new protocol operations interface for SCMI driver using the new
get/put common operations, while keeping the old handle->perf_ops still
around to ease transition.

Remove handle->perf_priv now unused.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/perf.c | 349 ---
 include/linux/scmi_protocol.h|  30 ++-
 2 files changed, 258 insertions(+), 121 deletions(-)

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index f27a0afbe65a..99144a70ded6 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -175,21 +175,21 @@ static enum scmi_performance_protocol_cmd evt_2_cmd[] = {
PERF_NOTIFY_LEVEL,
 };
 
-static int scmi_perf_attributes_get(const struct scmi_handle *handle,
+static int scmi_perf_attributes_get(const struct scmi_protocol_handle *ph,
struct scmi_perf_info *pi)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_perf_attributes *attr;
 
-   ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
-SCMI_PROTOCOL_PERF, 0, sizeof(*attr), );
+   ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
+ sizeof(*attr), );
if (ret)
return ret;
 
attr = t->rx.buf;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
u16 flags = le16_to_cpu(attr->flags);
 
@@ -200,28 +200,27 @@ static int scmi_perf_attributes_get(const struct 
scmi_handle *handle,
pi->stats_size = le32_to_cpu(attr->stats_size);
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
 static int
-scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
-   struct perf_dom_info *dom_info)
+scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
+   u32 domain, struct perf_dom_info *dom_info)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_perf_domain_attributes *attr;
 
-   ret = scmi_xfer_get_init(handle, PERF_DOMAIN_ATTRIBUTES,
-SCMI_PROTOCOL_PERF, sizeof(domain),
-sizeof(*attr), );
+   ret = ph->xops->xfer_get_init(ph, PERF_DOMAIN_ATTRIBUTES,
+sizeof(domain), sizeof(*attr), );
if (ret)
return ret;
 
put_unaligned_le32(domain, t->tx.buf);
attr = t->rx.buf;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
u32 flags = le32_to_cpu(attr->flags);
 
@@ -245,7 +244,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle 
*handle, u32 domain,
strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
@@ -257,7 +256,7 @@ static int opp_cmp_func(const void *opp1, const void *opp2)
 }
 
 static int
-scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
+scmi_perf_describe_levels_get(const struct scmi_protocol_handle *ph, u32 
domain,
  struct perf_dom_info *perf_dom)
 {
int ret, cnt;
@@ -268,8 +267,8 @@ scmi_perf_describe_levels_get(const struct scmi_handle 
*handle, u32 domain,
struct scmi_msg_perf_describe_levels *dom_info;
struct scmi_msg_resp_perf_describe_levels *level_info;
 
-   ret = scmi_xfer_get_init(handle, PERF_DESCRIBE_LEVELS,
-SCMI_PROTOCOL_PERF, sizeof(*dom_info), 0, );
+   ret = ph->xops->xfer_get_init(ph, PERF_DESCRIBE_LEVELS,
+ sizeof(*dom_info), 0, );
if (ret)
return ret;
 
@@ -281,14 +280,14 @@ scmi_perf_describe_levels_get(const struct scmi_handle 
*handle, u32 domain,
/* Set the number of OPPs to be skipped/already read */
dom_info->level_index = cpu_to_le32(tot_opp_cnt);
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (ret)
break;
 
num_returned = le16_to_cpu(level_info->num_returned);
num_remaining = le16_to_cpu(level_info->num_remaining);
if (tot_opp_cnt + num_returned > MAX_OPPS) {
-   dev_err(handle->dev, "No. of OPPs exceeded MAX_OPPS");
+   dev_err(ph->dev, "No. of OPPs exceeded MAX_OPPS");
break;
}
 
@@ -299,13 +298,13 @@ scmi_perf_describe_levels_get(const struct scmi_handle 
*handle, u32 domain,
opp->trans_latency_us = le16_to_cpu
  

[PATCH v4 11/37] firmware: arm_scmi: port Base protocol to new interface

2021-01-06 Thread Cristian Marussi
Port Base protocol to new protocol handles based interface.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/base.c   | 117 +++--
 drivers/firmware/arm_scmi/common.h |   3 +-
 drivers/firmware/arm_scmi/driver.c |  14 +++-
 3 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index e7c21e925ea2..c9e5e451b377 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -50,30 +50,30 @@ struct scmi_base_error_notify_payld {
  * scmi_base_attributes_get() - gets the implementation details
  * that are associated with the base protocol.
  *
- * @handle: SCMI entity handle
+ * @ph: SCMI protocol handle
  *
  * Return: 0 on success, else appropriate SCMI error.
  */
-static int scmi_base_attributes_get(const struct scmi_handle *handle)
+static int scmi_base_attributes_get(const struct scmi_protocol_handle *ph)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_base_attributes *attr_info;
-   struct scmi_revision_info *rev = handle->version;
+   struct scmi_revision_info *rev = ph->get_priv(ph);
 
-   ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
-SCMI_PROTOCOL_BASE, 0, sizeof(*attr_info), );
+   ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
+ 0, sizeof(*attr_info), );
if (ret)
return ret;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
attr_info = t->rx.buf;
rev->num_protocols = attr_info->num_protocols;
rev->num_agents = attr_info->num_agents;
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
 
return ret;
 }
@@ -81,19 +81,20 @@ static int scmi_base_attributes_get(const struct 
scmi_handle *handle)
 /**
  * scmi_base_vendor_id_get() - gets vendor/subvendor identifier ASCII string.
  *
- * @handle: SCMI entity handle
+ * @ph: SCMI protocol handle
  * @sub_vendor: specify true if sub-vendor ID is needed
  *
  * Return: 0 on success, else appropriate SCMI error.
  */
 static int
-scmi_base_vendor_id_get(const struct scmi_handle *handle, bool sub_vendor)
+scmi_base_vendor_id_get(const struct scmi_protocol_handle *ph, bool sub_vendor)
 {
u8 cmd;
int ret, size;
char *vendor_id;
struct scmi_xfer *t;
-   struct scmi_revision_info *rev = handle->version;
+   struct scmi_revision_info *rev = ph->get_priv(ph);
+
 
if (sub_vendor) {
cmd = BASE_DISCOVER_SUB_VENDOR;
@@ -105,15 +106,15 @@ scmi_base_vendor_id_get(const struct scmi_handle *handle, 
bool sub_vendor)
size = ARRAY_SIZE(rev->vendor_id);
}
 
-   ret = scmi_xfer_get_init(handle, cmd, SCMI_PROTOCOL_BASE, 0, size, );
+   ret = ph->xops->xfer_get_init(ph, cmd, 0, size, );
if (ret)
return ret;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret)
memcpy(vendor_id, t->rx.buf, size);
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
 
return ret;
 }
@@ -123,30 +124,30 @@ scmi_base_vendor_id_get(const struct scmi_handle *handle, 
bool sub_vendor)
  * implementation 32-bit version. The format of the version number is
  * vendor-specific
  *
- * @handle: SCMI entity handle
+ * @ph: SCMI protocol handle
  *
  * Return: 0 on success, else appropriate SCMI error.
  */
 static int
-scmi_base_implementation_version_get(const struct scmi_handle *handle)
+scmi_base_implementation_version_get(const struct scmi_protocol_handle *ph)
 {
int ret;
__le32 *impl_ver;
struct scmi_xfer *t;
-   struct scmi_revision_info *rev = handle->version;
+   struct scmi_revision_info *rev = ph->get_priv(ph);
 
-   ret = scmi_xfer_get_init(handle, BASE_DISCOVER_IMPLEMENT_VERSION,
-SCMI_PROTOCOL_BASE, 0, sizeof(*impl_ver), );
+   ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_IMPLEMENT_VERSION,
+ 0, sizeof(*impl_ver), );
if (ret)
return ret;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
impl_ver = t->rx.buf;
rev->impl_ver = le32_to_cpu(*impl_ver);
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
 
return ret;
 }
@@ -155,23 +156,24 @@ scmi_base_implementation_version_get(const struct 
scmi_handle *handle)
  * scmi_base_implementation_list_get() - gets the list of protocols it is
  * OSPM is allowed to access
  *
- * @handle: SCMI entity handle
+ * @ph: SCMI protocol handle
  * @protocols_imp: pointer to hold the list of protocol identifiers
  *
  * Return: 0 on success, else appropriate SCMI error.
  

[PATCH v4 13/37] cpufreq: scmi: port driver to the new scmi_perf_proto_ops interface

2021-01-06 Thread Cristian Marussi
Port driver to the new SCMI Perf interface based on protocol handles
and common devm_get_ops().

Signed-off-by: Cristian Marussi 
---
 drivers/cpufreq/scmi-cpufreq.c | 37 ++
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 491a0a24fb1e..520ecd03bf3e 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -25,17 +25,17 @@ struct scmi_data {
struct device *cpu_dev;
 };
 
-static const struct scmi_handle *handle;
+static struct scmi_protocol_handle *ph;
+static const struct scmi_perf_proto_ops *perf_ops;
 
 static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
 {
struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
-   const struct scmi_perf_ops *perf_ops = handle->perf_ops;
struct scmi_data *priv = policy->driver_data;
unsigned long rate;
int ret;
 
-   ret = perf_ops->freq_get(handle, priv->domain_id, , false);
+   ret = perf_ops->freq_get(ph, priv->domain_id, , false);
if (ret)
return 0;
return rate / 1000;
@@ -50,19 +50,17 @@ static int
 scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
 {
struct scmi_data *priv = policy->driver_data;
-   const struct scmi_perf_ops *perf_ops = handle->perf_ops;
u64 freq = policy->freq_table[index].frequency;
 
-   return perf_ops->freq_set(handle, priv->domain_id, freq * 1000, false);
+   return perf_ops->freq_set(ph, priv->domain_id, freq * 1000, false);
 }
 
 static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
 unsigned int target_freq)
 {
struct scmi_data *priv = policy->driver_data;
-   const struct scmi_perf_ops *perf_ops = handle->perf_ops;
 
-   if (!perf_ops->freq_set(handle, priv->domain_id,
+   if (!perf_ops->freq_set(ph, priv->domain_id,
target_freq * 1000, true))
return target_freq;
 
@@ -75,7 +73,7 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask 
*cpumask)
int cpu, domain, tdomain;
struct device *tcpu_dev;
 
-   domain = handle->perf_ops->device_domain_id(cpu_dev);
+   domain = perf_ops->device_domain_id(cpu_dev);
if (domain < 0)
return domain;
 
@@ -87,7 +85,7 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask 
*cpumask)
if (!tcpu_dev)
continue;
 
-   tdomain = handle->perf_ops->device_domain_id(tcpu_dev);
+   tdomain = perf_ops->device_domain_id(tcpu_dev);
if (tdomain == domain)
cpumask_set_cpu(cpu, cpumask);
}
@@ -102,13 +100,13 @@ scmi_get_cpu_power(unsigned long *power, unsigned long 
*KHz,
unsigned long Hz;
int ret, domain;
 
-   domain = handle->perf_ops->device_domain_id(cpu_dev);
+   domain = perf_ops->device_domain_id(cpu_dev);
if (domain < 0)
return domain;
 
/* Get the power cost of the performance domain. */
Hz = *KHz * 1000;
-   ret = handle->perf_ops->est_power_get(handle, domain, , power);
+   ret = perf_ops->est_power_get(ph, domain, , power);
if (ret)
return ret;
 
@@ -134,7 +132,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
return -ENODEV;
}
 
-   ret = handle->perf_ops->device_opps_add(handle, cpu_dev);
+   ret = perf_ops->device_opps_add(ph, cpu_dev);
if (ret) {
dev_warn(cpu_dev, "failed to add opps to the device\n");
return ret;
@@ -173,7 +171,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
}
 
priv->cpu_dev = cpu_dev;
-   priv->domain_id = handle->perf_ops->device_domain_id(cpu_dev);
+   priv->domain_id = perf_ops->device_domain_id(cpu_dev);
 
policy->driver_data = priv;
policy->freq_table = freq_table;
@@ -181,16 +179,16 @@ static int scmi_cpufreq_init(struct cpufreq_policy 
*policy)
/* SCMI allows DVFS request for any domain from any CPU */
policy->dvfs_possible_from_any_cpu = true;
 
-   latency = handle->perf_ops->transition_latency_get(handle, cpu_dev);
+   latency = perf_ops->transition_latency_get(ph, cpu_dev);
if (!latency)
latency = CPUFREQ_ETERNAL;
 
policy->cpuinfo.transition_latency = latency;
 
policy->fast_switch_possible =
-   handle->perf_ops->fast_switch_possible(handle, cpu_dev);
+   perf_ops->fast_switch_possible(ph, cpu_dev);
 
-   power_scale_mw = handle->perf_ops->power_scale_mw_get(handle);
+   power_scale_mw = perf_ops->power_scale_mw_get(ph);
em_dev_register_perf_domain(cpu_dev, nr_opp, _cb, policy->cpus,
power_scale_mw);
 
@@ 

[PATCH v4 09/37] firmware: arm_scmi: add new protocol handle core xfer ops

2021-01-06 Thread Cristian Marussi
Add new core SCMI xfer operations based on protocol handles to enable
protocols to builds and send their own protocol specific messages.

Keep old original scmi_xfer_ operations interface as wrappers around the
new interface in order to let coexist old and new interfaces to ease
protocol by protocol migration.

In order to support such migration the above wrappers and some additional
transient code is also introduced in this commit: it will be later removed
as a whole once the full migration of protocols and SCMI drivers will have
been completed.

Signed-off-by: Cristian Marussi 
---
An exmaple of transient code:

scmi_map_protocol_handle() / scmi_map_scmi_handle()

and their usage will removed later on together with all the scmi_xfer
wrappers.
---
 drivers/firmware/arm_scmi/common.h |  12 +-
 drivers/firmware/arm_scmi/driver.c | 182 +++--
 2 files changed, 158 insertions(+), 36 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h 
b/drivers/firmware/arm_scmi/common.h
index 218a389f87b5..10ac5a6daf10 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -19,6 +19,8 @@
 
 #include 
 
+#include "notify.h"
+
 #define PROTOCOL_REV_MINOR_MASKGENMASK(15, 0)
 #define PROTOCOL_REV_MAJOR_MASKGENMASK(31, 16)
 #define PROTOCOL_REV_MAJOR(x)  (u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))
@@ -179,6 +181,11 @@ struct scmi_protocol_handle {
void *(*get_priv)(const struct scmi_protocol_handle *ph);
 };
 
+const struct scmi_protocol_handle *
+scmi_map_protocol_handle(const struct scmi_handle *handle, u8 prot_id);
+
+struct scmi_handle *scmi_map_scmi_handle(const struct scmi_protocol_handle 
*ph);
+
 /**
  * struct scmi_xfer_ops  - References to the core SCMI xfer operations.
  * @version_get: Get this version protocol.
@@ -217,6 +224,7 @@ void scmi_setup_protocol_implemented(const struct 
scmi_handle *handle,
 
 int scmi_base_protocol_init(struct scmi_handle *h);
 typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *);
+typedef int (*scmi_prot_init_ph_fn_t)(const struct scmi_protocol_handle *);
 
 /**
  * struct scmi_protocol  - Protocol descriptor
@@ -231,8 +239,8 @@ typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *);
 struct scmi_protocol {
const u8id;
const scmi_prot_init_fn_t   init;
-   const scmi_prot_init_fn_t   init_instance;
-   const scmi_prot_init_fn_t   deinit_instance;
+   const scmi_prot_init_ph_fn_tinit_instance;
+   const scmi_prot_init_ph_fn_tdeinit_instance;
const void  *ops;
const struct scmi_protocol_events   *events;
 };
diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index da0620318cab..d1357640bf07 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -349,19 +349,54 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 
msg_hdr)
}
 }
 
+/* Transient code wrapper to ease API migration */
+const struct scmi_protocol_handle *
+scmi_map_protocol_handle(const struct scmi_handle *handle, u8 prot_id)
+{
+   struct scmi_info *info = handle_to_scmi_info(handle);
+   const struct scmi_protocol_instance *pi;
+
+   mutex_lock(>protocols_mtx);
+   pi = idr_find(>protocols, prot_id);
+   mutex_unlock(>protocols_mtx);
+
+   return pi ? >ph : NULL;
+}
+
+/* Transient code wrapper to ease API migration */
+struct scmi_handle *scmi_map_scmi_handle(const struct scmi_protocol_handle *ph)
+{
+   const struct scmi_protocol_instance *pi = ph_to_pi(ph);
+
+   return (struct scmi_handle *)pi->handle;
+}
+
 /**
- * scmi_xfer_put() - Release a transmit message
+ * xfer_put() - Release a transmit message
  *
- * @handle: Pointer to SCMI entity handle
+ * @ph: Pointer to SCMI protocol handle
  * @xfer: message that was reserved by scmi_xfer_get
  */
-void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+static void xfer_put(const struct scmi_protocol_handle *ph,
+struct scmi_xfer *xfer)
 {
-   struct scmi_info *info = handle_to_scmi_info(handle);
+   const struct scmi_protocol_instance *pi = ph_to_pi(ph);
+   struct scmi_info *info = handle_to_scmi_info(pi->handle);
 
__scmi_xfer_put(>tx_minfo, xfer);
 }
 
+void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer)
+{
+   const struct scmi_protocol_handle *ph;
+
+   ph = scmi_map_protocol_handle(h, xfer->hdr.protocol_id);
+   if (!ph)
+   return;
+
+   return xfer_put(ph, xfer);
+}
+
 #define SCMI_MAX_POLL_TO_NS(100 * NSEC_PER_USEC)
 
 static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
@@ -374,23 +409,32 @@ static bool scmi_xfer_done_no_timeout(struct 
scmi_chan_info *cinfo,
 }
 
 /**
- * scmi_do_xfer() - Do one transfer
+ * do_xfer() - Do one transfer
  *
- * 

[PATCH v4 15/37] firmware: arm_scmi: port Power protocol to new protocols interface

2021-01-06 Thread Cristian Marussi
Convert internals of protocol implementation to use protocol handles and
expose a new protocol operations interface for SCMI driver using the new
get/put common operations, while keeping the old handle->power_ops still
around to ease transition.

Remove handle->power_priv now unused.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/power.c | 141 +++---
 include/linux/scmi_protocol.h |  20 +++--
 2 files changed, 105 insertions(+), 56 deletions(-)

diff --git a/drivers/firmware/arm_scmi/power.c 
b/drivers/firmware/arm_scmi/power.c
index e4c084ca92e4..b3d1c032218c 100644
--- a/drivers/firmware/arm_scmi/power.c
+++ b/drivers/firmware/arm_scmi/power.c
@@ -68,21 +68,21 @@ struct scmi_power_info {
struct power_dom_info *dom_info;
 };
 
-static int scmi_power_attributes_get(const struct scmi_handle *handle,
+static int scmi_power_attributes_get(const struct scmi_protocol_handle *ph,
 struct scmi_power_info *pi)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_power_attributes *attr;
 
-   ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
-SCMI_PROTOCOL_POWER, 0, sizeof(*attr), );
+   ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
+ 0, sizeof(*attr), );
if (ret)
return ret;
 
attr = t->rx.buf;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
pi->num_domains = le16_to_cpu(attr->num_domains);
pi->stats_addr = le32_to_cpu(attr->stats_addr_low) |
@@ -90,28 +90,27 @@ static int scmi_power_attributes_get(const struct 
scmi_handle *handle,
pi->stats_size = le32_to_cpu(attr->stats_size);
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
 static int
-scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
-struct power_dom_info *dom_info)
+scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph,
+u32 domain, struct power_dom_info *dom_info)
 {
int ret;
struct scmi_xfer *t;
struct scmi_msg_resp_power_domain_attributes *attr;
 
-   ret = scmi_xfer_get_init(handle, POWER_DOMAIN_ATTRIBUTES,
-SCMI_PROTOCOL_POWER, sizeof(domain),
-sizeof(*attr), );
+   ret = ph->xops->xfer_get_init(ph, POWER_DOMAIN_ATTRIBUTES,
+ sizeof(domain), sizeof(*attr), );
if (ret)
return ret;
 
put_unaligned_le32(domain, t->tx.buf);
attr = t->rx.buf;
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
if (!ret) {
u32 flags = le32_to_cpu(attr->flags);
 
@@ -121,19 +120,18 @@ scmi_power_domain_attributes_get(const struct scmi_handle 
*handle, u32 domain,
strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
}
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
-static int
-scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state)
+static int scmi_power_state_set(const struct scmi_protocol_handle *ph,
+   u32 domain, u32 state)
 {
int ret;
struct scmi_xfer *t;
struct scmi_power_set_state *st;
 
-   ret = scmi_xfer_get_init(handle, POWER_STATE_SET, SCMI_PROTOCOL_POWER,
-sizeof(*st), 0, );
+   ret = ph->xops->xfer_get_init(ph, POWER_STATE_SET, sizeof(*st), 0, );
if (ret)
return ret;
 
@@ -142,64 +140,106 @@ scmi_power_state_set(const struct scmi_handle *handle, 
u32 domain, u32 state)
st->domain = cpu_to_le32(domain);
st->state = cpu_to_le32(state);
 
-   ret = scmi_do_xfer(handle, t);
+   ret = ph->xops->do_xfer(ph, t);
 
-   scmi_xfer_put(handle, t);
+   ph->xops->xfer_put(ph, t);
return ret;
 }
 
-static int
-scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state)
+static int __scmi_power_state_set(const struct scmi_handle *handle,
+ u32 domain, u32 state)
+{
+   const struct scmi_protocol_handle *ph =
+   scmi_map_protocol_handle(handle, SCMI_PROTOCOL_POWER);
+
+   return scmi_power_state_set(ph, domain, state);
+}
+
+static int scmi_power_state_get(const struct scmi_protocol_handle *ph,
+   u32 domain, u32 *state)
 {
int ret;
struct scmi_xfer *t;
 
-   ret = scmi_xfer_get_init(handle, POWER_STATE_GET, SCMI_PROTOCOL_POWER,
-sizeof(u32), sizeof(u32), );
+   ret = ph->xops->xfer_get_init(ph, POWER_STATE_GET, sizeof(u32), 
sizeof(u32), );
if (ret)

[PATCH v4 08/37] firmware: arm_scmi: convert events registration to protocol handles

2021-01-06 Thread Cristian Marussi
Convert refactored events registration routines to use protocol handles.

In order to maintain bisectability and to allow protocols and drivers
to be later ported to the new protocol handle interface one by one,
introduce here also some transient code and typing that will be removed
later in order to ease such transition.

Signed-off-by: Cristian Marussi 
---
In particular void* argument typing will be reverted later on once all
the protocols have been ported.
---
 drivers/firmware/arm_scmi/base.c|  4 ++--
 drivers/firmware/arm_scmi/driver.c  |  1 +
 drivers/firmware/arm_scmi/notify.c  | 13 +
 drivers/firmware/arm_scmi/notify.h  |  7 ---
 drivers/firmware/arm_scmi/perf.c|  9 +
 drivers/firmware/arm_scmi/power.c   |  9 +
 drivers/firmware/arm_scmi/reset.c   |  9 +
 drivers/firmware/arm_scmi/sensors.c | 12 +++-
 drivers/firmware/arm_scmi/system.c  |  4 ++--
 9 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index 2fe76827e627..e7c21e925ea2 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -262,7 +262,7 @@ static int scmi_base_error_notify(const struct scmi_handle 
*handle, bool enable)
return ret;
 }
 
-static int scmi_base_set_notify_enabled(const struct scmi_handle *handle,
+static int scmi_base_set_notify_enabled(const void *handle,
u8 evt_id, u32 src_id, bool enable)
 {
int ret;
@@ -274,7 +274,7 @@ static int scmi_base_set_notify_enabled(const struct 
scmi_handle *handle,
return ret;
 }
 
-static void *scmi_base_fill_custom_report(const struct scmi_handle *handle,
+static void *scmi_base_fill_custom_report(const void *handle,
  u8 evt_id, ktime_t timestamp,
  const void *payld, size_t payld_sz,
  void *report, u32 *src_id)
diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index 2740c28928c7..da0620318cab 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -647,6 +647,7 @@ scmi_get_protocol_instance(struct scmi_handle *handle, u8 
protocol_id)
 
if (pi->proto->events)
scmi_register_protocol_events(handle, pi->proto->id,
+ >ph,
  pi->proto->events);
 
devres_close_group(handle->dev, pi->gid);
diff --git a/drivers/firmware/arm_scmi/notify.c 
b/drivers/firmware/arm_scmi/notify.c
index 8b4af3847bfa..d88bc9960c7c 100644
--- a/drivers/firmware/arm_scmi/notify.c
+++ b/drivers/firmware/arm_scmi/notify.c
@@ -178,7 +178,7 @@
 #define REVT_NOTIFY_SET_STATUS(revt, eid, sid, state)  \
 ({ \
typeof(revt) r = revt;  \
-   r->proto->ops->set_notify_enabled(r->proto->ni->handle, \
+   r->proto->ops->set_notify_enabled(r->proto->ph, \
(eid), (sid), (state)); \
 })
 
@@ -191,7 +191,7 @@
 #define REVT_FILL_REPORT(revt, ...)\
 ({ \
typeof(revt) r = revt;  \
-   r->proto->ops->fill_custom_report(r->proto->ni->handle, \
+   r->proto->ops->fill_custom_report(r->proto->ph, \
  __VA_ARGS__); \
 })
 
@@ -279,6 +279,7 @@ struct scmi_registered_event;
  *events' descriptors, whose fixed-size is determined at
  *compile time.
  * @registered_mtx: A mutex to protect @registered_events_handlers
+ * @ph: SCMI protocol handle reference
  * @registered_events_handlers: An hashtable containing all events' handlers
  * descriptors registered for this protocol
  *
@@ -303,6 +304,7 @@ struct scmi_registered_events_desc {
struct scmi_registered_event**registered_events;
/* mutex to protect registered_events_handlers */
struct mutexregistered_mtx;
+   const struct scmi_protocol_handle   *ph;
DECLARE_HASHTABLE(registered_events_handlers, SCMI_REGISTERED_HASH_SZ);
 };
 
@@ -735,6 +737,7 @@ scmi_allocate_registered_events_desc(struct 
scmi_notify_instance *ni,
  * @handle: The handle identifying the platform instance against which the
  * protocol's events are registered
  * @proto_id: Protocol ID
+ * @ph: SCMI protocol handle.
  * @ee: A structure describing the events supported by this protocol.
  *
  * Used by SCMI Protocols initialization code to register with the notification
@@ -745,6 +748,7 @@ scmi_allocate_registered_events_desc(struct 
scmi_notify_instance *ni,
  * 

[PATCH v4 10/37] firmware: arm_scmi: add helper to access revision area memory

2021-01-06 Thread Cristian Marussi
Add an helper to grab, from a protocol handle, the handle common memory
area allocated to store SCMI version data which is exposed on sysfs.
Such helper will be needed by SCMI Base protocol initialization once it
will be moved to new protocol handles scheme.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/common.h |  2 ++
 drivers/firmware/arm_scmi/driver.c | 19 +++
 2 files changed, 21 insertions(+)

diff --git a/drivers/firmware/arm_scmi/common.h 
b/drivers/firmware/arm_scmi/common.h
index 10ac5a6daf10..428bfba40dfd 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -215,6 +215,8 @@ struct scmi_xfer_ops {
 struct scmi_xfer *xfer);
 };
 
+struct scmi_revision_info *
+scmi_get_revision_area(const struct scmi_protocol_handle *ph);
 int scmi_handle_put(const struct scmi_handle *handle);
 struct scmi_handle *scmi_handle_get(struct device *dev);
 void scmi_set_handle(struct scmi_device *scmi_dev);
diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index d1357640bf07..b936cf47cd7d 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -698,6 +698,25 @@ static const struct scmi_xfer_ops xfer_ops = {
.xfer_put = xfer_put,
 };
 
+/**
+ * scmi_get_revision_area  - Retrieve version memory area.
+ *
+ * @ph: A reference to the protocol handle.
+ *
+ * A helper to grab the version memory area reference during SCMI Base protocol
+ * initialization.
+ *
+ * Return: A reference to the version memory area associated to the SCMI
+ *instance underlying this protocol handle.
+ */
+struct scmi_revision_info *
+scmi_get_revision_area(const struct scmi_protocol_handle *ph)
+{
+   const struct scmi_protocol_instance *pi = ph_to_pi(ph);
+
+   return pi->handle->version;
+}
+
 /**
  * scmi_get_protocol_instance  - Protocol initialization helper.
  * @handle: A reference to the SCMI platform instance.
-- 
2.17.1



[PATCH v4 06/37] firmware: arm_scmi: introduce new devres notification ops

2021-01-06 Thread Cristian Marussi
Expose to the SCMI drivers a new alternative devres managed notifications
API based on protocol handles.

All drivers still keep using the old API, no functional change.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/notify.c | 123 +
 include/linux/scmi_protocol.h  |  15 +++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/notify.c 
b/drivers/firmware/arm_scmi/notify.c
index cdaf0f962d84..70e8eb4e33c6 100644
--- a/drivers/firmware/arm_scmi/notify.c
+++ b/drivers/firmware/arm_scmi/notify.c
@@ -1408,6 +1408,127 @@ static int scmi_unregister_notifier(const struct 
scmi_handle *handle,
return 0;
 }
 
+struct scmi_notifier_devres {
+   const struct scmi_handle *handle;
+   u8 proto_id;
+   u8 evt_id;
+   u32 __src_id;
+   u32 *src_id;
+   struct notifier_block *nb;
+};
+
+static void scmi_devm_release_notifier(struct device *dev, void *res)
+{
+   struct scmi_notifier_devres *dres = res;
+
+   scmi_unregister_notifier(dres->handle, dres->proto_id, dres->evt_id,
+dres->src_id, dres->nb);
+}
+
+/**
+ * scmi_devm_register_notifier()  - Managed registration of a notifier_block
+ * for an event
+ * @sdev: A reference to an scmi_device whose embedded struct device is to
+ *   be used for devres accounting.
+ * @proto_id: Protocol ID
+ * @evt_id: Event ID
+ * @src_id: Source ID, when NULL register for events coming form ALL possible
+ * sources
+ * @nb: A standard notifier block to register for the specified event
+ *
+ * Generic devres managed helper to register a notifier_block against a
+ * protocol event.
+ */
+static int scmi_devm_register_notifier(struct scmi_device *sdev,
+  u8 proto_id, u8 evt_id, u32 *src_id,
+  struct notifier_block *nb)
+{
+   int ret;
+   struct scmi_notifier_devres *dres;
+
+   dres = devres_alloc(scmi_devm_release_notifier,
+   sizeof(*dres), GFP_KERNEL);
+   if (!dres)
+   return -ENOMEM;
+
+   ret = scmi_register_notifier(sdev->handle, proto_id,
+evt_id, src_id, nb);
+   if (ret) {
+   devres_free(dres);
+   return ret;
+   }
+
+   dres->handle = sdev->handle;
+   dres->proto_id = proto_id;
+   dres->evt_id = evt_id;
+   dres->nb = nb;
+   if (src_id) {
+   dres->__src_id = *src_id;
+   dres->src_id = >__src_id;
+   } else {
+   dres->src_id = NULL;
+   }
+   devres_add(>dev, dres);
+
+   return ret;
+}
+
+static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
+{
+   struct scmi_notifier_devres *dres = res;
+   struct scmi_notifier_devres *xres = data;
+
+   if (WARN_ON(!dres || !xres))
+   return 0;
+
+   return dres->proto_id == xres->proto_id &&
+   dres->evt_id == xres->evt_id &&
+   dres->nb == xres->nb &&
+   ((!dres->src_id && !xres->src_id) ||
+ (dres->src_id && xres->src_id &&
+  dres->__src_id == xres->__src_id));
+}
+
+/**
+ * scmi_devm_unregister_notifier()  - Managed un-registration of a
+ * notifier_block for an event
+ * @sdev: A reference to an scmi_device whose embedded struct device is to
+ *   be used for devres accounting.
+ * @proto_id: Protocol ID
+ * @evt_id: Event ID
+ * @src_id: Source ID, when NULL register for events coming form ALL possible
+ * sources
+ * @nb: A standard notifier block to register for the specified event
+ *
+ * Generic devres managed helper to explicitly un-register a notifier_block
+ * against a protocol event, which was previously registered using the above
+ * @scmi_devm_register_notifier.
+ */
+static int scmi_devm_unregister_notifier(struct scmi_device *sdev,
+u8 proto_id, u8 evt_id, u32 *src_id,
+struct notifier_block *nb)
+{
+   int ret;
+   struct scmi_notifier_devres dres;
+
+   dres.handle = sdev->handle;
+   dres.proto_id = proto_id;
+   dres.evt_id = evt_id;
+   if (src_id) {
+   dres.__src_id = *src_id;
+   dres.src_id = __src_id;
+   } else {
+   dres.src_id = NULL;
+   }
+
+   ret = devres_release(>dev, scmi_devm_release_notifier,
+scmi_devm_notifier_match, );
+
+   WARN_ON(ret);
+
+   return ret;
+}
+
 /**
  * scmi_protocols_late_init()  - Worker for late initialization
  * @work: The work item to use associated to the proper SCMI instance
@@ -1465,6 +1586,8 @@ static void scmi_protocols_late_init(struct work_struct 
*work)
  * directly from an scmi_driver to register its own notifiers.
  */
 static const struct scmi_notify_ops notify_ops = {
+   

[PATCH v4 02/37] firmware: arm_scmi: introduce protocol handle definitions

2021-01-06 Thread Cristian Marussi
Add basic protocol handles definitions and private data helpers support.

A protocol handle identifies a protocol instance initialized against a
specific handle; it embeds all the references to the core SCMI xfer methods
that will be needed by a protocol implementation to build and send its own
protocol specific messages using common core methods.

As such, in the interface, a protocol handle will be passed down from the
core to the protocol specific initialization callback at init time.

Anyway at this point only definitions are introduced, all protocols
initialization code and SCMI drivers probing is still based on the old
interface, so no functional change.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/common.h | 59 ++
 drivers/firmware/arm_scmi/driver.c | 45 +++
 2 files changed, 104 insertions(+)

diff --git a/drivers/firmware/arm_scmi/common.h 
b/drivers/firmware/arm_scmi/common.h
index e052507dc918..977e31224efe 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -149,6 +149,65 @@ int scmi_xfer_get_init(const struct scmi_handle *h, u8 
msg_id, u8 prot_id,
   size_t tx_size, size_t rx_size, struct scmi_xfer **p);
 void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
struct scmi_xfer *xfer);
+
+struct scmi_xfer_ops;
+
+/**
+ * struct scmi_protocol_handle  - Reference to an initialized protocol instance
+ *
+ * @dev: A reference to the associated SCMI instance device (handle->dev).
+ * @xops: A reference to a struct holding refs to the core xfer operations that
+ *   can be used by the protocol implementation to generate SCMI messages.
+ * @set_priv: A method to set protocol private data for this instance.
+ * @get_priv: A method to get protocol private data previously set.
+ *
+ * This structure represents a protocol initialized against specific SCMI
+ * instance and it will be used as follows:
+ * - as a parameter fed from the core to the protocol initialization code so
+ *   that it can access the core xfer operations to build and generate SCMI
+ *   messages exclusively for the specific underlying protocol instance.
+ * - as an opaque handle fed by an SCMI driver user when it tries to access
+ *   this protocol through its own protocol operations.
+ *   In this case this handle will be returned as an opaque object together
+ *   with the related protocol operations when the SCMI driver tries to access
+ *   the protocol.
+ */
+struct scmi_protocol_handle {
+   struct device *dev;
+   const struct scmi_xfer_ops *xops;
+   int (*set_priv)(const struct scmi_protocol_handle *ph, void *priv);
+   void *(*get_priv)(const struct scmi_protocol_handle *ph);
+};
+
+/**
+ * struct scmi_xfer_ops  - References to the core SCMI xfer operations.
+ * @version_get: Get this version protocol.
+ * @xfer_get_init: Initialize one struct xfer if any xfer slot is free.
+ * @reset_rx_to_maxsz: Reset rx size to max transport size.
+ * @do_xfer: Do the SCMI transfer.
+ * @do_xfer_with_response: Do the SCMI transfer waiting for a response.
+ * @xfer_put: Free the xfer slot.
+ *
+ * Note that all this operations expect a protocol handle as first parameter;
+ * they then internally use it to infer the underlying protocol number: this
+ * way is not possible for a protocol implementation to forge messages for
+ * another protocol.
+ */
+struct scmi_xfer_ops {
+   int (*version_get)(const struct scmi_protocol_handle *ph, u32 *version);
+   int (*xfer_get_init)(const struct scmi_protocol_handle *ph, u8 msg_id,
+size_t tx_size, size_t rx_size,
+struct scmi_xfer **p);
+   void (*reset_rx_to_maxsz)(const struct scmi_protocol_handle *ph,
+ struct scmi_xfer *xfer);
+   int (*do_xfer)(const struct scmi_protocol_handle *ph,
+  struct scmi_xfer *xfer);
+   int (*do_xfer_with_response)(const struct scmi_protocol_handle *ph,
+struct scmi_xfer *xfer);
+   void (*xfer_put)(const struct scmi_protocol_handle *ph,
+struct scmi_xfer *xfer);
+};
+
 int scmi_handle_put(const struct scmi_handle *handle);
 struct scmi_handle *scmi_handle_get(struct device *dev);
 void scmi_set_handle(struct scmi_device *scmi_dev);
diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index 48059a4406df..10fe9aacae1b 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -72,19 +72,28 @@ struct scmi_xfers_info {
 
 /**
  * struct scmi_protocol_instance  - Describe an initialized protocol instance.
+ * @handle: Reference to the SCMI handle associated to this protocol instance.
  * @proto: A reference to the protocol descriptor.
  * @gid: A reference for per-protocol devres management.
  * @users: A refcount to track effective 

[PATCH v4 04/37] [RFC] firmware: arm_scmi: introduce bare get/put protocols ops

2021-01-06 Thread Cristian Marussi
Expose to the SCMI drivers a non managed version of a common protocols API
based on generic get/put methods and protocol handles.

All drivers still keep using the old API, no functional change.

Signed-off-by: Cristian Marussi 
---
These non devres methods are probably not needed, given the devm_ ones are
already provided and any SCMI driver (user of the API) has surely available
an scmi_device reference to use in the devm_ flavour...so the RFC
---
 drivers/firmware/arm_scmi/driver.c | 34 ++
 include/linux/scmi_protocol.h  |  8 +++
 2 files changed, 42 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index fbc3ba1b69f6..e6e760501587 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -710,6 +710,38 @@ void scmi_release_protocol(struct scmi_handle *handle, u8 
protocol_id)
mutex_unlock(>protocols_mtx);
 }
 
+/**
+ * scmi_get_protocol_operations  - Get protocol operations
+ * @handle: A reference to the SCMI platform instance.
+ * @protocol_id: The protocol being requested.
+ * @ph: A pointer reference used to pass back the associated protocol handle.
+ *
+ * Get hold of a protocol accounting for its usage, eventually triggering its
+ * initialization, and returning the protocol specific operations and related
+ * protocol handle which will be used as first argument in most of the 
protocols
+ * operations methods.
+ *
+ * Return: A reference to the requested protocol operations or error.
+ *Must be checked for errors by caller.
+ */
+static const void __must_check *
+scmi_get_protocol_operations(struct scmi_handle *handle, u8 protocol_id,
+struct scmi_protocol_handle **ph)
+{
+   struct scmi_protocol_instance *pi;
+
+   if (!ph)
+   return ERR_PTR(-EINVAL);
+
+   pi = scmi_get_protocol_instance(handle, protocol_id);
+   if (IS_ERR(pi))
+   return pi;
+
+   *ph = >ph;
+
+   return pi->proto->ops;
+}
+
 void scmi_setup_protocol_implemented(const struct scmi_handle *handle,
 u8 *prot_imp)
 {
@@ -1078,6 +1110,8 @@ static int scmi_probe(struct platform_device *pdev)
handle->version = >version;
handle->devm_get_ops = scmi_devm_get_protocol_ops;
handle->devm_put_ops = scmi_devm_put_protocol_ops;
+   handle->get_ops = scmi_get_protocol_operations;
+   handle->put_ops = scmi_release_protocol;
 
ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
if (ret)
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 2fd2fffb4024..8a2bb723602f 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -598,6 +598,9 @@ struct scmi_notify_ops {
  * @devm_get_ops: devres managed method to acquire a protocol and get specific
  *   operations and a dedicated protocol handler
  * @devm_put_ops: devres managed method to release a protocol
+ * @get_ops: method to acquire a protocol and get specific operations and a
+ *  dedicated protocol handler
+ * @put_ops: method to release a protocol
  * @notify_ops: pointer to set of notifications related operations
  * @perf_priv: pointer to private data structure specific to performance
  * protocol(for internal use only)
@@ -629,6 +632,11 @@ struct scmi_handle {
struct scmi_protocol_handle **ph);
void (*devm_put_ops)(struct scmi_device *sdev, u8 proto);
 
+   const void __must_check *
+   (*get_ops)(struct scmi_handle *handle, u8 proto,
+  struct scmi_protocol_handle **ph);
+   void (*put_ops)(struct scmi_handle *handle, u8 proto);
+
const struct scmi_notify_ops *notify_ops;
/* for protocol internal use */
void *perf_priv;
-- 
2.17.1



[PATCH v4 03/37] firmware: arm_scmi: introduce devres get/put protocols operations

2021-01-06 Thread Cristian Marussi
Expose to the SCMI drivers a new devres managed common protocols API based
on generic get/put methods and protocol handles.

All drivers still keep using the old API, no functional change.

Signed-off-by: Cristian Marussi 
---
 drivers/firmware/arm_scmi/driver.c | 92 ++
 include/linux/scmi_protocol.h  | 11 
 2 files changed, 103 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index 10fe9aacae1b..fbc3ba1b69f6 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -15,6 +15,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -732,6 +733,95 @@ scmi_is_protocol_implemented(const struct scmi_handle 
*handle, u8 prot_id)
return false;
 }
 
+struct scmi_protocol_devres {
+   struct scmi_handle *handle;
+   u8 protocol_id;
+};
+
+static void scmi_devm_release_protocol(struct device *dev, void *res)
+{
+   struct scmi_protocol_devres *dres = res;
+
+   scmi_release_protocol(dres->handle, dres->protocol_id);
+}
+
+/**
+ * scmi_devm_get_protocol_ops  - Devres managed get protocol operations
+ * @sdev: A reference to an scmi_device whose embedded struct device is to
+ *   be used for devres accounting.
+ * @protocol_id: The protocol being requested.
+ * @ph: A pointer reference used to pass back the associated protocol handle.
+ *
+ * Get hold of a protocol accounting for its usage, eventually triggering its
+ * initialization, and returning the protocol specific operations and related
+ * protocol handle which will be used as first argument in most of the
+ * protocols operations methods.
+ * Being a devres based managed method, protocol hold will be automatically
+ * released, and possibly de-initialized on last user, once the SCMI driver
+ * owning the scmi_device is unbound from it.
+ *
+ * Return: A reference to the requested protocol operations or error.
+ *Must be checked for errors by caller.
+ */
+static const void __must_check *
+scmi_devm_get_protocol_ops(struct scmi_device *sdev, u8 protocol_id,
+  struct scmi_protocol_handle **ph)
+{
+   struct scmi_protocol_instance *pi;
+   struct scmi_protocol_devres *dres;
+   struct scmi_handle *handle = sdev->handle;
+
+   if (!ph)
+   return ERR_PTR(-EINVAL);
+
+   dres = devres_alloc(scmi_devm_release_protocol,
+   sizeof(*dres), GFP_KERNEL);
+   if (!dres)
+   return ERR_PTR(-ENOMEM);
+
+   pi = scmi_get_protocol_instance(handle, protocol_id);
+   if (IS_ERR(pi)) {
+   devres_free(dres);
+   return pi;
+   }
+
+   dres->handle = handle;
+   dres->protocol_id = protocol_id;
+   devres_add(>dev, dres);
+
+   *ph = >ph;
+
+   return pi->proto->ops;
+}
+
+static int scmi_devm_protocol_match(struct device *dev, void *res, void *data)
+{
+   struct scmi_protocol_devres *dres = res;
+
+   if (WARN_ON(!dres || !data))
+   return 0;
+
+   return dres->protocol_id == *((u8 *)data);
+}
+
+/**
+ * scmi_devm_put_protocol_ops  - Devres managed put protocol operations
+ * @sdev: A reference to an scmi_device whose embedded struct device is to
+ *   be used for devres accounting.
+ * @protocol_id: The protocol being requested.
+ *
+ * Explicitly release a protocol hold previously obtained calling the above
+ * @scmi_devm_get_protocol_ops.
+ */
+static void scmi_devm_put_protocol_ops(struct scmi_device *sdev, u8 
protocol_id)
+{
+   int ret;
+
+   ret = devres_release(>dev, scmi_devm_release_protocol,
+scmi_devm_protocol_match, _id);
+   WARN_ON(ret);
+}
+
 /**
  * scmi_handle_get() - Get the SCMI handle for a device
  *
@@ -986,6 +1076,8 @@ static int scmi_probe(struct platform_device *pdev)
handle = >handle;
handle->dev = info->dev;
handle->version = >version;
+   handle->devm_get_ops = scmi_devm_get_protocol_ops;
+   handle->devm_put_ops = scmi_devm_put_protocol_ops;
 
ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
if (ret)
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 757a826e3cef..2fd2fffb4024 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -57,6 +57,8 @@ struct scmi_clock_info {
 };
 
 struct scmi_handle;
+struct scmi_device;
+struct scmi_protocol_handle;
 
 /**
  * struct scmi_clk_ops - represents the various operations provided
@@ -593,6 +595,9 @@ struct scmi_notify_ops {
  * @sensor_ops: pointer to set of sensor protocol operations
  * @reset_ops: pointer to set of reset protocol operations
  * @voltage_ops: pointer to set of voltage protocol operations
+ * @devm_get_ops: devres managed method to acquire a protocol and get specific
+ *   operations and a dedicated protocol handler
+ * @devm_put_ops: devres managed method to release a protocol
  

Re: [PATCH v3 2/2] power: supply: mt6360_charger: add MT6360 charger support

2021-01-06 Thread Sebastian Reichel
Hi Gene,

I have a bunch of comments, please take a look at my inline
comments.

On Thu, Dec 24, 2020 at 03:48:04PM +0800, Gene Chen wrote:
> From: Gene Chen 
> 
> Add basic support for the battery charger for MT6360 PMIC
> 
> Signed-off-by: Gene Chen 
> ---
>  drivers/power/supply/Kconfig  |   10 +
>  drivers/power/supply/Makefile |1 +
>  drivers/power/supply/mt6360_charger.c | 1054 
> +
>  3 files changed, 1065 insertions(+)
>  create mode 100644 drivers/power/supply/mt6360_charger.c
> 
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index eec646c..dd63bed 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -567,6 +567,16 @@ config CHARGER_MP2629
> Battery charger. This driver provides Battery charger power management
> functions on the systems.
>  
> +config CHARGER_MT6360
> + tristate "Mediatek MT6360 Charger Driver"
> + depends on MFD_MT6360
> + depends on REGULATOR
> + help
> +   Say Y here to enable MT6360 Charger Part.
> +   The device supports High-Accuracy Voltage/Current Regulation,
> +   Average Input Current Regulation, Battery Tempature Sensing,
> +   Over-Temperature Protection, DPDM Detection for BC1.2
> +
>  config CHARGER_QCOM_SMBB
>   tristate "Qualcomm Switch-Mode Battery Charger and Boost"
>   depends on MFD_SPMI_PMIC || COMPILE_TEST
> diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> index dd4b863..9bd0804 100644
> --- a/drivers/power/supply/Makefile
> +++ b/drivers/power/supply/Makefile
> @@ -77,6 +77,7 @@ obj-$(CONFIG_CHARGER_MAX77693)  += max77693_charger.o
>  obj-$(CONFIG_CHARGER_MAX8997)+= max8997_charger.o
>  obj-$(CONFIG_CHARGER_MAX8998)+= max8998_charger.o
>  obj-$(CONFIG_CHARGER_MP2629) += mp2629_charger.o
> +obj-$(CONFIG_CHARGER_MT6360) += mt6360_charger.o
>  obj-$(CONFIG_CHARGER_QCOM_SMBB)  += qcom_smbb.o
>  obj-$(CONFIG_CHARGER_BQ2415X)+= bq2415x_charger.o
>  obj-$(CONFIG_CHARGER_BQ24190)+= bq24190_charger.o
> diff --git a/drivers/power/supply/mt6360_charger.c 
> b/drivers/power/supply/mt6360_charger.c
> new file mode 100644
> index 000..f1dcb97
> --- /dev/null
> +++ b/drivers/power/supply/mt6360_charger.c
> @@ -0,0 +1,1054 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 MediaTek Inc.

2019-2021? :)

> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

change of.h to  after implementing my later
change request.

> +#include 
> +#include 
> +#include 
> +
> +#define MT6360_PMU_CHG_CTRL1 0x311
> +#define MT6360_PMU_CHG_CTRL2 0x312
> +#define MT6360_PMU_CHG_CTRL3 0x313
> +#define MT6360_PMU_CHG_CTRL4 0x314
> +#define MT6360_PMU_CHG_CTRL5 0x315
> +#define MT6360_PMU_CHG_CTRL6 0x316
> +#define MT6360_PMU_CHG_CTRL7 0x317
> +#define MT6360_PMU_CHG_CTRL8 0x318
> +#define MT6360_PMU_CHG_CTRL9 0x319
> +#define MT6360_PMU_CHG_CTRL100x31A
> +#define MT6360_PMU_CHG_CTRL110x31B
> +#define MT6360_PMU_CHG_CTRL120x31C
> +#define MT6360_PMU_CHG_CTRL130x31D
> +#define MT6360_PMU_DEVICE_TYPE   0x322
> +#define MT6360_PMU_USB_STATUS1   0x327
> +#define MT6360_PMU_CHG_CTRL170x32B
> +#define MT6360_PMU_CHG_CTRL180x32C
> +#define MT6360_PMU_CHG_STAT  0x34A
> +#define MT6360_PMU_CHG_CTRL190x361
> +#define MT6360_PMU_FOD_STAT  0x3E7
> +
> +/* MT6360_PMU_CHG_CTRL1 */
> +#define MT6360_FSLP_SHFT (3)
> +#define MT6360_FSLP_MASK BIT(MT6360_FSLP_SHFT)
> +#define MT6360_HIZ_SHFT  (2)
> +#define MT6360_HIZ_MASK  BIT(MT6360_HIZ_SHFT)
> +#define MT6360_OPA_MODE_SHFT (0)
> +#define MT6360_OPA_MODE_MASK BIT(MT6360_OPA_MODE_SHFT)
> +/* MT6360_PMU_CHG_CTRL2 */
> +#define MT6360_TE_SHFT   (4)
> +#define MT6360_TE_MASK   BIT(MT6360_TE_SHFT)
> +#define MT6360_IINLMTSEL_SHFT(2)
> +#define MT6360_IINLMTSEL_MASKGENMASK(3, 2)
> +#define MT6360_CHG_EN_SHFT   (0)
> +#define MT6360_CHG_EN_MASK   BIT(MT6360_CHG_EN_SHFT)
> +/* MT6360_PMU_CHG_CTRL3 */
> +#define MT6360_IAICR_SHFT(2)
> +#define MT6360_IAICR_MASKGENMASK(7, 2)
> +#define MT6360_ILIM_EN_MASK  BIT(0)
> +/* MT6360_PMU_CHG_CTRL4 */
> +#define MT6360_VOREG_SHFT(1)
> +#define MT6360_VOREG_MASKGENMASK(7, 1)
> +/* MT6360_PMU_CHG_CTRL5 */
> +#define MT6360_VOBST_MASKGENMASK(7, 2)
> +/* MT6360_PMU_CHG_CTRL6 */
> +#define MT6360_VMIVR_SHFT(1)
> +#define MT6360_VMIVR_MASKGENMASK(7, 1)
> +/* MT6360_PMU_CHG_CTRL7 */
> +#define MT6360_ICHG_SHFT (2)
> +#define MT6360_ICHG_MASK GENMASK(7, 2)
> +/* MT6360_PMU_CHG_CTRL8 */
> +#define MT6360_IPREC_SHFT(0)
> +#define MT6360_IPREC_MASKGENMASK(3, 0)
> +/* MT6360_PMU_CHG_CTRL9 */
> +#define MT6360_IEOC_SHFT (4)
> +#define MT6360_IEOC_MASK GENMASK(7, 4)
> +/* MT6360_PMU_CHG_CTRL10 */
> +#define MT6360_LBP_SHFT  (4)
> +#define 

[PATCH v4 01/37] firmware: arm_scmi: review protocol registration interface

2021-01-06 Thread Cristian Marussi
Extend common protocol registration routines and provide some new generic
protocols get/put helpers that can track protocols usage and automatically
perform the proper initialization and de-initialization on demand when
required.

Convert all standard protocols to use this new registration scheme while
keeping them all still using the usual initialization logic bound to SCMI
devices probing.

Signed-off-by: Cristian Marussi 
---
v2 --> v3
- removed new Base protocol initialization, it will be re-introduced
  later with all other protocols
---
 drivers/firmware/arm_scmi/base.c|   8 ++
 drivers/firmware/arm_scmi/bus.c |  61 ---
 drivers/firmware/arm_scmi/clock.c   |  10 +-
 drivers/firmware/arm_scmi/common.h  |  30 +-
 drivers/firmware/arm_scmi/driver.c  | 159 +++-
 drivers/firmware/arm_scmi/perf.c|  10 +-
 drivers/firmware/arm_scmi/power.c   |  10 +-
 drivers/firmware/arm_scmi/reset.c   |  10 +-
 drivers/firmware/arm_scmi/sensors.c |   8 +-
 drivers/firmware/arm_scmi/system.c  |   8 +-
 drivers/firmware/arm_scmi/voltage.c |   8 +-
 include/linux/scmi_protocol.h   |   6 +-
 12 files changed, 296 insertions(+), 32 deletions(-)

diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index 017e5d8bd869..1469bad34bc1 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -365,3 +365,11 @@ int scmi_base_protocol_init(struct scmi_handle *h)
 
return 0;
 }
+
+static const struct scmi_protocol scmi_base = {
+   .id = SCMI_PROTOCOL_BASE,
+   .init = _base_protocol_init,
+   .ops = NULL,
+};
+
+DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(base, scmi_base)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 1377ec76a45d..044aa9e3ebb0 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -16,7 +16,7 @@
 #include "common.h"
 
 static DEFINE_IDA(scmi_bus_id);
-static DEFINE_IDR(scmi_protocols);
+static DEFINE_IDR(scmi_available_protocols);
 static DEFINE_SPINLOCK(protocol_lock);
 
 static const struct scmi_device_id *
@@ -51,13 +51,29 @@ static int scmi_dev_match(struct device *dev, struct 
device_driver *drv)
return 0;
 }
 
+const struct scmi_protocol *scmi_get_protocol(int protocol_id)
+{
+   const struct scmi_protocol *proto;
+
+   proto = idr_find(_available_protocols, protocol_id);
+   if (!proto) {
+   pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
+   return NULL;
+   }
+
+   pr_debug("GOT SCMI Protocol 0x%x\n", protocol_id);
+
+   return proto;
+}
+
 static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
 {
-   scmi_prot_init_fn_t fn = idr_find(_protocols, protocol_id);
+   const struct scmi_protocol *proto;
 
-   if (unlikely(!fn))
+   proto = scmi_get_protocol(protocol_id);
+   if (!proto)
return -EINVAL;
-   return fn(handle);
+   return proto->init(handle);
 }
 
 static int scmi_protocol_dummy_init(struct scmi_handle *handle)
@@ -84,7 +100,7 @@ static int scmi_dev_probe(struct device *dev)
return ret;
 
/* Skip protocol initialisation for additional devices */
-   idr_replace(_protocols, _protocol_dummy_init,
+   idr_replace(_available_protocols, _protocol_dummy_init,
scmi_dev->protocol_id);
 
return scmi_drv->probe(scmi_dev);
@@ -194,26 +210,45 @@ void scmi_set_handle(struct scmi_device *scmi_dev)
scmi_dev->handle = scmi_handle_get(_dev->dev);
 }
 
-int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn)
+int scmi_protocol_register(const struct scmi_protocol *proto)
 {
int ret;
 
+   if (!proto) {
+   pr_err("invalid protocol\n");
+   return -EINVAL;
+   }
+
+   if (!proto->init && !proto->init_instance) {
+   pr_err("missing .init() for protocol 0x%x\n", proto->id);
+   return -EINVAL;
+   }
+
spin_lock(_lock);
-   ret = idr_alloc(_protocols, fn, protocol_id, protocol_id + 1,
-   GFP_ATOMIC);
+   ret = idr_alloc(_available_protocols, (void *)proto,
+   proto->id, proto->id + 1, GFP_ATOMIC);
spin_unlock(_lock);
-   if (ret != protocol_id)
-   pr_err("unable to allocate SCMI idr slot, err %d\n", ret);
+   if (ret != proto->id) {
+   pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
+  proto->id, ret);
+   return ret;
+   }
+
+   pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
 
-   return ret;
+   return 0;
 }
 EXPORT_SYMBOL_GPL(scmi_protocol_register);
 
-void scmi_protocol_unregister(int protocol_id)
+void scmi_protocol_unregister(const struct scmi_protocol *proto)
 {
spin_lock(_lock);
-   idr_remove(_protocols, protocol_id);
+   idr_remove(_available_protocols, 

[PATCH v4 0/37] SCMI vendor protocols and modularization

2021-01-06 Thread Cristian Marussi
Hi all,

The current SCMI implementation does not provide an interface to easily
develop and include a custom vendor protocol implementation as prescribed
by the SCMI standard, also because, there is not currently any custom
protocol in the upstream to justify the development of a custom interface
and its maintenance.

Moreover the current interface exposes protocol operations to the SCMI
driver users attaching per-protocol operations directly to the handle
structure, which, in this way, tends to grow indefinitely for each new
protocol addition.

Beside this, protocols private data are also exposed via handle *_priv
pointers, making such private data accessible also to the SCMI drivers
even if neither really needed nor advisable.

This series wants to address this by simplifying the SCMI protocols
interface and reducing it, roughly, to these common generic operations:

handle->devm_get_ops() / handle->devm_put_ops() / handle->notify_ops()

All protocols' private data pointers are removed from handle too and made
accessible only to the protocols code through dedicated internal helpers.

The concept of protocol handle is introduced in the SCMI protocol code
to represent a protocol instance initialized against a specific SCMI
instance (handle), so that all the new protocol code uses such protocol
handles wherever previously SCMI handle was used: this enable tighter
control of what is exposed to the protocol code vs the SCMI drivers.

Moreover protocol initialization is moved away from device probe and now
happens on demand when the first user shows up (first .get_ops), while
de-initialization is performed once the last user of the protocol (even in
terms of notifications) is gone, with the SCMI core taking care to perform
all the needed underlying resource accounting.

This way any new future standard or custom protocol implementation will
expose a common unified interface which does not need to be extended
endlessly: no need to maintain a custom interface only for vendor protos.
SCMI drivers written on top of standard or custom protocols will use this
same common interface to access any protocol operations.

All existent upstream SCMI drivers are converted to this new interface.

Patch [4/37] ("firmware: arm_scmi: introduce bare get/put protocols ops")
is marked as RFC because I was not sure if this non devres methods are
really needed (probbaly not).

In order to make this migration painless and to avoid the need of a big
un-mergeable jumbo patch touching all over the protocols and drivers (like
it was in v2), since v3 the migration process has been heavily split with a
bit of transient code added along the way (to preserve bisectability) and
finally removed towards the ends of the series.
Protocols and SCMI drivers migration to the new interface happens along
patches 11->30.

Note that in v4 all the related SCMI drivers maintainers are still NOT
CC'ed given I am still sort of gather consensus about the interface itself.

Leveraging this new centralized and common initialization flow we took
care also to refactor and simplify protocol-events registration and remove
*notify_priv from the handle interface making it accessible only to the
notification core.

Patch 36 builds on top of this new interface and introduces a mechanism to
define an SCMI protocol as a full blown module (possibly loadable) while
leaving the core dealing with proper resource accounting.
Standard protocols are still kept as builtins in this series, though.

Finally, patch 37 introduces dynamic SCMI devices creation to avoid having
to update the static module device table in the core each time a new driver
is added.

The whole SCMI stack can still be built alternatively as a module (including
all the standard protocols in scmi-module.ko in that case).

On top of this series an example SCMI Custom protocol 0x99 and related
SCMI Custom Dummy driver has been built and it is available at [1] as a
series of DEBUG patches on top this same series.

The series is currently based on for-next/scmi [2] on top of:

commit 6054d97ab512 MAINTAINERS: Update ARM SCMI entry

Any feedback welcome.

Thanks,

Cristian

---
v3 --> v4
- rebased on sudeep/for-next/scmi v5.11-rc1
- added a few comments more

v2 --> v3
- added dynamic SCMI devices creation (getting rid of static device table)
- heavy split of protocols and drivers migrations to the new interface
- rebased on top of next-20201201 so migrating also:
  + SCMIv3.0 Voltage Domain protocol & SCMI Regulator
  + SCMIv3.0 Sensor Extensions

v1 --> v2
- rebased on for-next/scmi v5.10-rc1
- introduced protocol handles
- added devres managed devm_ variant for protocols operations
- made all scmi_protocol refs const
- introduced IDR to handle protocols instead of static array
- refactored code around fast path

[1]:https://gitlab.arm.com/linux-arm/linux-cm/-/commits/scmi_modules_ext_V4/
[2]:https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/log/?h=for-next/scmi

Cristian Marussi (37):
  

Re: [PATCH mips-next 0/4] MIPS: vmlinux.lds.S sections fix & cleanup

2021-01-06 Thread Alexander Lobakin
From: Nathan Chancellor 
Date: Mon, 4 Jan 2021 17:09:36 -0700

> On Mon, Jan 04, 2021 at 12:18:10PM +, Alexander Lobakin wrote:
>> This series hunts the problems discovered after manual enabling of
>> ARCH_WANT_LD_ORPHAN_WARN, notably the missing PAGE_ALIGNED_DATA()
>> section affecting VDSO placement (marked for stable).
>>
>> Compile and runtime tested on MIPS32R2 CPS board with no issues.
>>
>> Alexander Lobakin (4):
>>   MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section
>>   MIPS: vmlinux.lds.S: add ".rel.dyn" to DISCARDS
>>   MIPS: vmlinux.lds.S: add ".gnu.attributes" to DISCARDS
>>   MIPS: select ARCH_WANT_LD_ORPHAN_WARN
>>
>>  arch/mips/Kconfig  | 1 +
>>  arch/mips/kernel/vmlinux.lds.S | 5 -
>>  2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> --
>> 2.30.0
>>
>
> Glad to see ARCH_WANT_LD_ORPHAN_WARN catching on :)
>
> I took this for a spin with clang with malta_kvm_guest_defconfig and I
> only see one section unaccounted for:
>
> $ make -skj"$(nproc)" ARCH=mips CROSS_COMPILE=mipsel-linux-gnu- LLVM=1 
> O=out/mips distclean malta_kvm_guest_defconfig all
> ...
> ld.lld: warning: :(.got) is being placed in '.got'
> ld.lld: warning: :(.got) is being placed in '.got'
> ld.lld: warning: :(.got) is being placed in '.got'
>
> Looks like most architectures place it in .got (ia64, nios2, powerpc)
> or .text (arm64).

Addressed in v2, thanks!

> Cheers,
> Nathan

Al



Re: arch/arm64/kernel/topology.c:367:22: sparse: sparse: dereference of noderef expression

2021-01-06 Thread Ionela Voinescu
On Wednesday 06 Jan 2021 at 17:47:58 (+), Al Viro wrote:
> On Wed, Jan 06, 2021 at 03:07:24PM +, Ionela Voinescu wrote:
> 
> > > >  > 367  switch ((u64)reg->address) {
> > > 
> > > That's not a dereference but I guess sparse complains of dropping the
> > > __iomem. We could change the cast to (__force u64) to silence sparse.
> 
> Oh, yes, it is - that of >address, to fetch the value you are
> casting to u64.  And nonsense in declaration of struct cpc_reg says
> that its 'address' field somehow manages to be located in iomem,
> regardless of where the entire structure is stored.
> 
> Qualifiers apply to lvalues - it's "how can that object be accessed".
> They don't say anything with the values _stored_ in that object.
> It is possible to have them applied to individual fields of a structure;
> for some qualifiers that might be legitimate - e.g. you could do
> struct foo {
>   char *s;
>   volatile int x;
> } *p;
> telling the compiler that p->x is to be treated as volatile (make no
> assumptions about the value not being changed behind your back, etc.),
> while p->s is not.
> 
> However, for __iomem (or __user, etc.) that makes no sense whatsoever;
> you are saying "this field lives in iomem, no matter where the entire
> structure is located".
> 
> To quote C99 6.3.2.1[2]:
>   Except when it is the operand of the sizeof operator, the unary & 
> operator, the ++
> operator, the -- operator, or the left operand of the . operator or an 
> assignment operator,
> an lvalue that does not have array type is converted to the value stored in 
> the designated
> object (and is no longer an lvalue). If the lvalue has qualified type, the 
> value has the
> unqualified version of the type of the lvalue; otherwise, the value has the 
> type of the
> lvalue. If the lvalue has an incomplete type and does not have array type, 
> the behavior is
> undefined.
> 
>   IOW, in the example above, as lvalue p->x will have "volatile int"
> for type; using it as argument of cast operator will convert it (_before_
> doing the cast) to whatever integer that had been found stored
> in that field and the type of that will be "int", not "volatile int".
> As soon as you fetch the value stored in object, qualifiers are gone.
> 
>   The syntax is somewhat unfortunate - it's easy to confuse
> qualified pointer to type with pointer to qualified type.
>   const int *r
> means "r is an unqualified pointer to const int"; the value stored in r may
> be modified, but the value stored in *r may not.
>   int * const r
> means "r is a const pointer to int"; the value stored in r may not be 
> modified,
> but the value stored in *r may.
> 
>   You often run into something like
> struct foo {
>   ...
>   u64 __iomem *some_reg;
>   ...
> } *p;
> and, unlike the mess in struct cpc_reg declaration, here p->some_reg is *NOT*
> __iomem-qualified.  It's a perfectly normal field of a structure somewhere
> in kernel memory, it can be fetched from, stored into, etc.  The contents
> of that field is a pointer to __iomem u64.  It can be passed to e.g.
> readq(), but trying to directly fetch *(p->some_reg) will barf.
>   In such cases the limitations apply not to how we can access the
> field itself, but to what we can do with the value we find in that
> field.
> 
>   At a guess, the intent of that (mis)annotation had been
> "this field contains a 64bit unsigned integer that happens to contain
> an address of something in iomem".  But qualifiers are useless for
> that - once you've fetched that value, all you have is plain u64.
> Nor would they be carried through the arithmetics, etc.
>

This could have been the intention, as that value is used as an offset
in the PCC virtual space (although it does not make complete sense even
in this case). Otherwise it's used as a pysical address offset for
system memory, and given as pysical address argument to ioremap :).

In any case, thank you for the detailed explanation. After your first
email I was thinking that it does not make sense to have the __iomem
annotation for address in cpc_reg, especially given its uses in
cppc_acpi.c and for the code that implements the ffh functions, but I
think only after this email it really  sunk in how wrong that
annotation really was.

Initially I though it always only makes sense to have a __iomem pointer.
That is, it only makes sense to have a pointer with a cookie attached
specifying that it addresses a device memory space that should only be
accessed using special functions.

But then you've got something like this in drivers/input/serio/apbps2.c:
struct apbps2_regs {
u32 __iomem data;   /* 0x00 */
u32 __iomem status; /* 0x04 */
u32 __iomem ctrl;   /* 0x08 */
u32 __iomem reload; /* 0x0c */
};
struct apbps2_priv {
struct serio*io;
struct apbps2_regs  *regs;
};
[..] (followed by)
ioread32be(>regs->status)

which I think is correct despite 

Re: [PATCH] mm/mmap: replace if (cond) BUG() with BUG_ON()

2021-01-06 Thread Andrea Arcangeli
Hello,

On Wed, Jan 06, 2021 at 11:46:20AM -0800, Andrew Morton wrote:
> On Tue, 5 Jan 2021 20:28:27 -0800 (PST) Hugh Dickins  wrote:
> 
> > Alex, please consider why the authors of these lines (whom you
> > did not Cc) chose to write them without BUG_ON(): it has always
> > been preferred practice to use BUG_ON() on predicates, but not on
> > functionally effective statements (sorry, I've forgotten the proper
> > term: I'd say statements with side-effects, but here they are not
> > just side-effects: they are their main purpose).
> > 
> > We prefer not to hide those away inside BUG macros
> 
> Should we change that?  I find BUG_ON(something_which_shouldnt_fail())
> to be quite natural and readable.
> 
> As are things like the existing
> 
> BUG_ON(mmap_read_trylock(mm));
> BUG_ON(wb_domain_init(_wb_domain, GFP_KERNEL));
> 
> etc.
> 
> 
> No strong opinion here, but is current mostly-practice really
> useful?

I'd be surprised if the kernel can boot with BUG_ON() defined as "do
{}while(0)" so I guess it doesn't make any difference.

I've no strong opinion either, but personally my views matches Hugh's
views on this. I certainly tried to stick to that in the past since I
find it cleaner if a bugcheck just "checks" and can be deleted at any
time without sudden breakage.

Said that I also guess we're in the minority.

Thanks,
Andrea



Re: [PATCH] mm/mmap: replace if (cond) BUG() with BUG_ON()

2021-01-06 Thread Hugh Dickins
On Wed, 6 Jan 2021, Andrew Morton wrote:
> On Tue, 5 Jan 2021 20:28:27 -0800 (PST) Hugh Dickins  wrote:
> 
> > Alex, please consider why the authors of these lines (whom you
> > did not Cc) chose to write them without BUG_ON(): it has always
> > been preferred practice to use BUG_ON() on predicates, but not on
> > functionally effective statements (sorry, I've forgotten the proper
> > term: I'd say statements with side-effects, but here they are not
> > just side-effects: they are their main purpose).
> > 
> > We prefer not to hide those away inside BUG macros
> 
> Should we change that?  I find BUG_ON(something_which_shouldnt_fail())
> to be quite natural and readable.

Fair enough.  Whereas my mind tends to filter out the BUG lines when
skimming code, knowing they can be skipped, not needing that effort
to pull out what's inside them.

Perhaps I'm a relic and everyone else is with you: I can only offer
my own preference, which until now was supported by kernel practice.

> 
> As are things like the existing
> 
> BUG_ON(mmap_read_trylock(mm));
> BUG_ON(wb_domain_init(_wb_domain, GFP_KERNEL));
> 
> etc.

People say "the exception proves the rule".  Perhaps we should invite a
shower of patches to change those?  (I'd prefer not, I'm no fan of churn.)

> 
> No strong opinion here, but is current mostly-practice really
> useful?

You've seen my vote.  Now let the games begin!

Hugh


Re: [PATCH v2 2/4] pinctrl: sunxi: h6-r: Add s_rsb pin functions

2021-01-06 Thread Linus Walleij
On Sun, Jan 3, 2021 at 11:00 AM Samuel Holland  wrote:

> As there is an RSB controller in the H6 SoC, there should be some pin
> configuration for it. While no such configuration is documented, the
> "s_i2c" pins are suspiciously on the "alternate" function 3, with no
> primary function 2 given. This suggests the primary function for these
> pins is actually RSB, and that is indeed the case.
>
> Add the "s_rsb" pin functions so the RSB controller can be used.
>
> Signed-off-by: Samuel Holland 

This patch applied to the pinctrl tree.

Yours,
Linus Walleij


RE: [RFC PATCH v3 2/2] scheduler: add scheduler level for clusters

2021-01-06 Thread Song Bao Hua (Barry Song)


> -Original Message-
> From: Vincent Guittot [mailto:vincent.guit...@linaro.org]
> Sent: Thursday, January 7, 2021 5:29 AM
> To: Song Bao Hua (Barry Song) 
> Cc: Valentin Schneider ; Catalin Marinas
> ; Will Deacon ; Rafael J. Wysocki
> ; Cc: Len Brown ;
> gre...@linuxfoundation.org; Jonathan Cameron ;
> Ingo Molnar ; Peter Zijlstra ; Juri
> Lelli ; Dietmar Eggemann ;
> Steven Rostedt ; Ben Segall ; Mel
> Gorman ; Mark Rutland ; Sudeep Holla
> ; Aubrey Li ; LAK
> ; linux-kernel
> ; ACPI Devel Maling List
> ; linux...@openeuler.org; xuwei (O)
> ; Zengtao (B) ; tiantao (H)
> 
> Subject: Re: [RFC PATCH v3 2/2] scheduler: add scheduler level for clusters
> 
> On Wed, 6 Jan 2021 at 09:35, Barry Song  wrote:
> >
> > ARM64 server chip Kunpeng 920 has 6 clusters in each NUMA node, and each
> > cluster has 4 cpus. All clusters share L3 cache data, but each cluster
> > has local L3 tag. On the other hand, each clusters will share some
> > internal system bus. This means cache coherence overhead inside one cluster
> > is much less than the overhead across clusters.
> >
> > This patch adds the sched_domain for clusters. On kunpeng 920, without
> > this patch, domain0 of cpu0 would be MC with cpu0~cpu23 with ; with this
> > patch, MC becomes domain1, a new domain0 "CLS" including cpu0-cpu3.
> >
> > This will affect load balance. For example, without this patch, while cpu0
> > becomes idle, it will pull a task from cpu1-cpu15. With this patch, cpu0
> > will try to pull a task from cpu1-cpu3 first. This will have much less
> > overhead of task migration.
> >
> > On the other hand, while doing WAKE_AFFINE, this patch will try to find
> > a core in the target cluster before scanning the whole llc domain.
> > This means it will proactively use a core which has better affinity with
> > target core at first.
> >
> > Though it is named "cluster", architectures or machines can define its
> > exact meaning of cluster as long as some cpus can share some resources
> > in lower level than llc. So the implementation is applicable to all
> > architectures.
> >
> > Different cpus might have different resource sharing like L1, L2, cache
> > tags, internal busses etc.
> > Since it is hard to know where we should start to scan, this patch adds
> > a SD_SHARE_CLS_RESOURCES rather than directly leveraging the existing
> 
> Not sure that we need this new flag. See more about this below
> 
> You should have a look at https://lkml.org/lkml/2020/12/14/560 which
> rework select_idle_core/cpu/smt
> 
> > SD_SHARE_PKG_RESOURCES flag. Architectures or machines can decide what
> > is cluster and who should get SD_SHARE_CLS_RESOURCES. select_idle_cpu()
> > will scan from the first sched_domain with SD_SHARE_CLS_RESOURCES.
> >
> > The below is a hackbench result:
> >
> > we run the below command with different -g parameter from 1 to 10, for each
> > different g, we run the command 10 times and get the average time
> > $ numactl -N 0 hackbench -p -T -l 2 -g $1
> >
> > hackbench will report the time which is needed to complete a certain number
> > of messages transmissions between a certain number of tasks, for example:
> > $ numactl -N 0 hackbench -p -T -l 2 -g 10
> > Running in threaded mode with 10 groups using 40 file descriptors each
> > (== 400 tasks)
> > Each sender will pass 2 messages of 100 bytes
> > Time: 8.874
> >
> > The below is the result of hackbench w/ and w/o the patch:
> > g 1  2  3  4  5  6  7  8  9  10
> > w/o 1.4777 2.0112 3.1919 4.2654 5.3246 6.4019 7.5939 8.7073 9.7526 10.8987
> > w/  1.4793 1.9344 2.9080 3.9267 4.8339 5.7186 6.6923 7.5088 8.3715 9.2173
> >   +8.9%  +7.9%  +9.3%  +10.7% +11.8% +13.8% +14.2% +15.5%
> >
> > Tracing the kernel while g=10, it shows select_idle_cpu() has a large chance
> > to get cpu in the same cluster with the target while it sometimes gets cpu
> > outside the cluster:
> > target cpu
> > 19  -> 17
> > 13  -> 15
> > 23  -> 20
> > 23  -> 20
> > 19  -> 17
> > 13  -> 15
> > 16  -> 17
> > 19  -> 17
> > 7   -> 5
> > 10  -> 11
> > 23  -> 20
> > *23 -> 4
> > ...
> >
> > Signed-off-by: Barry Song 
> > ---
> >  -v3:
> >   - rebased againest 5.11-rc2
> >   - with respect to the comments of Valentin Schneider, Peter Zijlstra,
> > Vincent Guittot and Mel Gorman etc.
> >   * moved the scheduler changes from arm64 to the common place for all
> > architectures.
> >   * added SD_SHARE_CLS_RESOURCES sd_flags specifying the sched_domain
> > where select_idle_cpu() should begin to scan from
> >   * removed redundant select_idle_cluster() function since all code is
> > in select_idle_cpu() now. it also avoided scanning cluster cpus
> > twice in v2 code;
> >   * redo the hackbench in one numa after the above changes
> >
> >  arch/arm64/Kconfig |  7 +++
> >  include/linux/sched/sd_flags.h |  9 +
> >  include/linux/sched/topology.h |  7 +++
> >  include/linux/topology.h   |  7 +++
> >  

[PATCH v2 mips-next 4/4] MIPS: select ARCH_WANT_LD_ORPHAN_WARN

2021-01-06 Thread Alexander Lobakin
Now, after that all the sections are explicitly described and
declared in vmlinux.lds.S, we can enable ld orphan warnings to
prevent from missing any new sections in future.

Signed-off-by: Alexander Lobakin 
---
 arch/mips/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d68df1febd25..d3e64cc0932b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -18,6 +18,7 @@ config MIPS
select ARCH_USE_QUEUED_SPINLOCKS
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
select ARCH_WANT_IPC_PARSE_VERSION
+   select ARCH_WANT_LD_ORPHAN_WARN
select BUILDTIME_TABLE_SORT
select CLONE_BACKWARDS
select CPU_NO_EFFICIENT_FFS if (TARGET_ISA_REV < 1)
-- 
2.30.0




[PATCH v2 mips-next 3/4] MIPS: vmlinux.lds.S: catch bad .got, .plt and .rel.dyn at link time

2021-01-06 Thread Alexander Lobakin
Catch any symbols placed in .got, .got.plt, .plt, .rel.dyn
or .rela.dyn and check for these sections to be zero-sized
at link time.

At least two of them were noticed in real builds:

mips-alpine-linux-musl-ld: warning: orphan section `.rel.dyn'
from `init/main.o' being placed in section `.rel.dyn'

ld.lld: warning: :(.got) is being placed in '.got'

Adopted from x86/kernel/vmlinux.lds.S.

Reported-by: Nathan Chancellor  # .got
Suggested-by: Fangrui Song  # .rel.dyn
Signed-off-by: Alexander Lobakin 
---
 arch/mips/kernel/vmlinux.lds.S | 35 ++
 1 file changed, 35 insertions(+)

diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 5d6563970ab2..05eda9d9a7d5 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -227,4 +227,39 @@ SECTIONS
*(.pdr)
*(.reginfo)
}
+
+   /*
+* Sections that should stay zero sized, which is safer to
+* explicitly check instead of blindly discarding.
+*/
+
+   .got : {
+   *(.got)
+   *(.igot.*)
+   }
+   ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!")
+
+   .got.plt (INFO) : {
+   *(.got.plt)
+   }
+   ASSERT(SIZEOF(.got.plt) == 0, "Unexpected GOT/PLT entries detected!")
+
+   .plt : {
+   *(.plt)
+   *(.plt.*)
+   *(.iplt)
+   }
+   ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages 
detected!")
+
+   .rel.dyn : {
+   *(.rel.*)
+   *(.rel_*)
+   }
+   ASSERT(SIZEOF(.rel.dyn) == 0, "Unexpected run-time relocations (.rel) 
detected!")
+
+   .rela.dyn : {
+   *(.rela.*)
+   *(.rela_*)
+   }
+   ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) 
detected!")
 }
-- 
2.30.0




[PATCH v2 mips-next 2/4] MIPS: vmlinux.lds.S: add ".gnu.attributes" to DISCARDS

2021-01-06 Thread Alexander Lobakin
Discard GNU attributes at link time as kernel doesn't use it at all.
Solves a dozen of the following ld warnings (one per every file):

mips-alpine-linux-musl-ld: warning: orphan section `.gnu.attributes'
from `arch/mips/kernel/head.o' being placed in section
`.gnu.attributes'
mips-alpine-linux-musl-ld: warning: orphan section `.gnu.attributes'
from `init/main.o' being placed in section `.gnu.attributes'

Misc: sort DISCARDS section entries alphabetically.

Signed-off-by: Alexander Lobakin 
---
 arch/mips/kernel/vmlinux.lds.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 83e27a181206..5d6563970ab2 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -221,9 +221,10 @@ SECTIONS
/* ABI crap starts here */
*(.MIPS.abiflags)
*(.MIPS.options)
+   *(.eh_frame)
+   *(.gnu.attributes)
*(.options)
*(.pdr)
*(.reginfo)
-   *(.eh_frame)
}
 }
-- 
2.30.0




[PATCH v2 mips-next 1/4] MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section

2021-01-06 Thread Alexander Lobakin
MIPS uses its own declaration of rwdata, and thus it should be kept
in sync with the asm-generic one. Currently PAGE_ALIGNED_DATA() is
missing from the linker script, which emits the following ld
warnings:

mips-alpine-linux-musl-ld: warning: orphan section
`.data..page_aligned' from `arch/mips/kernel/vdso.o' being placed
in section `.data..page_aligned'
mips-alpine-linux-musl-ld: warning: orphan section
`.data..page_aligned' from `arch/mips/vdso/vdso-image.o' being placed
in section `.data..page_aligned'

Add the necessary declaration, so the mentioned structures will be
placed in vmlinux as intended:

80630580 D __end_once
80630580 D __start___dyndbg
80630580 D __start_once
80630580 D __stop___dyndbg
80634000 d mips_vdso_data
80638000 d vdso_data
80638580 D _gp
8063c000 T __init_begin
8063c000 D _edata
8063c000 T _sinittext

->

805a4000 D __end_init_task
805a4000 D __nosave_begin
805a4000 D __nosave_end
805a4000 d mips_vdso_data
805a8000 d vdso_data
805ac000 D mmlist_lock
805ac080 D tasklist_lock

Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
Cc: sta...@vger.kernel.org # 4.4+
Signed-off-by: Alexander Lobakin 
---
 arch/mips/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 5e97e9d02f98..83e27a181206 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -90,6 +90,7 @@ SECTIONS
 
INIT_TASK_DATA(THREAD_SIZE)
NOSAVE_DATA
+   PAGE_ALIGNED_DATA(PAGE_SIZE)
CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
DATA_DATA
-- 
2.30.0




[PATCH v2 mips-next 0/4] MIPS: vmlinux.lds.S sections fix & cleanup

2021-01-06 Thread Alexander Lobakin
This series hunts the problems discovered after manual enabling of
ARCH_WANT_LD_ORPHAN_WARN, notably the missing PAGE_ALIGNED_DATA()
section affecting VDSO placement (marked for stable).

Compile and runtime tested on MIPS32R2 CPS board with no issues.

Since v1 [0]:
 - catch .got entries too as LLD may produce it (Nathan);
 - check for unwanted sections to be zero-sized instead of
   discarding (Fangrui).

[0] https://lore.kernel.org/linux-mips/20210104121729.46981-1-aloba...@pm.me

Alexander Lobakin (4):
  MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section
  MIPS: vmlinux.lds.S: add ".gnu.attributes" to DISCARDS
  MIPS: vmlinux.lds.S: catch bad .got, .plt and .rel.dyn at link time
  MIPS: select ARCH_WANT_LD_ORPHAN_WARN

 arch/mips/Kconfig  |  1 +
 arch/mips/kernel/vmlinux.lds.S | 39 +-
 2 files changed, 39 insertions(+), 1 deletion(-)

-- 
2.30.0




drivers/soc/litex/litex_soc_ctrl.c:143:34: warning: unused variable 'litex_soc_ctrl_of_match'

2021-01-06 Thread kernel test robot
Hi Pawel,

FYI, the error/warning still remains.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62
commit: 22447a99c97e353bde8f90c2353873f27681d57c drivers/soc/litex: add LiteX 
SoC Controller driver
date:   8 weeks ago
config: x86_64-randconfig-a001-20210107 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 
5c951623bc8965fa1e89660f2f5f4a2944e4981a)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=22447a99c97e353bde8f90c2353873f27681d57c
git remote add linus 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout 22447a99c97e353bde8f90c2353873f27681d57c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/soc/litex/litex_soc_ctrl.c:143:34: warning: unused variable 
>> 'litex_soc_ctrl_of_match' [-Wunused-const-variable]
   static const struct of_device_id litex_soc_ctrl_of_match[] = {
^
   1 warning generated.


vim +/litex_soc_ctrl_of_match +143 drivers/soc/litex/litex_soc_ctrl.c

   142  
 > 143  static const struct of_device_id litex_soc_ctrl_of_match[] = {
   144  {.compatible = "litex,soc-controller"},
   145  {},
   146  };
   147  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH] mm: memcg/slab: optimize objcg stock draining

2021-01-06 Thread Roman Gushchin
On Wed, Jan 06, 2021 at 11:50:44AM -0800, Andrew Morton wrote:
> On Tue, 5 Jan 2021 20:22:39 -0800 Roman Gushchin  wrote:
> 
> > Imran Khan reported a regression in hackbench results caused by the
> > commit f2fe7b09a52b ("mm: memcg/slab: charge individual slab objects
> > instead of pages").
> 
> How large was the regression?

~16% according to Imran's data.

> 
> > --- a/mm/memcontrol.c
> > +++ b/mm/memcontrol.c
> > @@ -3122,9 +3122,7 @@ void __memcg_kmem_uncharge(struct mem_cgroup *memcg, 
> > unsigned int nr_pages)
> > if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
> > page_counter_uncharge(>kmem, nr_pages);
> >  
> > -   page_counter_uncharge(>memory, nr_pages);
> > -   if (do_memsw_account())
> > -   page_counter_uncharge(>memsw, nr_pages);
> > +   refill_stock(memcg, nr_pages);
> >  }
> 
> IOW, which kernel version(s) should we be patching?

5.9+

Thanks!


Re: [PATCH] mm: Teach pfn_to_online_page() about ZONE_DEVICE section collisions

2021-01-06 Thread Dan Williams
On Wed, Jan 6, 2021 at 3:23 AM David Hildenbrand  wrote:
>
> On 06.01.21 11:42, Michal Hocko wrote:
> > On Wed 06-01-21 10:56:19, David Hildenbrand wrote:
> > [...]
> >> Note that this is not sufficient in the general case. I already
> >> mentioned that we effectively override an already initialized memmap.
> >>
> >> ---
> >>
> >> [SECTION ]
> >> Before:
> >> [ ZONE_NORMAL ][Hole ]
> >>
> >> The hole has some node/zone (currently 0/0, discussions ongoing on how
> >> to optimize that to e.g., ZONE_NORMAL in this example) and is
> >> PG_reserved - looks like an ordinary memory hole.
> >>
> >> After memremap:
> >> [ ZONE_NORMAL ][ ZONE_DEVICE ]
> >>
> >> The already initialized memmap was converted to ZONE_DEVICE. Your
> >> slowpath will work.
> >>
> >> After memunmap (no poisioning):
> >> [ ZONE_NORMAL ][ ZONE_DEVICE ]
> >>
> >> The slow path is no longer working. pfn_to_online_page() might return
> >> something that is ZONE_DEVICE.
> >>
> >> After memunmap (poisioning):
> >> [ ZONE_NORMAL ][ POISONED]
> >>
> >> The slow path is no longer working. pfn_to_online_page() might return
> >> something that will BUG_ON via page_to_nid() etc.
> >>
> >> ---
> >>
> >> Reason is that pfn_to_online_page() does no care about sub-sections. And
> >> for now, it didn't had to. If there was an online section, it either was
> >>
> >> a) Completely present. The whole memmap is initialized to sane values.
> >> b) Partially present. The whole memmap is initialized to sane values.
> >>
> >> memremap/memunmap messes with case b)
> >
> > I do not see we ever clear the newly added flag and my understanding is
> > that the subsection removed would lead to get_dev_pagemap returning a
> > NULL. Which would obviously need to be checked for pfn_to_online_page.
> > Or do I miss anything and the above is not the case and we could still
> > get false positives?
>
> See my example above ("After memunmap").
>
> We're still in the slow pathg. pfn_to_online_page() will return a struct
> page as get_dev_pagemap() is now  NULL.
>
> Yet page_zone(page) will either
> - BUG_ON (memmap was poisoned)
> - return ZONE_DEVICE zone (memmap not poisoned when memunmapping)
>
> As I said, can be tackled by checking for pfn_section_valid() at least
> on the slow path. Ideally also on the fast path.

Good eye, I glazed over that the existing pfn_section_valid() check in
pfn_valid() is obviated by early_section(). I'll respin with a
standalone pfn_section_valid() gate in pfn_to_online_page().

>
> >
> >> Well have to further tweak pfn_to_online_page(). You'll have to also
> >> check pfn_section_valid() *at least* on the slow path. Less-hacky would
> >> be checking it also in the "somehwat-faster" path - that would cover
> >> silently overriding a memmap that's visible via pfn_to_online_page().
> >> Might slow down things a bit.
> >>
> >>
> >> Not completely opposed to this, but I would certainly still prefer just
> >> avoiding this corner case completely instead of patching around it. Thanks!
> >
> > Well, I would love to have no surprises either. So far there was not
> > actual argument why the pmem reserved space cannot be fully initialized.
>
> Yes, I'm still hoping Dan can clarify that.

Complexity and effective utility (once pfn_to_online_page() is fixed)
are the roadblocks in my mind. The altmap is there to allow for PMEM
capacity to be used as memmap space, so there would need to be code to
break that circular dependency and allocate a memmap for the metadata
space from DRAM and the rest of the memmap space for the data capacity
from pmem itself. That memmap-for-pmem-metadata will still represent
offline pages. So once pfn_to_online_page() is fixed, what pfn-walker
is going to be doing pfn_to_page() on PMEM metadata? Secondly, there
is a PMEM namespace mode called "raw" that eschews DAX and 'struct
page' for pmem and just behaves like a memory-backed block device. The
end result is still that pfn walkers need to discover if a PMEM pfn
has a page, so I don't see what "sometimes there's an
memmap-for-pmem-metadata" buys us?

>
> > On the other hand making sure that pfn_to_online_page sounds like the
> > right thing to do. And having an explicit check for zone device there in
> > a slow path makes sense to me.
>
> As I said, I'd favor to simplify and just get rid of the special case,
> instead of coming up with increasingly complex ways to deal with it.
> pfn_to_online_page() used to be simple, essentially checking a single
> flag was sufficient in most setups.

I think the logic to throw away System RAM that might collide with
PMEM and soft-reserved memory within a section is on the order of the
same code complexity as the patch proposed here, no? Certainly the
throw-away concept itself is easier to grasp, but I don't think that
would be reflected in the code patch to achieve it... willing to be
proved wrong with a patch.


Re: [PATCH v2 2/6] mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page

2021-01-06 Thread Michal Hocko
On Wed 06-01-21 11:30:25, Mike Kravetz wrote:
> On 1/6/21 8:35 AM, Michal Hocko wrote:
> > On Wed 06-01-21 16:47:35, Muchun Song wrote:
> >> Because we only can isolate a active page via isolate_huge_page()
> >> and hugetlbfs_fallocate() forget to mark it as active, we cannot
> >> isolate and migrate those pages.
> > 
> > I've little bit hard time to understand this initially and had to dive
> > into the code to make sense of it. I would consider the following
> > wording easier to grasp. Feel free to reuse if you like.
> > "
> > If a new hugetlb page is allocated during fallocate it will not be
> > marked as active (set_page_huge_active) which will result in a later
> > isolate_huge_page failure when the page migration code would like to
> > move that page. Such a failure would be unexpected and wrong.
> > "
> > 
> > Now to the fix. I believe that this patch shows that the
> > set_page_huge_active is just too subtle. Is there any reason why we
> > cannot make all freshly allocated huge pages active by default?
> 
> I looked into that yesterday.  The primary issue is in page fault code,
> hugetlb_no_page is an example.  If page_huge_active is set, then it can
> be isolated for migration.  So, migration could race with the page fault
> and the page could be migrated before being added to the page table of
> the faulting task.  This was an issue when hugetlb_no_page 
> set_page_huge_active
> right after allocating and clearing the huge page.  Commit cb6acd01e2e4
> moved the set_page_huge_active after adding the page to the page table
> to address this issue.

Thanks for the clarification. I was not aware of this subtlety. The
existing comment is not helping much TBH. I am still digesting the
suggested race. The page is new and exclusive and not visible via page
tables yet, so the only source of the migration would be pfn based
(hotplug, poisoning), right?

Btw. s@set_page_huge_active@set_page_huge_migrateable@ would help
readability IMHO. With a comment explaining that this _has_ to be called
after the page is fully initialized.
-- 
Michal Hocko
SUSE Labs


[PATCH v10 1/2] dt-bindings: power: Add the bq256xx dt bindings

2021-01-06 Thread Ricardo Rivera-Matos
Add the bindings for the bq256xx series of battery charging ICs.

Datasheets:
- https://www.ti.com/lit/ds/symlink/bq25600.pdf
- https://www.ti.com/lit/ds/symlink/bq25601.pdf
- https://www.ti.com/lit/ds/symlink/bq25600d.pdf
- https://www.ti.com/lit/ds/symlink/bq25601d.pdf
- https://www.ti.com/lit/ds/symlink/bq25611d.pdf
- https://www.ti.com/lit/ds/symlink/bq25618.pdf
- https://www.ti.com/lit/ds/symlink/bq25619.pdf

Reviewed-by: Rob Herring 
Signed-off-by: Ricardo Rivera-Matos 
---
 .../bindings/power/supply/bq256xx.yaml| 110 ++
 1 file changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/bq256xx.yaml

diff --git a/Documentation/devicetree/bindings/power/supply/bq256xx.yaml 
b/Documentation/devicetree/bindings/power/supply/bq256xx.yaml
new file mode 100644
index ..18b54783e11a
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/bq256xx.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+# Copyright (C) 2020 Texas Instruments Incorporated
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/power/supply/bq256xx.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: TI bq256xx Switch Mode Buck Charger
+
+maintainers:
+  - Ricardo Rivera-Matos 
+
+description: |
+  The bq256xx devices are a family of highly-integrated battery charge
+  management and system power management ICs for single cell Li-ion and Li-
+  polymer batteries.
+
+  Datasheets:
+- https://www.ti.com/lit/ds/symlink/bq25600.pdf
+- https://www.ti.com/lit/ds/symlink/bq25601.pdf
+- https://www.ti.com/lit/ds/symlink/bq25600d.pdf
+- https://www.ti.com/lit/ds/symlink/bq25601d.pdf
+- https://www.ti.com/lit/ds/symlink/bq25611d.pdf
+- https://www.ti.com/lit/ds/symlink/bq25618.pdf
+- https://www.ti.com/lit/ds/symlink/bq25619.pdf
+
+properties:
+  compatible:
+enum:
+  - ti,bq25600
+  - ti,bq25601
+  - ti,bq25600d
+  - ti,bq25601d
+  - ti,bq25611d
+  - ti,bq25618
+  - ti,bq25619
+
+  reg:
+maxItems: 1
+
+  ti,watchdog-timeout-ms:
+$ref: /schemas/types.yaml#/definitions/uint32
+default: 0
+description: |
+  Watchdog timer in ms. 0 (default) disables the watchdog
+minimum: 0
+maximum: 16
+enum: [ 0, 4, 8, 16]
+
+  input-voltage-limit-microvolt:
+description: |
+   Minimum input voltage limit in µV with a 10 µV step
+minimum: 390
+maximum: 540
+
+  input-current-limit-microamp:
+description: |
+   Maximum input current limit in µA with a 10 µA step
+minimum: 10
+maximum: 320
+
+  monitored-battery:
+$ref: /schemas/types.yaml#/definitions/phandle
+description: phandle to the battery node being monitored
+
+  interrupts:
+maxItems: 1
+description: |
+  Interrupt sends an active low, 256 μs pulse to host to report the charger
+  device status and faults.
+
+required:
+  - compatible
+  - reg
+  - monitored-battery
+
+additionalProperties: false
+
+examples:
+  - |
+bat: battery {
+  compatible = "simple-battery";
+  constant-charge-current-max-microamp = <204>;
+  constant-charge-voltage-max-microvolt = <4352000>;
+  precharge-current-microamp = <18>;
+  charge-term-current-microamp = <18>;
+};
+#include 
+#include 
+i2c {
+
+  clock-frequency = <40>;
+
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  charger@6b {
+compatible = "ti,bq25601";
+reg = <0x6b>;
+monitored-battery = <>;
+
+interrupt-parent = <>;
+interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+ti,watchdog-timeout-ms = <4>;
+
+input-voltage-limit-microvolt = <450>;
+input-current-limit-microamp = <240>;
+   };
+};
+...
-- 
2.30.0



[PATCH v10 2/2] power: supply: bq256xx: Introduce the BQ256XX charger driver

2021-01-06 Thread Ricardo Rivera-Matos
The BQ256XX family of devices are highly integrated buck chargers
for single cell batteries.

Signed-off-by: Ricardo Rivera-Matos 
---
 v9 - resolves two warnings issued by kernel test robot
 v10 - passes psy_cfg by reference
 
 drivers/power/supply/Kconfig   |   11 +
 drivers/power/supply/Makefile  |1 +
 drivers/power/supply/bq256xx_charger.c | 1745 
 3 files changed, 1757 insertions(+)
 create mode 100644 drivers/power/supply/bq256xx_charger.c

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index eec646c568b7..cedef501e683 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -645,6 +645,17 @@ config CHARGER_BQ25980
  Say Y to enable support for the TI BQ25980, BQ25975 and BQ25960
  series of fast battery chargers.
 
+config CHARGER_BQ256XX
+   tristate "TI BQ256XX battery charger driver"
+   depends on I2C
+   depends on GPIOLIB || COMPILE_TEST
+   select REGMAP_I2C
+   help
+ Say Y to enable support for the TI BQ256XX battery chargers. The
+ BQ256XX family of devices are highly-integrated, switch-mode battery
+ charge management and system power path management devices for single
+ cell Li-ion and Li-polymer batteries.
+
 config CHARGER_SMB347
tristate "Summit Microelectronics SMB3XX Battery Charger"
depends on I2C
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index dd4b86318cd9..ae322b1da1ed 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o
 obj-$(CONFIG_CHARGER_BQ2515X)  += bq2515x_charger.o
 obj-$(CONFIG_CHARGER_BQ25890)  += bq25890_charger.o
 obj-$(CONFIG_CHARGER_BQ25980)  += bq25980_charger.o
+obj-$(CONFIG_CHARGER_BQ256XX)  += bq256xx_charger.o
 obj-$(CONFIG_CHARGER_SMB347)   += smb347-charger.o
 obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
 obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
diff --git a/drivers/power/supply/bq256xx_charger.c 
b/drivers/power/supply/bq256xx_charger.c
new file mode 100644
index ..dc74c44618af
--- /dev/null
+++ b/drivers/power/supply/bq256xx_charger.c
@@ -0,0 +1,1745 @@
+// SPDX-License-Identifier: GPL-2.0
+// BQ256XX Battery Charger Driver
+// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BQ256XX_MANUFACTURER "Texas Instruments"
+
+#define BQ256XX_INPUT_CURRENT_LIMIT0x00
+#define BQ256XX_CHARGER_CONTROL_0  0x01
+#define BQ256XX_CHARGE_CURRENT_LIMIT   0x02
+#define BQ256XX_PRECHG_AND_TERM_CURR_LIM   0x03
+#define BQ256XX_BATTERY_VOLTAGE_LIMIT  0x04
+#define BQ256XX_CHARGER_CONTROL_1  0x05
+#define BQ256XX_CHARGER_CONTROL_2  0x06
+#define BQ256XX_CHARGER_CONTROL_3  0x07
+#define BQ256XX_CHARGER_STATUS_0   0x08
+#define BQ256XX_CHARGER_STATUS_1   0x09
+#define BQ256XX_CHARGER_STATUS_2   0x0a
+#define BQ256XX_PART_INFORMATION   0x0b
+#define BQ256XX_CHARGER_CONTROL_4  0x0c
+
+#define BQ256XX_IINDPM_MASKGENMASK(4, 0)
+#define BQ256XX_IINDPM_STEP_uA 10
+#define BQ256XX_IINDPM_OFFSET_uA   10
+#define BQ256XX_IINDPM_MIN_uA  10
+#define BQ256XX_IINDPM_MAX_uA  320
+#define BQ256XX_IINDPM_DEF_uA  240
+
+#define BQ256XX_VINDPM_MASKGENMASK(3, 0)
+#define BQ256XX_VINDPM_STEP_uV 10
+#define BQ256XX_VINDPM_OFFSET_uV   390
+#define BQ256XX_VINDPM_MIN_uV  390
+#define BQ256XX_VINDPM_MAX_uV  540
+#define BQ256XX_VINDPM_DEF_uV  450
+
+#define BQ256XX_VBATREG_MASK   GENMASK(7, 3)
+#define BQ2560X_VBATREG_STEP_uV32000
+#define BQ2560X_VBATREG_OFFSET_uV  3856000
+#define BQ2560X_VBATREG_MIN_uV 3856000
+#define BQ2560X_VBATREG_MAX_uV 4624000
+#define BQ2560X_VBATREG_DEF_uV 4208000
+#define BQ25601D_VBATREG_OFFSET_uV 3847000
+#define BQ25601D_VBATREG_MIN_uV3847000
+#define BQ25601D_VBATREG_MAX_uV4615000
+#define BQ25601D_VBATREG_DEF_uV4199000
+#define BQ2561X_VBATREG_STEP_uV1
+#define BQ25611D_VBATREG_MIN_uV3494000
+#define BQ25611D_VBATREG_MAX_uV451
+#define BQ25611D_VBATREG_DEF_uV419
+#define BQ25618_VBATREG_MIN_uV 3504000
+#define BQ25618_VBATREG_MAX_uV 450
+#define BQ25618_VBATREG_DEF_uV 420
+#define BQ256XX_VBATREG_BIT_SHIFT  3
+#define BQ2561X_VBATREG_THRESH 0x8
+#define BQ25611D_VBATREG_THRESH_uV 429
+#define BQ25618_VBATREG_THRESH_uV  430
+
+#define 

[PATCH v10 0/2] Introduce the BQ256XX family of chargers

2021-01-06 Thread Ricardo Rivera-Matos
Hello,

This patchset introduces the bq256xx family of charging ICs. The bq256xx
ICs are highly integrated, buck, switching chargers intended for use in 
smartphones, tablets, and portable electronics.

Ricardo Rivera-Matos (2):
  dt-bindings: power: Add the bq256xx dt bindings
  power: supply: bq256xx: Introduce the BQ256XX charger driver

 .../bindings/power/supply/bq256xx.yaml|  110 ++
 drivers/power/supply/Kconfig  |   11 +
 drivers/power/supply/Makefile |1 +
 drivers/power/supply/bq256xx_charger.c| 1745 +
 4 files changed, 1867 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/bq256xx.yaml
 create mode 100644 drivers/power/supply/bq256xx_charger.c

-- 
2.30.0



Re: [PATCH v2 5/6] PCI: brcmstb: Add panic/die handler to RC driver

2021-01-06 Thread Jim Quinlan
On Wed, Jan 6, 2021 at 2:42 PM Jim Quinlan  wrote:
>
> -- Forwarded message -
> From: Bjorn Helgaas 
> Date: Wed, Jan 6, 2021 at 2:19 PM
> Subject: Re: [PATCH v2 5/6] PCI: brcmstb: Add panic/die handler to RC driver
> To: Jim Quinlan 
> Cc: , Nicolas Saenz Julienne
> , ,
> , Lorenzo Pieralisi
> , Rob Herring , Bjorn
> Helgaas , Florian Fainelli
> , moderated list:BROADCOM BCM2711/BCM2835 ARM
> ARCHITECTURE , moderated
> list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
> , open list
> 
>
>
> On Mon, Nov 30, 2020 at 04:11:42PM -0500, Jim Quinlan wrote:
> > Whereas most PCIe HW returns 0x on illegal accesses and the like,
> > by default Broadcom's STB PCIe controller effects an abort.  This simple
> > handler determines if the PCIe controller was the cause of the abort and if
> > so, prints out diagnostic info.
> >
> > Example output:
> >   brcm-pcie 8b2.pcie: Error: Mem Acc: 32bit, Read, @0x3800
> >   brcm-pcie 8b2.pcie:  Type: TO=0 Abt=0 UnspReq=1 AccDsble=0 BadAddr=0
>
> What does this mean for all the other PCI core code that expects
> 0x data returns?  Does it work?  Does it break differently on
> STB than on other platforms?
Hi Bjorn,

Our PCIe HW causes a CPU abort when this happens.  Occasionally a
customer will have a fault handler try to fix up the abort and
continue on, but we recommend solving the root problem.  This commit
just gives us a chance to glean info about the problem.  Our newer
SOCs have a mode that doesn't abort and instead returns 0x.

BTW, can you point me to example files where "PCI core code that
expects  0x data returns" [on bad accesses]?

Regards,
Jim Quinlan
Broadcom STB

>
> > +/*
> > + * Dump out pcie errors on die or panic.
>
> s/pcie/PCIe/
> This could be a single-line comment.
>
> > + */
>


Re: [PATCH RFC clocksource 2/5] clocksource: Retry clock read if long delays detected

2021-01-06 Thread Paul E. McKenney
On Wed, Jan 06, 2021 at 11:28:00AM -0500, Rik van Riel wrote:
> On Tue, 2021-01-05 at 16:41 -0800, paul...@kernel.org wrote:
> > 
> > @@ -203,7 +204,6 @@ static void
> > clocksource_watchdog_inject_delay(void)
> > injectfail = inject_delay_run;
> > if (!(++injectfail / inject_delay_run % inject_delay_freq)) {
> > printk("%s(): Injecting delay.\n", __func__);
> > -   injectfail = 0;
> > for (i = 0; i < 2 * WATCHDOG_THRESHOLD / NSEC_PER_MSEC;
> > i++)
> > udelay(1000);
> 
> Wait, patch 1 just added that line?
> 
> Should patch 1 not add it and this
> patch go without
> this removal? :)

Good catch, will fix.  ;-)

> +   wdagain_nsec = clocksource_cyc2ns(delta, watchdog-
> >mult, watchdog->shift);
> +   if (wdagain_nsec < 0 || wdagain_nsec >
> WATCHDOG_MAX_SKEW) {
> +   wderr_nsec = wdagain_nsec;
> +   if (nretries++ < max_read_retries)
> +   goto retry;
> +   }
> 
> Given that clocksource_cyc2ns uses unsigned multiplication
> followed by a right shift, do we need to test for <0?

I am worried about the possibility of the "shift" argument to
clocksource_cyc2ns() being zero.  For example, unless I am missing
something, clocksource_tsc has a zero .shift field.

Thanx, Paul


Re: [PATCH] mm: memcg/slab: optimize objcg stock draining

2021-01-06 Thread Andrew Morton
On Tue, 5 Jan 2021 20:22:39 -0800 Roman Gushchin  wrote:

> Imran Khan reported a regression in hackbench results caused by the
> commit f2fe7b09a52b ("mm: memcg/slab: charge individual slab objects
> instead of pages").

How large was the regression?

> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -3122,9 +3122,7 @@ void __memcg_kmem_uncharge(struct mem_cgroup *memcg, 
> unsigned int nr_pages)
>   if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
>   page_counter_uncharge(>kmem, nr_pages);
>  
> - page_counter_uncharge(>memory, nr_pages);
> - if (do_memsw_account())
> - page_counter_uncharge(>memsw, nr_pages);
> + refill_stock(memcg, nr_pages);
>  }

IOW, which kernel version(s) should we be patching?


Re: [PATCH 5.10 00/40] 5.10.3-rc1 review

2021-01-06 Thread Greg Kroah-Hartman
On Thu, Jan 07, 2021 at 01:08:01AM +0530, Jeffrin Jose T wrote:
> On Mon, 2021-01-04 at 07:21 +0100, Greg Kroah-Hartman wrote:
> > On Sun, Jan 03, 2021 at 06:37:51PM +0530, Jeffrin Jose T wrote:
> > > On Mon, 2020-12-28 at 12:41 -0800, Guenter Roeck wrote:
> > > > On 12/28/20 1:50 AM, Pavel Machek wrote:
> > > > > Hi!
> > > > > 
> > > > > > > > > > > https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.3-rc1.gz
> > > > > > > > > > > or in the git tree and branch at:
> > > > > > > > > > > git://git.kernel.org/pub/scm/linux/kernel/g
> > > > > > > > > > > it/s
> > > > > > > > > > > table/
> > > > > > > > > > > linu
> > > > > > > > > > > x-
> > > > > > > > > > > stable-rc.git linux-5.10.y
> > > > > > > > > > > and the diffstat can be found below.
> > > > > > > > > > > 
> > > > > > > > > > > thanks,
> > > > > > > > > > > 
> > > > > > > > > > > greg k-h
> > > > > > > > > > 
> > > > > > > > > > hello ,
> > > > > > > > > > Compiled and booted 5.10.3-rc1+.
> > > > > > > > > > 
> > > > > > > > > > dmesg -l err gives...
> > > > > > > > > > --x-x--->
> > > > > > > > > >    43.190922] Bluetooth: hci0: don't support firmware
> > > > > > > > > > rome
> > > > > > > > > > 0x31010100
> > > > > > > > > > --x---x->
> > > > > > > > > > 
> > > > > > > > > > My Bluetooth is Off.
> > > > > > > > > 
> > > > > > > > > Is this a new warning?  Does it show up on 5.10.2?
> > > > > > > > > 
> > > > > > > > > > Tested-by: Jeffrin Jose T <
> > > > > > > > > > jeff...@rajagiritech.edu.in>
> > > > > > > > > 
> > > > > > > > > thanks for testing?
> > > > > > > > > 
> > > > > > > > > greg k-h
> > > > > > > > 
> > > > > > > > this does not show up in 5.10.2-rc1+
> > > > > > > 
> > > > > > > Odd.  Can you run 'git bisect' to find the offending
> > > > > > > commit?
> > > > > > > 
> > > > > > > Does this same error message show up in Linus's git tree?
> > > > > 
> > > > > > i will try to do "git bisect" .  i saw this error in linus's 
> > > > > > tree.
> > > > > 
> > > > > The bug is in -stable, too, so it is probably easiest to do
> > > > > bisect
> > > > > on
> > > > > -stable tree. IIRC there's less then few hundred commits, so it
> > > > > should
> > > > > be feasible to do bisection by hand if you are not familiar
> > > > > with
> > > > > git
> > > > > bisect.
> > > > > 
> > > > 
> > > > My wild guess would be commit b260e4a68853 ("Bluetooth: Fix slab-
> > > > out-
> > > > of-bounds
> > > > read in hci_le_direct_adv_report_evt()"), but I don't see what
> > > > might
> > > > be wrong
> > > > with it unless some BT device sends a bad report which used to be
> > > > accepted
> > > > but is now silently ignored.
> > > > 
> > > > Guenter
> > > > 
> > > hello,
> > > 
> > > Did  "git bisect" in  a typically ok fashion and found that 5.9.0
> > > is
> > > working for bluetooth related. But 5.10.0-rc1  related is not
> > > working.
> > > 
> > > some related information in bisect.txt  attached.
> > > 
> > > -- 
> > > software engineer
> > > rajagiri school of engineering and technology - autonomous
> > > 
> > 
> > > $sudo git bisect bad
> > > Bisecting: 0 revisions left to test after this (roughly 1 step)
> > > [194810f78402128fe07676646cf9027fd3ed431c] dt-bindings: leds:
> > > Update devicetree documents for ID_RGB
> > > 
> > > $sudo git bisect bad
> > > Bisecting: 0 revisions left to test after this (roughly 0 steps)
> > > [3650b228f83adda7e5ee532e2b90429c03f7b9ec] Linux 5.10-rc1
> > 
> > That's really odd, as that commit only has a Makefile change.
> 
> i will try to work on it again
> 
> > Also, why run this as root?
> > 
> there may be some problem in my sudo configurtion or the way in run
> sudo.\
> when i run "make modules_install" and "make install" using sudo typical
> files 
> ownership changes to root.

That's fine when installing the kernel, but not when building or running
git, please don't do that.


Re: [PATCH] mm/mmap: replace if (cond) BUG() with BUG_ON()

2021-01-06 Thread Andrew Morton
On Tue, 5 Jan 2021 20:28:27 -0800 (PST) Hugh Dickins  wrote:

> Alex, please consider why the authors of these lines (whom you
> did not Cc) chose to write them without BUG_ON(): it has always
> been preferred practice to use BUG_ON() on predicates, but not on
> functionally effective statements (sorry, I've forgotten the proper
> term: I'd say statements with side-effects, but here they are not
> just side-effects: they are their main purpose).
> 
> We prefer not to hide those away inside BUG macros

Should we change that?  I find BUG_ON(something_which_shouldnt_fail())
to be quite natural and readable.

As are things like the existing

BUG_ON(mmap_read_trylock(mm));
BUG_ON(wb_domain_init(_wb_domain, GFP_KERNEL));

etc.


No strong opinion here, but is current mostly-practice really
useful?



Re: [PATCH] rxrpc: fix handling of an unsupported token type in rxrpc_read()

2021-01-06 Thread David Howells
Tom Rix  wrote:

> These two loops iterate over the same data, i believe returning here is all
> that is needed.

But if the first loop is made to support a new type, but the second loop is
missed, it will then likely oops.  Besides, the compiler should optimise both
paths together.

David



Re: [PATCH 5.10 00/40] 5.10.3-rc1 review

2021-01-06 Thread Jeffrin Jose T
On Mon, 2021-01-04 at 07:21 +0100, Greg Kroah-Hartman wrote:
> On Sun, Jan 03, 2021 at 06:37:51PM +0530, Jeffrin Jose T wrote:
> > On Mon, 2020-12-28 at 12:41 -0800, Guenter Roeck wrote:
> > > On 12/28/20 1:50 AM, Pavel Machek wrote:
> > > > Hi!
> > > > 
> > > > > > > > > > https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.3-rc1.gz
> > > > > > > > > > or in the git tree and branch at:
> > > > > > > > > > git://git.kernel.org/pub/scm/linux/kernel/g
> > > > > > > > > > it/s
> > > > > > > > > > table/
> > > > > > > > > > linu
> > > > > > > > > > x-
> > > > > > > > > > stable-rc.git linux-5.10.y
> > > > > > > > > > and the diffstat can be found below.
> > > > > > > > > > 
> > > > > > > > > > thanks,
> > > > > > > > > > 
> > > > > > > > > > greg k-h
> > > > > > > > > 
> > > > > > > > > hello ,
> > > > > > > > > Compiled and booted 5.10.3-rc1+.
> > > > > > > > > 
> > > > > > > > > dmesg -l err gives...
> > > > > > > > > --x-x--->
> > > > > > > > >    43.190922] Bluetooth: hci0: don't support firmware
> > > > > > > > > rome
> > > > > > > > > 0x31010100
> > > > > > > > > --x---x->
> > > > > > > > > 
> > > > > > > > > My Bluetooth is Off.
> > > > > > > > 
> > > > > > > > Is this a new warning?  Does it show up on 5.10.2?
> > > > > > > > 
> > > > > > > > > Tested-by: Jeffrin Jose T <
> > > > > > > > > jeff...@rajagiritech.edu.in>
> > > > > > > > 
> > > > > > > > thanks for testing?
> > > > > > > > 
> > > > > > > > greg k-h
> > > > > > > 
> > > > > > > this does not show up in 5.10.2-rc1+
> > > > > > 
> > > > > > Odd.  Can you run 'git bisect' to find the offending
> > > > > > commit?
> > > > > > 
> > > > > > Does this same error message show up in Linus's git tree?
> > > > 
> > > > > i will try to do "git bisect" .  i saw this error in linus's 
> > > > > tree.
> > > > 
> > > > The bug is in -stable, too, so it is probably easiest to do
> > > > bisect
> > > > on
> > > > -stable tree. IIRC there's less then few hundred commits, so it
> > > > should
> > > > be feasible to do bisection by hand if you are not familiar
> > > > with
> > > > git
> > > > bisect.
> > > > 
> > > 
> > > My wild guess would be commit b260e4a68853 ("Bluetooth: Fix slab-
> > > out-
> > > of-bounds
> > > read in hci_le_direct_adv_report_evt()"), but I don't see what
> > > might
> > > be wrong
> > > with it unless some BT device sends a bad report which used to be
> > > accepted
> > > but is now silently ignored.
> > > 
> > > Guenter
> > > 
> > hello,
> > 
> > Did  "git bisect" in  a typically ok fashion and found that 5.9.0
> > is
> > working for bluetooth related. But 5.10.0-rc1  related is not
> > working.
> > 
> > some related information in bisect.txt  attached.
> > 
> > -- 
> > software engineer
> > rajagiri school of engineering and technology - autonomous
> > 
> 
> > $sudo git bisect bad
> > Bisecting: 0 revisions left to test after this (roughly 1 step)
> > [194810f78402128fe07676646cf9027fd3ed431c] dt-bindings: leds:
> > Update devicetree documents for ID_RGB
> > 
> > $sudo git bisect bad
> > Bisecting: 0 revisions left to test after this (roughly 0 steps)
> > [3650b228f83adda7e5ee532e2b90429c03f7b9ec] Linux 5.10-rc1
> 
> That's really odd, as that commit only has a Makefile change.

i will try to work on it again

> Also, why run this as root?
> 
there may be some problem in my sudo configurtion or the way in run
sudo.\
when i run "make modules_install" and "make install" using sudo typical
files 
ownership changes to root.

-- 
software engineer
rajagiri school of engineering and technology - autonomous



Re: [PATCH] media: atomisp: ov2722: replace hardcoded function name

2021-01-06 Thread Dan Carpenter
On Wed, Jan 06, 2021 at 10:25:26AM -0800, Joe Perches wrote:
> On Wed, 2021-01-06 at 18:52 +0100, Greg Kroah-Hartman wrote:
> > On Wed, Jan 06, 2021 at 07:43:42PM +0200, Filip Kolev wrote: 
> > > On 06-Jan-21 09:51, Greg Kroah-Hartman wrote:
> > > > On Tue, Jan 05, 2021 at 10:29:18PM +0200, Filip Kolev wrote:
> > > > > There is a debug message using hardcoded function name instead of the
> > > > > __func__ macro. Replace it.
> > > > > 
> > > > > Report from checkpatch.pl on the file:
> > > > > 
> > > > > WARNING: Prefer using '"%s...", __func__' to using 'ov2722_remove', 
> > > > > this function's name, in a string
> > > > > + dev_dbg(>dev, "ov2722_remove...\n");
> []
> > > > > diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c 
> > > > > b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> []
> > > > > @@ -1175,7 +1175,7 @@ static int ov2722_remove(struct i2c_client 
> > > > > *client)
> > > > >   struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > > >   struct ov2722_device *dev = to_ov2722_sensor(sd);
> > > > > - dev_dbg(>dev, "ov2722_remove...\n");
> > > > > + dev_dbg(>dev, "%s...\n", __func__);
> > > > 
> > > > dev_dbg() provides the function name already, and this is just a "trace"
> > > > call, and ftrace should be used instead, so the whole line should be
> > > > removed entirely.
> > > 
> > > Thank you for the review!
> > > 
> > > How do I go about this? Do I amend the patch and re-send as v2 or create a
> > > new patch entirely?
> > 
> > New patch entirely please.
> 
> There are quite a lot of these relatively useless function tracing like
> uses in the kernel:
> 
> $ git grep -P '"%s[\.\!]*\\n"\s*,\s*__func__\s*\)' | wc -l
> 1065

These are printing other stuff besides just the function name.  Maybe
grep for '", __func__\)'?

regards,
dan carpenter



[PATCH 2/2] scsi: ufs: handle LINERESET with correct tm_cmd

2021-01-06 Thread Jaegeuk Kim
From: Jaegeuk Kim 

This fixes a warning caused by wrong reserve tag usage in __ufshcd_issue_tm_cmd.

WARNING: CPU: 7 PID: 7 at block/blk-core.c:630 blk_get_request+0x68/0x70
WARNING: CPU: 4 PID: 157 at block/blk-mq-tag.c:82 blk_mq_get_tag+0x438/0x46c

And, in ufshcd_err_handler(), we can avoid to send tm_cmd before aborting
outstanding commands by waiting a bit for IO completion like this.

__ufshcd_issue_tm_cmd: task management cmd 0x80 timed-out

Signed-off-by: Jaegeuk Kim 
---
 drivers/scsi/ufs/ufshcd.c | 36 
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 1678cec08b51..377da8e98d9b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -44,6 +44,9 @@
 /* Query request timeout */
 #define QUERY_REQ_TIMEOUT 1500 /* 1.5 seconds */
 
+/* LINERESET TIME OUT */
+#define LINERESET_IO_TIMEOUT_MS(3) /* 30 sec */
+
 /* Task management command timeout */
 #define TM_CMD_TIMEOUT 100 /* msecs */
 
@@ -5899,6 +5902,8 @@ static void ufshcd_err_handler(struct work_struct *work)
 * check if power mode restore is needed.
 */
if (hba->saved_uic_err & UFSHCD_UIC_PA_GENERIC_ERROR) {
+   ktime_t start = ktime_get();
+
hba->saved_uic_err &= ~UFSHCD_UIC_PA_GENERIC_ERROR;
if (!hba->saved_uic_err)
hba->saved_err &= ~UIC_ERROR;
@@ -5906,6 +5911,20 @@ static void ufshcd_err_handler(struct work_struct *work)
if (ufshcd_is_pwr_mode_restore_needed(hba))
needs_restore = true;
spin_lock_irqsave(hba->host->host_lock, flags);
+   /* Wait for IO completion to avoid aborting IOs */
+   while (hba->outstanding_reqs) {
+   ufshcd_complete_requests(hba);
+   spin_unlock_irqrestore(hba->host->host_lock, flags);
+   schedule();
+   spin_lock_irqsave(hba->host->host_lock, flags);
+   if (ktime_to_ms(ktime_sub(ktime_get(), start)) >
+   LINERESET_IO_TIMEOUT_MS) {
+   dev_err(hba->dev, "%s: timeout, 
outstanding=%x\n",
+   __func__, hba->outstanding_reqs);
+   break;
+   }
+   }
+
if (!hba->saved_err && !needs_restore)
goto skip_err_handling;
}
@@ -6302,9 +6321,13 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
}
 
-   if (enabled_intr_status && retval == IRQ_NONE) {
-   dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n",
-   __func__, intr_status);
+   if (enabled_intr_status && retval == IRQ_NONE &&
+   !ufshcd_eh_in_progress(hba)) {
+   dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x (0x%08x, 
0x%08x)\n",
+   __func__,
+   intr_status,
+   hba->ufs_stats.last_intr_status,
+   enabled_intr_status);
ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: ");
}
 
@@ -6348,7 +6371,11 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
 * Even though we use wait_event() which sleeps indefinitely,
 * the maximum wait time is bounded by %TM_CMD_TIMEOUT.
 */
-   req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED);
+   req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED |
+   BLK_MQ_REQ_NOWAIT);
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+
req->end_io_data = 
free_slot = req->tag;
WARN_ON_ONCE(free_slot < 0 || free_slot >= hba->nutmrs);
@@ -9355,6 +9382,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem 
*mmio_base, unsigned int irq)
 
hba->tmf_tag_set = (struct blk_mq_tag_set) {
.nr_hw_queues   = 1,
+   .reserved_tags  = 1,
.queue_depth= hba->nutmrs,
.ops= _tmf_ops,
.flags  = BLK_MQ_F_NO_SCHED,
-- 
2.29.2.729.g45daf8777d-goog



[PATCH 1/2] scsi: ufs: fix livelock of ufshcd_clear_ua_wluns

2021-01-06 Thread Jaegeuk Kim
When gate_work/ungate_work gets an error during hibern8_enter or exit,
 ufshcd_err_handler()
   ufshcd_scsi_block_requests()
   ufshcd_reset_and_restore()
 ufshcd_clear_ua_wluns() -> stuck
   ufshcd_scsi_unblock_requests()

In order to avoid it, ufshcd_clear_ua_wluns() can be called per recovery flows
such as suspend/resume, link_recovery, and error_handler.

Fixes: 1918651f2d7e ("scsi: ufs: Clear UAC for RPMB after ufshcd resets")
Signed-off-by: Jaegeuk Kim 
---
 drivers/scsi/ufs/ufshcd.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index bedb822a40a3..1678cec08b51 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3996,6 +3996,8 @@ int ufshcd_link_recovery(struct ufs_hba *hba)
if (ret)
dev_err(hba->dev, "%s: link recovery failed, err %d",
__func__, ret);
+   else
+   ufshcd_clear_ua_wluns(hba);
 
return ret;
 }
@@ -6003,6 +6005,9 @@ static void ufshcd_err_handler(struct work_struct *work)
ufshcd_scsi_unblock_requests(hba);
ufshcd_err_handling_unprepare(hba);
up(>eh_sem);
+
+   if (!err && needs_reset)
+   ufshcd_clear_ua_wluns(hba);
 }
 
 /**
@@ -6940,14 +6945,11 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba 
*hba)
ufshcd_set_clk_freq(hba, true);
 
err = ufshcd_hba_enable(hba);
-   if (err)
-   goto out;
 
/* Establish the link again and restore the device */
-   err = ufshcd_probe_hba(hba, false);
if (!err)
-   ufshcd_clear_ua_wluns(hba);
-out:
+   err = ufshcd_probe_hba(hba, false);
+
if (err)
dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
ufshcd_update_evt_hist(hba, UFS_EVT_HOST_RESET, (u32)err);
@@ -8777,6 +8779,7 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum 
ufs_pm_op pm_op)
ufshcd_resume_clkscaling(hba);
hba->clk_gating.is_suspended = false;
hba->dev_info.b_rpm_dev_flush_capable = false;
+   ufshcd_clear_ua_wluns(hba);
ufshcd_release(hba);
 out:
if (hba->dev_info.b_rpm_dev_flush_capable) {
@@ -8887,6 +8890,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum 
ufs_pm_op pm_op)
cancel_delayed_work(>rpm_dev_flush_recheck_work);
}
 
+   ufshcd_clear_ua_wluns(hba);
+
/* Schedule clock gating in case of no access to UFS device yet */
ufshcd_release(hba);
 
-- 
2.29.2.729.g45daf8777d-goog



[PATCH 1/2] drm/sun4i: tcon: fix inverted DCLK polarity

2021-01-06 Thread Giulio Benetti
During commit "88bc4178568b8e0331143cc0616640ab72f0cba1" DRM_BUS_FLAG_*
macros have been changed to avoid ambiguity but just because of this
ambiguity previous DRM_BUS_FLAG_PIXDATA_(POS/NEG)EDGE were used meaning
_SAMPLE_ not _DRIVE_. This lead to DLCK inversion, so let's swap DCLK
phase to fix it.

Signed-off-by: Giulio Benetti 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index eaaf5d70e352..52598bb0fb0b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -585,10 +585,10 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon 
*tcon,
 * and DOTCLOCK drivers.
 */
if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
-   clk_set_phase(tcon->dclk, 240);
+   clk_set_phase(tcon->dclk, 0);
 
if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
-   clk_set_phase(tcon->dclk, 0);
+   clk_set_phase(tcon->dclk, 240);
 
regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
   SUN4I_TCON0_IO_POL_HSYNC_POSITIVE |
-- 
2.25.1



[PATCH 0/2] drm/sun4i: fix DCLK and improve its handling

2021-01-06 Thread Giulio Benetti
First patch is a tested by me fix, while the second need testing to
understand if it works correctly with any sunxi SoC with DE peripheral.
Already tested SoCs are:
- A20
- A33

Need testing:
- A10
- A10s
- A13

Giulio Benetti (2):
  drm/sun4i: tcon: fix inverted DCLK polarity
  drm/sun4i: tcon: improve DCLK polarity handling

 drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +---
 drivers/gpu/drm/sun4i/sun4i_tcon.h |  1 +
 2 files changed, 2 insertions(+), 19 deletions(-)

-- 
2.25.1



[PATCH 2/2] drm/sun4i: tcon: improve DCLK polarity handling

2021-01-06 Thread Giulio Benetti
It turned out(Maxime suggestion) that bit 26 of SUN4I_TCON0_IO_POL_REG is
dedicated to invert DCLK polarity and this makes thing really easier than
before. So let's handle DCLK polarity by adding
SUN4I_TCON0_IO_POL_DCLK_POSITIVE as bit 26 and activating according to
bus_flags the same way is done for all the other signals.

Cc: Maxime Ripard 
Signed-off-by: Giulio Benetti 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +---
 drivers/gpu/drm/sun4i/sun4i_tcon.h |  1 +
 2 files changed, 2 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 52598bb0fb0b..30171ccd87e5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -569,26 +569,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon 
*tcon,
if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
val |= SUN4I_TCON0_IO_POL_DE_NEGATIVE;
 
-   /*
-* On A20 and similar SoCs, the only way to achieve Positive Edge
-* (Rising Edge), is setting dclk clock phase to 2/3(240°).
-* By default TCON works in Negative Edge(Falling Edge),
-* this is why phase is set to 0 in that case.
-* Unfortunately there's no way to logically invert dclk through
-* IO_POL register.
-* The only acceptable way to work, triple checked with scope,
-* is using clock phase set to 0° for Negative Edge and set to 240°
-* for Positive Edge.
-* On A33 and similar SoCs there would be a 90° phase option,
-* but it divides also dclk by 2.
-* Following code is a way to avoid quirks all around TCON
-* and DOTCLOCK drivers.
-*/
if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
-   clk_set_phase(tcon->dclk, 0);
-
-   if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
-   clk_set_phase(tcon->dclk, 240);
+   val |= SUN4I_TCON0_IO_POL_DCLK_POSITIVE;
 
regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
   SUN4I_TCON0_IO_POL_HSYNC_POSITIVE |
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index cfbf4e6c1679..0ce71d10a31b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -113,6 +113,7 @@
 #define SUN4I_TCON0_IO_POL_REG 0x88
 #define SUN4I_TCON0_IO_POL_DCLK_PHASE(phase)   ((phase & 3) << 28)
 #define SUN4I_TCON0_IO_POL_DE_NEGATIVE BIT(27)
+#define SUN4I_TCON0_IO_POL_DCLK_POSITIVE   BIT(26)
 #define SUN4I_TCON0_IO_POL_HSYNC_POSITIVE  BIT(25)
 #define SUN4I_TCON0_IO_POL_VSYNC_POSITIVE  BIT(24)
 
-- 
2.25.1



Re: [PATCH] mm/memcontrol: fix warning in mem_cgroup_page_lruvec()

2021-01-06 Thread Andrew Morton
On Wed, 6 Jan 2021 14:49:35 +0800 Baoquan He  wrote:

> > Fixes: 9a1ac2288cf1 ("mm/memcontrol:rewrite mem_cgroup_page_lruvec()")
> 
> ...
>
> Thanks for fixing this. We also encountered this issue in kdump kernel
> with the mainline 5.10 kernel since 'cgroup_disable=memory' is added.

Wait.  9a1ac2288cf1 isn't present in 5.10?


Re: [PATCH] rxrpc: fix handling of an unsupported token type in rxrpc_read()

2021-01-06 Thread Tom Rix


On 1/6/21 9:40 AM, David Howells wrote:
> David Howells  wrote:
>
>> How about this?
>> ...
>> Fix the second loop so that it doesn't encode the size and type of an
>> unsupported token, but rather just ignore it as does the first loop.
> Actually, a better way is probably just to error out in this case.  This
> should only happen if a new token type is incompletely implemented.
>
> David
> ---
> commit e68ef16f59aa57564761b21e5ecb2ebbd72d1c57
> Author: David Howells 
> Date:   Wed Jan 6 16:21:40 2021 +
>
> rxrpc: Fix handling of an unsupported token type in rxrpc_read()
> 
> Clang static analysis reports the following:
> 
> net/rxrpc/key.c:657:11: warning: Assigned value is garbage or undefined
> toksize = toksizes[tok++];
> ^ ~~~
> 
> rxrpc_read() contains two consecutive loops.  The first loop calculates 
> the
> token sizes and stores the results in toksizes[] and the second one uses
> the array.  When there is an error in identifying the token in the first
> loop, the token is skipped, no change is made to the toksizes[] array.
> When the same error happens in the second loop, the token is not skipped.
> This will cause the toksizes[] array to be out of step and will overrun
> past the calculated sizes.
> 
> Fix this by making both loops log a message and return an error in this
> case.  This should only happen if a new token type is incompletely
> implemented, so it should normally be impossible to trigger this.
> 
> Fixes: 9a059cd5ca7d ("rxrpc: Downgrade the BUG() for unsupported token 
> type in rxrpc_read()")
> Reported-by: Tom Rix 
> Signed-off-by: David Howells 
>
> diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
> index 9631aa8543b5..8d2073e0e3da 100644
> --- a/net/rxrpc/key.c
> +++ b/net/rxrpc/key.c
> @@ -598,7 +598,7 @@ static long rxrpc_read(const struct key *key,
>   default: /* we have a ticket we can't encode */
>   pr_err("Unsupported key token type (%u)\n",
>  token->security_index);
> - continue;
> + return -ENOPKG;
>   }

These two loops iterate over the same data, i believe returning here is all 
that is needed.

Tom

>  
>   _debug("token[%u]: toksize=%u", ntoks, toksize);
> @@ -674,7 +674,9 @@ static long rxrpc_read(const struct key *key,
>   break;
>  
>   default:
> - break;
> + pr_err("Unsupported key token type (%u)\n",
> +token->security_index);
> + return -ENOPKG;
>   }
>  
>   ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
>



[PATCH 1/2] scsi: ufs: fix livelock of ufshcd_clear_ua_wluns

2021-01-06 Thread Jaegeuk Kim
When gate_work/ungate_work gets an error during hibern8_enter or exit,
 ufshcd_err_handler()
   ufshcd_scsi_block_requests()
   ufshcd_reset_and_restore()
 ufshcd_clear_ua_wluns() -> stuck
   ufshcd_scsi_unblock_requests()

In order to avoid it, ufshcd_clear_ua_wluns() can be called per recovery flows
such as suspend/resume, link_recovery, and error_handler.

Fixes: 1918651f2d7e ("scsi: ufs: Clear UAC for RPMB after ufshcd resets")
Signed-off-by: Jaegeuk Kim 
---
 drivers/scsi/ufs/ufshcd.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index bedb822a40a3..1678cec08b51 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3996,6 +3996,8 @@ int ufshcd_link_recovery(struct ufs_hba *hba)
if (ret)
dev_err(hba->dev, "%s: link recovery failed, err %d",
__func__, ret);
+   else
+   ufshcd_clear_ua_wluns(hba);
 
return ret;
 }
@@ -6003,6 +6005,9 @@ static void ufshcd_err_handler(struct work_struct *work)
ufshcd_scsi_unblock_requests(hba);
ufshcd_err_handling_unprepare(hba);
up(>eh_sem);
+
+   if (!err && needs_reset)
+   ufshcd_clear_ua_wluns(hba);
 }
 
 /**
@@ -6940,14 +6945,11 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba 
*hba)
ufshcd_set_clk_freq(hba, true);
 
err = ufshcd_hba_enable(hba);
-   if (err)
-   goto out;
 
/* Establish the link again and restore the device */
-   err = ufshcd_probe_hba(hba, false);
if (!err)
-   ufshcd_clear_ua_wluns(hba);
-out:
+   err = ufshcd_probe_hba(hba, false);
+
if (err)
dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
ufshcd_update_evt_hist(hba, UFS_EVT_HOST_RESET, (u32)err);
@@ -8777,6 +8779,7 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum 
ufs_pm_op pm_op)
ufshcd_resume_clkscaling(hba);
hba->clk_gating.is_suspended = false;
hba->dev_info.b_rpm_dev_flush_capable = false;
+   ufshcd_clear_ua_wluns(hba);
ufshcd_release(hba);
 out:
if (hba->dev_info.b_rpm_dev_flush_capable) {
@@ -8887,6 +8890,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum 
ufs_pm_op pm_op)
cancel_delayed_work(>rpm_dev_flush_recheck_work);
}
 
+   ufshcd_clear_ua_wluns(hba);
+
/* Schedule clock gating in case of no access to UFS device yet */
ufshcd_release(hba);
 
-- 
2.29.2.729.g45daf8777d-goog



Re: [PATCH 0/5] virtio/vsock: introduce SOCK_SEQPACKET support.

2021-01-06 Thread Arseny Krasnov
> Hi Arseny, thanks for your work on this!
> I did a small review in a hope it helps.
> Also it may be cool to have the driver feature
> for that (so that the host can see if its supported).
> But I guess this was already said by Michael. :)

Hello, thank You for your review, i'll prepare
v2 as soon as possible.




Re: [PATCH] mm/memcontrol: fix warning in mem_cgroup_page_lruvec()

2021-01-06 Thread Andrew Morton
On Wed, 6 Jan 2021 14:49:35 +0800 Baoquan He  wrote:

> > --- 5.11-rc2/include/linux/memcontrol.h 2020-12-27 20:39:36.751923135 
> > -0800
> > +++ linux/include/linux/memcontrol.h2021-01-03 19:38:24.822978559 
> > -0800
> > @@ -665,7 +665,7 @@ static inline struct lruvec *mem_cgroup_
> >  {
> > struct mem_cgroup *memcg = page_memcg(page);
> >  
> > -   VM_WARN_ON_ONCE_PAGE(!memcg, page);
> > +   VM_WARN_ON_ONCE_PAGE(!memcg && !mem_cgroup_disabled(), page);
> > return mem_cgroup_lruvec(memcg, pgdat);
> 
> Thanks for fixing this. We also encountered this issue in kdump kernel
> with the mainline 5.10 kernel since 'cgroup_disable=memory' is added.

Thanks - I added the cc:stable.


Re: [PATCH v2 2/6] mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page

2021-01-06 Thread Mike Kravetz
On 1/6/21 8:35 AM, Michal Hocko wrote:
> On Wed 06-01-21 16:47:35, Muchun Song wrote:
>> Because we only can isolate a active page via isolate_huge_page()
>> and hugetlbfs_fallocate() forget to mark it as active, we cannot
>> isolate and migrate those pages.
> 
> I've little bit hard time to understand this initially and had to dive
> into the code to make sense of it. I would consider the following
> wording easier to grasp. Feel free to reuse if you like.
> "
> If a new hugetlb page is allocated during fallocate it will not be
> marked as active (set_page_huge_active) which will result in a later
> isolate_huge_page failure when the page migration code would like to
> move that page. Such a failure would be unexpected and wrong.
> "
> 
> Now to the fix. I believe that this patch shows that the
> set_page_huge_active is just too subtle. Is there any reason why we
> cannot make all freshly allocated huge pages active by default?

I looked into that yesterday.  The primary issue is in page fault code,
hugetlb_no_page is an example.  If page_huge_active is set, then it can
be isolated for migration.  So, migration could race with the page fault
and the page could be migrated before being added to the page table of
the faulting task.  This was an issue when hugetlb_no_page set_page_huge_active
right after allocating and clearing the huge page.  Commit cb6acd01e2e4
moved the set_page_huge_active after adding the page to the page table
to address this issue.
-- 
Mike Kravetz


Re: [PATCH] media: zr364xx: fix memory leaks in probe()

2021-01-06 Thread Dan Carpenter
On Wed, Jan 06, 2021 at 11:45:50AM -0500, Alan Stern wrote:
> On Wed, Jan 06, 2021 at 01:10:05PM +0300, Dan Carpenter wrote:
> > Syzbot discovered that the probe error handling doesn't clean up the
> > resources allocated in zr364xx_board_init().  There are several
> > related bugs in this code so I have re-written the error handling.
> 
> Dan:
> 
> I recently sent in a patch for a similar problem in the gspca driver
> (commit e469d0b09a19 "media: gspca: Fix memory leak in probe").  It
> seems there may be similar issues in that driver: one single function
> call tries to undo an indeterminate number of initializations.
> 
> I don't know enough about these subsystems to evaluate this.  Can you
> take a look at it?
> 

The probe error handling in gspca_dev_probe2() is fine now.  All those
functions are no-ops when they haven't been allocated/registered.

regards,
dan carpenter



Re: [PATCH 4/5] af_vsock: add socket ops for SOCK_SEQPACKET.

2021-01-06 Thread Arseny Krasnov
> Is ENODEV the right error here?
> Just a quick look at a man page, and
> I am under impression something like
> EPROTONOSUPPORT or ESOCKNOSUPPORT
> may suit?

I used ENODEV because this code is returned some
lines below when !new_transport(e.g. valid transport
not found). But i think you codes will be also ok.



Re: [PATCH net-next] net: broadcom: Drop OF dependency from BGMAC_PLATFORM

2021-01-06 Thread Randy Dunlap
On 1/6/21 11:15 AM, Florian Fainelli wrote:
> All of the OF code that is used has stubbed and will compile and link
> just fine, keeping COMPILE_TEST is enough.

Yes, that matches my understanding.

I wish we had a list of which API families have full stub support...

Acked-by: Randy Dunlap 

Thanks.

> Signed-off-by: Florian Fainelli 
> ---
>  drivers/net/ethernet/broadcom/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/broadcom/Kconfig 
> b/drivers/net/ethernet/broadcom/Kconfig
> index 7b79528d6eed..4bdf8fbe75a6 100644
> --- a/drivers/net/ethernet/broadcom/Kconfig
> +++ b/drivers/net/ethernet/broadcom/Kconfig
> @@ -174,7 +174,6 @@ config BGMAC_BCMA
>  config BGMAC_PLATFORM
>   tristate "Broadcom iProc GBit platform support"
>   depends on ARCH_BCM_IPROC || COMPILE_TEST
> - depends on OF
>   select BGMAC
>   select PHYLIB
>   select FIXED_PHY
> 


-- 
~Randy


Re: [PATCH 1/5] vsock/virtio: support for SOCK_SEQPACKET socket.

2021-01-06 Thread Arseny Krasnov
> IMHO you can avoid this special-casing
> by introducing yet another outer loop just
> for draining the extra data from buffer.
> Admittedly that may also require an extra
> transport op.

I'm not sure that extra tranport op is needed, may be i'll
try to put drain code inside copy loop, because only
difference is that copy length is 0.

> Why do you need this change?
> (maybe its ok, just wondering)

> No need to reset here, like a few lines
> above in a seemingly similar condition?


Yes, i think you are right. 



Re: [PATCH] module: harden ELF info handling

2021-01-06 Thread Frank van der Linden
On Tue, Jan 05, 2021 at 02:39:28PM +0100, Jessica Yu wrote:
> Hi Frank,
> 
> Sorry for the delay. I've just gotten back from vacation :-)

No problem - I figured you were :-)

Comments inline -
> 
> +++ Frank van der Linden [21/12/20 23:49 +]:
> > 5fdc7db644 ("module: setup load info before module_sig_check()")
> > moved the ELF setup, so that it was done before the signature
> > check. This made the module name available to signature error
> > messages.
> > 
> > However, the checks for ELF correctness in setup_load_info
> > are not sufficient to prevent bad memory references due to
> > corrupted offset fields, indices, etc.
> > 
> > So, there's a regression in behavior here: a corrupt and unsigned
> > (or badly signed) module, which might previously have been rejected
> > immediately, can now cause an oops/crash.
> > 
> > Harden ELF handling for module loading by doing the following:
> > 
> > - Move the signature check back up so that it comes before ELF
> >  initialization. It's best to do the signature check to see
> >  if we can trust the module, before using the ELF structures
> >  inside it. This also makes checks against info->len
> >  more accurate again, as this field will be reduced by the
> >  length of the signature in mod_check_sig().
> > 
> >  The module name is now once again not available for error
> >  messages during the signature check, but that seems like
> >  a fair tradeoff.
> 
> I vaguely remember that I had made the module name available in
> response to a one-off request, IIRC someone had wanted the module name
> logged to be able to figure out which module(s) had failed signature
> verification. But I do agree with your line of reasoning, that we
> should probably not access internal module structures until we have
> verified that we can trust the module. It is a chicken and egg problem
> unfortunately. Although, it is probably worth it to trade ease of
> debugging for a more hardened approach.

Cool, thanks, I'm glad you agree/
> 
> > - Check if sections have offset / size fields that at least don't
> >  exceed the length of the module.
> > 
> > - Check if sections have section name offsets that don't fall
> >  outside the section name table.
> > 
> > - Add a few other sanity checks against invalid section indices,
> >  etc.
> > 
> > This is not an exhaustive consistency check, but the idea is to
> > at least get through the signature and blacklist checks without
> > crashing because of corrupted ELF info, and to error out gracefully
> > for most issues that would have caused problems later on.
> > 
> > Fixes: 5fdc7db644 ("module: setup load info before module_sig_check()")
> > Signed-off-by: Frank van der Linden 
> > ---
> > kernel/module.c   | 143 +-
> > kernel/module_signature.c |   2 +-
> > kernel/module_signing.c   |   2 +-
> > 3 files changed, 126 insertions(+), 21 deletions(-)
> > 
> > diff --git a/kernel/module.c b/kernel/module.c
> > index 4bf30e4b3eaa..ef7681a22a1a 100644
> > --- a/kernel/module.c
> > +++ b/kernel/module.c
> > @@ -2964,7 +2964,7 @@ static int module_sig_check(struct load_info *info, 
> > int flags)
> >   }
> > 
> >   if (is_module_sig_enforced()) {
> > -  pr_notice("%s: loading of %s is rejected\n", info->name, 
> > reason);
> > +  pr_notice("loading of %s is rejected\n", reason);
> 
> Small nit: Let's start with a capital letter perhaps? Just to be
> consistent with the other log messages that don't start with a prefix.
> Same goes for the other pr_err()s below.

Sure, will do.

> 
> >   return -EKEYREJECTED;
> >   }
> > 
> > @@ -2977,9 +2977,33 @@ static int module_sig_check(struct load_info *info, 
> > int flags)
> > }
> > #endif /* !CONFIG_MODULE_SIG */
> > 
> > -/* Sanity checks against invalid binaries, wrong arch, weird elf version. 
> > */
> > -static int elf_header_check(struct load_info *info)
> > +static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr)
> > {
> > +  unsigned long secend;
> > +
> > +  /*
> > +   * Check for both overflow and offset/size being
> > +   * too large.
> > +   */
> > +  secend = shdr->sh_offset + shdr->sh_size;
> > +  if (secend < shdr->sh_offset || secend >= info->len)
> 
> Should this not be secend > info->len?

Yep, good catch, will fix that.

> 
> > +  return -ENOEXEC;
> > +
> > +  return 0;
> > +}
> > +
> > +/*
> > + * Sanity checks against invalid binaries, wrong arch, weird elf version.
> > + *
> > + * Also do basic validity checks against section offsets and sizes, the
> > + * section name string table, and the indices used for it (sh_name).
> > + */
> > +static int elf_validity_check(struct load_info *info)
> > +{
> > +  unsigned int i;
> > +  Elf_Shdr *shdr, *strhdr;
> > +  int err;
> > +
> >   if (info->len < sizeof(*(info->hdr)))
> >   return -ENOEXEC;
> > 
> > @@ -2989,11 +3013,78 @@ static int elf_header_check(struct 

Re: [GIT PULL] Btrfs fixes for 5.11-rc3

2021-01-06 Thread pr-tracker-bot
The pull request you sent on Wed,  6 Jan 2021 12:48:12 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-5.11-rc2-tag

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/71c061d2443814de15e177489d5cc00a4a253ef3

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


Re: (hid-logitech) Support for non-DJ receivers

2021-01-06 Thread Filipe Laíns
On Wed, 2021-01-06 at 20:16 +0100, Hans de Goede wrote:
> Hi Filipe,
> 
> hid-logitech-dj already supports exposing devices behind a non-DJ / non-
> unifying
> receiver as separate HID child-devices of the receiver as we doe for DJ
> devices.
> 
> ATM hid-logitech-dj does not yet support the c541 PID receiver, but with some
> luck that could be as simple as adding this patch to the kernel:
> 
> diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
> index 1ffcfc9a1e03..ee7051f3c926 100644
> --- a/drivers/hid/hid-logitech-dj.c
> +++ b/drivers/hid/hid-logitech-dj.c
> @@ -1877,6 +1877,10 @@ static const struct hid_device_id logi_dj_receivers[] =
> {
>   HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
> USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
>  .driver_data = recvr_type_gaming_hidpp},
> +   { /* Logitech lightspeed receiver (0xc541) */
> + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
> +   0xc541),
> +    .driver_data = recvr_type_gaming_hidpp},
> { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
>   HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
> USB_DEVICE_ID_MX3000_RECEIVER),
>  .driver_data = recvr_type_27mhz},
> 
> Where the second 0xc541 should really be a
> USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 define in hid-ids.h, but
> we
> can fix that when upstreaming this.
> 
> For now if you can get the reporter of the bug to build a kernel with the
> above change and test that, then that would be great. If things do not work
> OOTB with this change, then we may need to do some additional work on
> the kernel side, but we do already support lightspeed receivers, so
> we should be able to add support for this new model too.
> 
> Regards,
> 
> Hans
> 
> [1] https://github.com/libratbag/libratbag/pull/1071
> 
> 
> 

Great to know!

I have that device, I can try it out and send a patch if everything is working
correctly :)

The lightspeed receivers we support all have the DJ interface, these new ones do
not. But yeah, I think it should just work, or at least be simple to make it
work.

Cheers,
Filipe Laíns


signature.asc
Description: This is a digitally signed message part


Re: [RFC 0/3] mm, slab, slub: remove cpu and memory hotplug locks

2021-01-06 Thread Christoph Lameter
On Wed, 6 Jan 2021, Vlastimil Babka wrote:

> rather accept some wasted memory in scenarios that should be rare anyway (full
> memory hot remove), as we do the same in other contexts already. It's all RFC
> for now, as I might have missed some reason why it's not safe.

Looks good to me. My only concern is the kernel that has hotplug disabled.
Current code allows the online/offline checks to be optimized away.

Can this patch be enhanced to do the same?



Re: [PATCH v2 0/6] brcmstb: add EP regulators and panic handler

2021-01-06 Thread Bjorn Helgaas
On Mon, Nov 30, 2020 at 04:11:37PM -0500, Jim Quinlan wrote:
> v2 -- Use regulator bulk API rather than multiple calls (MarkB).
> 
> v1 -- Bindings are added for fixed regulators that may power the EP device.
>-- The brcmstb RC driver is modified to control these regulators
>   during probe, suspend, and resume.
>-- 7216 type SOCs have additional error reporting HW and a
>   panic handler is added to dump its info.
>-- A missing return value check is added.
> 
> 
> Jim Quinlan (6):
>   dt-bindings: PCI: Add bindings for Brcmstb EP voltage regulators
>   PCI: brcmstb: Add control of EP voltage regulator(s)
>   PCI: brcmstb: Do not turn off regulators if EP can wake up
>   PCI: brcmstb: Give 7216 SOCs their own config type
>   PCI: brcmstb: Add panic/die handler to RC driver
>   PCI: brcmstb: check return value of clk_prepare_enable()

If/when you repost this, capitalize the subjects consistently.

>  .../bindings/pci/brcm,stb-pcie.yaml   |  12 +
>  drivers/pci/controller/pcie-brcmstb.c | 219 +-
>  2 files changed, 228 insertions(+), 3 deletions(-)
> 
> -- 
> 2.17.1
> 




Re: [PATCH v2 5/6] PCI: brcmstb: Add panic/die handler to RC driver

2021-01-06 Thread Bjorn Helgaas
On Mon, Nov 30, 2020 at 04:11:42PM -0500, Jim Quinlan wrote:
> Whereas most PCIe HW returns 0x on illegal accesses and the like,
> by default Broadcom's STB PCIe controller effects an abort.  This simple
> handler determines if the PCIe controller was the cause of the abort and if
> so, prints out diagnostic info.
> 
> Example output:
>   brcm-pcie 8b2.pcie: Error: Mem Acc: 32bit, Read, @0x3800
>   brcm-pcie 8b2.pcie:  Type: TO=0 Abt=0 UnspReq=1 AccDsble=0 BadAddr=0

What does this mean for all the other PCI core code that expects
0x data returns?  Does it work?  Does it break differently on
STB than on other platforms?

> +/*
> + * Dump out pcie errors on die or panic.

s/pcie/PCIe/
This could be a single-line comment.

> + */


Re: (hid-logitech) Support for non-DJ receivers

2021-01-06 Thread Hans de Goede
Hi Filipe,

On 1/6/21 8:07 PM, Filipe Laíns wrote:
> Hey,
> 
> Some of the new Logitech receivers do not have the DJ interface, this creates 
> an
> issue userspace applications like libratbag, as seen in [1], because we can't
> identify the device based on the hidraw PID.
> 
> There are two solutions for this:
> 
> 1) Implement device discovery via the internal Logitech ID in libratbag and 
> all
> other userspace apps.
> 
> 2) Make hid-logitech-dj export a duplicated hidraw node with internal Logitech
> ID as PID, just like it does for the DJ interface.
> 
> In case you aren't aware of what the DJ interface is, it is essentially a
> multiplexing protocol that receivers support. 6 devices could be connected to
> the same receiver, hid-logitech-dj enables the DJ mode and the receiver will
> essentially perpend the device ID to each HID report. hid-logitech-dj then
> creates a HID device for each connected device and routes the HID reports to 
> the
> correspondent HID device.
> 
> Option 2) would be the easier on userspace, as it keeps the same interface we
> use for DJ receivers for other Logitech HID++ receivers and avoids all 
> userspace
> apps to have to reimplement the same discovery logic.
> 
> Any thoughts?

hid-logitech-dj already supports exposing devices behind a non-DJ / non-unifying
receiver as separate HID child-devices of the receiver as we doe for DJ devices.

ATM hid-logitech-dj does not yet support the c541 PID receiver, but with some
luck that could be as simple as adding this patch to the kernel:

diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 1ffcfc9a1e03..ee7051f3c926 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -1877,6 +1877,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
 .driver_data = recvr_type_gaming_hidpp},
+   { /* Logitech lightspeed receiver (0xc541) */
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
+   0xc541),
+.driver_data = recvr_type_gaming_hidpp},
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
 .driver_data = recvr_type_27mhz},

Where the second 0xc541 should really be a
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 define in hid-ids.h, but we
can fix that when upstreaming this.

For now if you can get the reporter of the bug to build a kernel with the
above change and test that, then that would be great. If things do not work
OOTB with this change, then we may need to do some additional work on
the kernel side, but we do already support lightspeed receivers, so
we should be able to add support for this new model too.

Regards,

Hans

[1] https://github.com/libratbag/libratbag/pull/1071





Re: [PATCH] HID: logitech-hidpp: add support for Unified Battery (1004) feature

2021-01-06 Thread Bastien Nocera
On Wed, 2021-01-06 at 18:48 +, Filipe Laíns wrote:
> On Wed, 2021-01-06 at 10:34 +0100, Bastien Nocera wrote:
> > On Mon, 2021-01-04 at 18:29 +, la...@archlinux.org wrote:
> > > From: Filipe Laíns 
> > > 
> > > This new feature present in new devices replaces the old Battery
> > > Level
> > > Status (0x1000) feature. It keeps essentially the same
> > > information
> > > for
> > > levels (reporting critical, low, good and full) but makes these
> > > levels
> > > optional, the device exports a capability setting which describes
> > > which
> > > levels it supports. In addition to this, there is an optional
> > > state_of_charge paramenter that exports the battery percentage.
> > > 
> > > This patch adds support for this new feature. There were some
> > > implementation choices, as described below and in the code.
> > > 
> > > If the device supports the state_of_charge parameter, we will
> > > just
> > > export the battery percentage and not the levels, which the
> > > device
> > > might
> > > still support.
> > 
> > I'm guessing that means no changes needed on the upower side?
> > 
> > Cheers
> > 
> 
> Yes :)
> I tested upower and all works as expected.
> 
> There will still be devices that only support battery voltage, so I
> might
> implement the battery voltage to charge percentage in a future patch.

I sent a WIP patch at the end of November for that, it wasn't even
compile-tested, but might be a good base to start from.

I don't think that I have any hardware that supports that feature in
any case.

Cheers



Re: [PATCH RFC x86/mce] Make mce_timed_out() identify holdout CPUs

2021-01-06 Thread Paul E. McKenney
On Wed, Jan 06, 2021 at 06:39:30PM +, Luck, Tony wrote:
> > The "Timeout: Not all CPUs entered broadcast exception handler" message
> > will appear from time to time given enough systems, but this message does
> > not identify which CPUs failed to enter the broadcast exception handler.
> > This information would be valuable if available, for example, in order to
> > correlated with other hardware-oriented error messages.  This commit
> > therefore maintains a cpumask_t of CPUs that have entered this handler,
> > and prints out which ones failed to enter in the event of a timeout.
> 
> I tried doing this a while back, but found that in my test case where I forced
> an error that would cause both threads from one core to be "missing", the
> output was highly unpredictable. Some random number of extra CPUs were
> reported as missing. After I added some extra breadcrumbs it became clear
> that pretty much all the CPUs (except the missing pair) entered 
> do_machine_check(),
> but some got hung up at various points beyond the entry point. My only theory
> was that they were trying to snoop caches from the dead core (or access some
> other resource held by the dead core) and so they hung too.
> 
> Your code is much neater than mine ... and perhaps works in other cases, but
> maybe the message needs to allow for the fact that some of the cores that
> are reported missing may just be collateral damage from the initial problem.

Understood.  The system is probably not in the best shape if this code
is ever executed, after all.  ;-)

So how about like this?

pr_info("%s: MCE holdout CPUs (may include false positives): %*pbl\n",

Easy enough if so!

> If I get time in the next day or two, I'll run my old test against your code 
> to
> see what happens.

Thank you very much in advance!

For my own testing, is this still the right thing to use?

https://github.com/andikleen/mce-inject

Thanx, Paul


[PATCH net-next] net: broadcom: Drop OF dependency from BGMAC_PLATFORM

2021-01-06 Thread Florian Fainelli
All of the OF code that is used has stubbed and will compile and link
just fine, keeping COMPILE_TEST is enough.

Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/broadcom/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/Kconfig 
b/drivers/net/ethernet/broadcom/Kconfig
index 7b79528d6eed..4bdf8fbe75a6 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -174,7 +174,6 @@ config BGMAC_BCMA
 config BGMAC_PLATFORM
tristate "Broadcom iProc GBit platform support"
depends on ARCH_BCM_IPROC || COMPILE_TEST
-   depends on OF
select BGMAC
select PHYLIB
select FIXED_PHY
-- 
2.25.1



Re: [PATCH RFC x86/mce] Make mce_timed_out() identify holdout CPUs

2021-01-06 Thread Paul E. McKenney
On Wed, Jan 06, 2021 at 07:32:44PM +0100, Borislav Petkov wrote:
> On Wed, Jan 06, 2021 at 09:41:02AM -0800, Paul E. McKenney wrote:
> > The "Timeout: Not all CPUs entered broadcast exception handler" message
> > will appear from time to time given enough systems, but this message does
> > not identify which CPUs failed to enter the broadcast exception handler.
> > This information would be valuable if available, for example, in order to
> > correlated with other hardware-oriented error messages.
> 
> Because you're expecting that the CPUs which have not entered the
> exception handler might have stuck earlier and that's the correlation
> there?

Or that there might have been any number of other error messages that
flagged that CPU.  For a few examples, watchdogs, hung tasks, and RCU
CPU stall warnings.

> > This commit
> 
> That's a tautology. :)

Not yet, it isn't!  Well, except in -rcu.  ;-)

> > therefore maintains a cpumask_t of CPUs that have entered this handler,
> > and prints out which ones failed to enter in the event of a timeout.
> > Build-tested only.
> > 
> > Cc: Tony Luck 
> > Cc: Borislav Petkov 
> > Cc: Thomas Gleixner 
> > Cc: Ingo Molnar 
> > Cc: "H. Peter Anvin" 
> > Cc: 
> > Cc: 
> > Reported-by: Jonathan Lemon 
> > Signed-off-by: Paul E. McKenney 
> > 
> > diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
> > index 13d3f1c..44d2b99 100644
> > --- a/arch/x86/kernel/cpu/mce/core.c
> > +++ b/arch/x86/kernel/cpu/mce/core.c
> > @@ -878,6 +878,12 @@ static atomic_t mce_executing;
> >  static atomic_t mce_callin;
> >  
> >  /*
> > + * Track which CPUs entered and not in order to print holdouts.
> > + */
> > +static cpumask_t mce_present_cpus;
> > +static cpumask_t mce_missing_cpus;
> > +
> > +/*
> >   * Check if a timeout waiting for other CPUs happened.
> >   */
> >  static int mce_timed_out(u64 *t, const char *msg)
> > @@ -894,8 +900,12 @@ static int mce_timed_out(u64 *t, const char *msg)
> > if (!mca_cfg.monarch_timeout)
> > goto out;
> > if ((s64)*t < SPINUNIT) {
> > -   if (mca_cfg.tolerant <= 1)
> > +   if (mca_cfg.tolerant <= 1) {
> > +   if (!cpumask_andnot(_missing_cpus, cpu_online_mask, 
> > _present_cpus))
> > +   pr_info("%s: MCE holdout CPUs: %*pbl\n",
> > +   __func__, 
> > cpumask_pr_args(_missing_cpus));
> > mce_panic(msg, NULL, NULL);
> > +   }
> > cpu_missing = 1;
> > return 1;
> > }
> > @@ -1006,6 +1016,7 @@ static int mce_start(int *no_way_out)
> >  * is updated before mce_callin.
> >  */
> > order = atomic_inc_return(_callin);
> 
> Doesn't a single mce_callin_mask suffice?

You are suggesting dropping mce_missing_cpus and just doing this?

if (!cpumask_andnot(_present_cpus, cpu_online_mask, _present_cpus))

I was worried (perhaps unnecessarily) about the possibility of CPUs
checking in during the printout operation, which would set rather than
clear the bit.  But perhaps the possible false positives that Tony points
out make this race not worth worrying about.

Thoughts?

Thanx, Paul


Re: [PATCH 05/10] dma: tx49 removal

2021-01-06 Thread Joe Perches
On Tue, 2021-01-05 at 15:02 +0100, Thomas Bogendoerfer wrote:
> Signed-off-by: Thomas Bogendoerfer 
[]
> diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h
[]
> @@ -26,11 +26,6 @@
>   * DMA channel.
>   */
>  
> 
> -#ifdef CONFIG_MACH_TX49XX
> -static inline bool txx9_dma_have_SMPCHN(void)
> -{
> - return true;
> -}
>  #define TXX9_DMA_USE_SIMPLE_CHAIN
>  #else
>  static inline bool txx9_dma_have_SMPCHN(void)

This doesn't look like it compiles as there's now an #else
without an #if




(hid-logitech) Support for non-DJ receivers

2021-01-06 Thread Filipe Laíns
Hey,

Some of the new Logitech receivers do not have the DJ interface, this creates an
issue userspace applications like libratbag, as seen in [1], because we can't
identify the device based on the hidraw PID.

There are two solutions for this:

1) Implement device discovery via the internal Logitech ID in libratbag and all
other userspace apps.

2) Make hid-logitech-dj export a duplicated hidraw node with internal Logitech
ID as PID, just like it does for the DJ interface.

In case you aren't aware of what the DJ interface is, it is essentially a
multiplexing protocol that receivers support. 6 devices could be connected to
the same receiver, hid-logitech-dj enables the DJ mode and the receiver will
essentially perpend the device ID to each HID report. hid-logitech-dj then
creates a HID device for each connected device and routes the HID reports to the
correspondent HID device.

Option 2) would be the easier on userspace, as it keeps the same interface we
use for DJ receivers for other Logitech HID++ receivers and avoids all userspace
apps to have to reimplement the same discovery logic.

Any thoughts?

[1] https://github.com/libratbag/libratbag/pull/1071

Cheers,
Filipe Laíns


signature.asc
Description: This is a digitally signed message part


Re: [PATCH -next] pci: hotplug: Use DEFINE_SPINLOCK() for spinlock

2021-01-06 Thread Bjorn Helgaas
On Mon, Dec 28, 2020 at 09:50:38PM +0800, Zheng Yongjun wrote:
> spinlock can be initialized automatically with DEFINE_SPINLOCK()
> rather than explicitly calling spin_lock_init().

See this again:

https://lore.kernel.org/r/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com

> Signed-off-by: Zheng Yongjun 
> ---
>  drivers/pci/hotplug/cpqphp_nvram.c | 5 +
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/hotplug/cpqphp_nvram.c 
> b/drivers/pci/hotplug/cpqphp_nvram.c
> index 00cd2b43364f..7a65d427ac11 100644
> --- a/drivers/pci/hotplug/cpqphp_nvram.c
> +++ b/drivers/pci/hotplug/cpqphp_nvram.c
> @@ -80,7 +80,7 @@ static u8 evbuffer[1024];
>  static void __iomem *compaq_int15_entry_point;
>  
>  /* lock for ordering int15_bios_call() */
> -static spinlock_t int15_lock;
> +static DEFINE_SPINLOCK(int15_lock);
>  
>  
>  /* This is a series of function that deals with
> @@ -415,9 +415,6 @@ void compaq_nvram_init(void __iomem *rom_start)
>   compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - 
> ROM_PHY_ADDR);
>  
>   dbg("int15 entry  = %p\n", compaq_int15_entry_point);
> -
> - /* initialize our int15 lock */
> - spin_lock_init(_lock);
>  }
>  
>  
> -- 
> 2.22.0
> 


Re: [PATCH V3] drm/vkms: Decouple config data for configfs

2021-01-06 Thread Melissa Wen
On 01/05, Sumera Priyadarsini wrote:
> Currently, data for the device instance is held by vkms_device.
> Add a separate type, vkms_config to contain configuration details
> for the device and various modes to be later used by configfs.
> This config data stays constant once the device is created.
> 
> Accordingly, add vkms_create and vkms_destroy to initialize/destroy
> device through configfs. Currently, they are being called from vkms_init
> and vkms_exit, but will be evoked from configfs later on. When configfs
> is added, device configuration will be tracked by configfs and only vkms
> device lifetime will be handled by vkms_init and vkms_exit functions.
> 
> Modify usage of enable_cursor feature to reflect the changes in
> relevant files.
> 
> Add enable_writeback_connector feature to vkms_config type.
> 
> Co-developed-by: Daniel Vetter 
> Signed-off-by: Daniel Vetter 
> Signed-off-by: Sumera Priyadarsini 
> 
> ---
> Changes in v2:
> - add Co-developed-by tag
> 
> Changes in v3:
> - correct usage of Co-developed by tag(Melissa)
> - add enable_writeback_feature(Melissa)
> - modify commit message(Melissa)
> ---
>  drivers/gpu/drm/vkms/vkms_drv.c| 45 --
>  drivers/gpu/drm/vkms/vkms_drv.h| 12 ++--
>  drivers/gpu/drm/vkms/vkms_output.c | 13 +
>  3 files changed, 54 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
> index aef29393b811..fab964900dce 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.c
> +++ b/drivers/gpu/drm/vkms/vkms_drv.c
> @@ -34,12 +34,16 @@
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  
> -static struct vkms_device *vkms_device;
> +static struct vkms_config *default_config;
>  
> -bool enable_cursor = true;
> +static bool enable_cursor = true;
>  module_param_named(enable_cursor, enable_cursor, bool, 0444);
>  MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
>  
> +static bool enable_writeback_connector = true;
> +module_param_named(enable_writeback_connector, enable_writeback_connector, 
> bool, 0444);
> +MODULE_PARM_DESC(enable_writeback_connector, "Enable/Disable writeback 
> connector support");
> +
Even though the limit is now 100 characteres, I consider 'enable_writeback'
enough here. I think removing this _connector suffix doesn't affect the
undestanding and also save some space to avoid break lines in the future

>  DEFINE_DRM_GEM_FOPS(vkms_driver_fops);
>  
>  static void vkms_release(struct drm_device *dev)
> @@ -122,10 +126,11 @@ static int vkms_modeset_init(struct vkms_device 
> *vkmsdev)
>   return vkms_output_init(vkmsdev, 0);
>  }
>  
> -static int __init vkms_init(void)
> +static int vkms_create(struct vkms_config *config)
>  {
>   int ret;
>   struct platform_device *pdev;
> + struct vkms_device *vkms_device;
>  
>   pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
>   if (IS_ERR(pdev))
> @@ -143,6 +148,8 @@ static int __init vkms_init(void)
>   goto out_devres;
>   }
>   vkms_device->platform = pdev;
> + vkms_device->config = config;
> + config->dev = vkms_device;
>  
>   ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
>  DMA_BIT_MASK(64));
> @@ -179,21 +186,43 @@ static int __init vkms_init(void)
>   return ret;
>  }
>  
> -static void __exit vkms_exit(void)
> +static int __init vkms_init(void)
> +{
> + struct vkms_config *config = kmalloc(sizeof(*config), GFP_KERNEL);
> +
> + default_config = config;
> +
> + config->cursor = enable_cursor;
> + config->writeback = enable_writeback_connector;
> +
> + return vkms_create(config);
> +}
> +
> +static void vkms_destroy(struct vkms_config *config)
>  {
>   struct platform_device *pdev;
>  
> - if (!vkms_device) {
> + if (!config->dev) {
>   DRM_INFO("vkms_device is NULL.\n");
>   return;
>   }
>  
> - pdev = vkms_device->platform;
> + pdev = config->dev->platform;
>  
> - drm_dev_unregister(_device->drm);
> - drm_atomic_helper_shutdown(_device->drm);
> + drm_dev_unregister(>dev->drm);
> + drm_atomic_helper_shutdown(>dev->drm);
>   devres_release_group(>dev, NULL);
>   platform_device_unregister(pdev);
> +
> + config->dev = NULL;
> +}
> +
> +static void __exit vkms_exit(void)
> +{
> + if (default_config->dev)
> + vkms_destroy(default_config);
> +
> + kfree(default_config);
>  }
>  
>  module_init(vkms_init);
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index 5ed91ff08cb3..caa1fafb6ca7 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -19,8 +19,6 @@
>  #define XRES_MAX  8192
>  #define YRES_MAX  8192
>  
> -extern bool enable_cursor;
> -
>  struct vkms_composer {
>   struct drm_framebuffer fb;
>   struct drm_rect src, dst;
> @@ -82,10 +80,18 @@ struct vkms_output {
>

Re: [PATCH -next] pci/controller/dwc: convert comma to semicolon

2021-01-06 Thread Bjorn Helgaas
On Wed, Dec 16, 2020 at 09:19:44PM +0800, Zheng Yongjun wrote:
> Replace a comma between expression statements by a semicolon.

Looks like a good fix, but read this about the changelog title:

https://lore.kernel.org/r/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com

> Signed-off-by: Zheng Yongjun 
> ---
>  drivers/pci/controller/dwc/pci-layerscape-ep.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 84206f265e54..917ba8d254fc 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -178,7 +178,7 @@ static int __init ls_pcie_ep_probe(struct platform_device 
> *pdev)
>   pci->dev = dev;
>   pci->ops = pcie->drvdata->dw_pcie_ops;
>  
> - ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> + ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
>  
>   pcie->pci = pci;
>   pcie->ls_epc = ls_epc;
> -- 
> 2.22.0
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH v2 1/2] KVM: x86/mmu: Ensure TDP MMU roots are freed after yield

2021-01-06 Thread Ben Gardon
On Wed, Jan 6, 2021 at 10:59 AM Ben Gardon  wrote:
>
> Many TDP MMU functions which need to perform some action on all TDP MMU
> roots hold a reference on that root so that they can safely drop the MMU
> lock in order to yield to other threads. However, when releasing the
> reference on the root, there is a bug: the root will not be freed even
> if its reference count (root_count) is reduced to 0.
>
> To simplify acquiring and releasing references on TDP MMU root pages, and
> to ensure that these roots are properly freed, move the get/put operations
> into the TDP MMU root iterator macro. Not all functions which use the macro
> currently get and put a reference to the root, but adding this behavior is
> harmless.
>
> Moving the get/put operations into the iterator macro also helps
> simplify control flow when a root does need to be freed. Note that using
> the list_for_each_entry_unsafe macro would not have been appropriate in
> this situation because it could keep a reference to the next root across
> an MMU lock release + reacquire.
>
> Reported-by: Maciej S. Szmigiero 
> Suggested-by: Paolo Bonzini 
> Fixes: faaf05b00aec ("kvm: x86/mmu: Support zapping SPTEs in the TDP MMU")
> Fixes: 063afacd8730 ("kvm: x86/mmu: Support invalidate range MMU notifier for 
> TDP MMU")
> Fixes: a6a0b05da9f3 ("kvm: x86/mmu: Support dirty logging for the TDP MMU")
> Fixes: 14881998566d ("kvm: x86/mmu: Support disabling dirty logging for the 
> tdp MMU")
> Signed-off-by: Ben Gardon 
> ---
>  arch/x86/kvm/mmu/tdp_mmu.c | 97 +-
>  1 file changed, 44 insertions(+), 53 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
> index 75db27fda8f3..6e076b66973c 100644
> --- a/arch/x86/kvm/mmu/tdp_mmu.c
> +++ b/arch/x86/kvm/mmu/tdp_mmu.c
> @@ -44,8 +44,44 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm)
> WARN_ON(!list_empty(>arch.tdp_mmu_roots));
>  }
>
> -#define for_each_tdp_mmu_root(_kvm, _root) \
> -   list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link)
> +static void tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root)
> +{
> +   if (kvm_mmu_put_root(kvm, root))
> +   kvm_tdp_mmu_free_root(kvm, root);
> +}
> +
> +static inline bool tdp_mmu_next_root_valid(struct kvm *kvm,
> +  struct kvm_mmu_page *root)
> +{
> +   if (list_entry_is_head(root, >arch.tdp_mmu_roots, link))
> +   return false;
> +
> +   kvm_mmu_get_root(kvm, root);
> +   return true;
> +
> +}
> +
> +static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
> +struct kvm_mmu_page 
> *root)
> +{
> +   struct kvm_mmu_page *next_root;
> +
> +   next_root = list_next_entry(root, link);
> +   tdp_mmu_put_root(kvm, root);
> +   return next_root;
> +}
> +
> +/*
> + * Note: this iterator gets and puts references to the roots it iterates 
> over.
> + * This makes it safe to release the MMU lock and yield within the loop, but
> + * if exiting the loop early, the caller must drop the reference to the most
> + * recent root. (Unless keeping a live reference is desirable.)
> + */
> +#define for_each_tdp_mmu_root(_kvm, _root) \
> +   for (_root = list_first_entry(&_kvm->arch.tdp_mmu_roots,\
> + typeof(*_root), link);\
> +tdp_mmu_next_root_valid(_kvm, _root);  \
> +_root = tdp_mmu_next_root(_kvm, _root))
>
>  bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa)
>  {
> @@ -128,7 +164,11 @@ static struct kvm_mmu_page *get_tdp_mmu_vcpu_root(struct 
> kvm_vcpu *vcpu)
> /* Check for an existing root before allocating a new one. */
> for_each_tdp_mmu_root(kvm, root) {
> if (root->role.word == role.word) {
> -   kvm_mmu_get_root(kvm, root);
> +   /*
> +* The iterator already acquired a reference to this
> +* root, so simply return early without dropping the
> +* reference.
> +*/
> spin_unlock(>mmu_lock);
> return root;
> }
> @@ -447,18 +487,9 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t 
> start, gfn_t end)
> struct kvm_mmu_page *root;
> bool flush = false;
>
> -   for_each_tdp_mmu_root(kvm, root) {
> -   /*
> -* Take a reference on the root so that it cannot be freed if
> -* this thread releases the MMU lock and yields in this loop.
> -*/
> -   kvm_mmu_get_root(kvm, root);
> -
> +   for_each_tdp_mmu_root(kvm, root)
> flush |= zap_gfn_range(kvm, root, start, end, true);
>
> -   kvm_mmu_put_root(kvm, root);
> -   }
> -
>  

Re: [PATCH 4/6] hugetlb: avoid allocation failed when page reporting is on going

2021-01-06 Thread Alexander Duyck
On Tue, Jan 5, 2021 at 7:50 PM Liang Li  wrote:
>
> Page reporting isolates free pages temporarily when reporting
> free pages information. It will reduce the actual free pages
> and may cause application failed for no enough available memory.
> This patch try to solve this issue, when there is no free page
> and page repoting is on going, wait until it is done.
>
> Cc: Alexander Duyck 

Please don't use this email address for me anymore. Either use
alexander.du...@gmail.com or alexanderdu...@fb.com. I am getting
bounces when I reply to this thread because of the old address.

> Cc: Mel Gorman 
> Cc: Andrea Arcangeli 
> Cc: Dan Williams 
> Cc: Dave Hansen 
> Cc: David Hildenbrand 
> Cc: Michal Hocko 
> Cc: Andrew Morton 
> Cc: Alex Williamson 
> Cc: Michael S. Tsirkin 
> Cc: Liang Li 
> Signed-off-by: Liang Li 
> ---
>  include/linux/hugetlb.h | 2 ++
>  mm/hugetlb.c| 9 +
>  mm/page_reporting.c | 6 +-
>  3 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index d55e6a00b3dc..73b2934ba91c 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -490,6 +490,7 @@ struct hstate {
> unsigned long resv_huge_pages;
> unsigned long surplus_huge_pages;
> unsigned long nr_overcommit_huge_pages;
> +   unsigned long isolated_huge_pages;
> struct list_head hugepage_activelist;
> struct list_head hugepage_freelists[MAX_NUMNODES];
> unsigned int nr_huge_pages_node[MAX_NUMNODES];
> @@ -500,6 +501,7 @@ struct hstate {
> struct cftype cgroup_files_dfl[7];
> struct cftype cgroup_files_legacy[9];
>  #endif
> +   struct mutex mtx_prezero;
> char name[HSTATE_NAME_LEN];
>  };
>
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index eb533995cb49..0fccd5f96954 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -2320,6 +2320,12 @@ struct page *alloc_huge_page(struct vm_area_struct 
> *vma,
> goto out_uncharge_cgroup_reservation;
>
> spin_lock(_lock);
> +   while (h->free_huge_pages <= 1 && h->isolated_huge_pages) {
> +   spin_unlock(_lock);
> +   mutex_lock(>mtx_prezero);
> +   mutex_unlock(>mtx_prezero);
> +   spin_lock(_lock);
> +   }

This seems like a bad idea. It kind of defeats the whole point of
doing the page zeroing outside of the hugetlb_lock. Also it is
operating on the assumption that the only way you might get a page is
from the page zeroing logic.

With the page reporting code we wouldn't drop the count to zero. We
had checks that were going through and monitoring the watermarks and
if we started to hit the low watermark we would stop page reporting
and just assume there aren't enough pages to report. You might need to
look at doing something similar here so that you can avoid colliding
with the allocator.


> /*
>  * glb_chg is passed to indicate whether or not a page must be taken
>  * from the global free pool (global change).  gbl_chg == 0 indicates
> @@ -3208,6 +3214,7 @@ void __init hugetlb_add_hstate(unsigned int order)
> INIT_LIST_HEAD(>hugepage_activelist);
> h->next_nid_to_alloc = first_memory_node;
> h->next_nid_to_free = first_memory_node;
> +   mutex_init(>mtx_prezero);
> snprintf(h->name, HSTATE_NAME_LEN, "hugepages-%lukB",
> huge_page_size(h)/1024);
>
> @@ -5541,6 +5548,7 @@ void isolate_free_huge_page(struct page *page, struct 
> hstate *h, int nid)
>
> list_move(>lru, >hugepage_activelist);
> set_page_refcounted(page);
> +   h->isolated_huge_pages++;
>  }
>
>  void putback_isolate_huge_page(struct hstate *h, struct page *page)
> @@ -5548,6 +5556,7 @@ void putback_isolate_huge_page(struct hstate *h, struct 
> page *page)
> int nid = page_to_nid(page);
>
> list_move(>lru, >hugepage_freelists[nid]);
> +   h->isolated_huge_pages--;
>  }
>
>  bool isolate_huge_page(struct page *page, struct list_head *list)
> diff --git a/mm/page_reporting.c b/mm/page_reporting.c
> index cc31696225bb..99e1e688d7c1 100644
> --- a/mm/page_reporting.c
> +++ b/mm/page_reporting.c
> @@ -272,12 +272,15 @@ hugepage_reporting_process_hstate(struct 
> page_reporting_dev_info *prdev,
> int ret = 0, nid;
>
> offset = max_items;
> +   mutex_lock(>mtx_prezero);
> for (nid = 0; nid < MAX_NUMNODES; nid++) {
> ret = hugepage_reporting_cycle(prdev, h, nid, sgl, ,
>max_items);
>
> -   if (ret < 0)
> +   if (ret < 0) {
> +   mutex_unlock(>mtx_prezero);
> return ret;
> +   }
> }
>
> /* report the leftover pages before going idle */
> @@ -291,6 +294,7 @@ hugepage_reporting_process_hstate(struct 
> page_reporting_dev_info *prdev,
> 

[PATCH v2 1/2] KVM: x86/mmu: Ensure TDP MMU roots are freed after yield

2021-01-06 Thread Ben Gardon
Many TDP MMU functions which need to perform some action on all TDP MMU
roots hold a reference on that root so that they can safely drop the MMU
lock in order to yield to other threads. However, when releasing the
reference on the root, there is a bug: the root will not be freed even
if its reference count (root_count) is reduced to 0.

To simplify acquiring and releasing references on TDP MMU root pages, and
to ensure that these roots are properly freed, move the get/put operations
into the TDP MMU root iterator macro. Not all functions which use the macro
currently get and put a reference to the root, but adding this behavior is
harmless.

Moving the get/put operations into the iterator macro also helps
simplify control flow when a root does need to be freed. Note that using
the list_for_each_entry_unsafe macro would not have been appropriate in
this situation because it could keep a reference to the next root across
an MMU lock release + reacquire.

Reported-by: Maciej S. Szmigiero 
Suggested-by: Paolo Bonzini 
Fixes: faaf05b00aec ("kvm: x86/mmu: Support zapping SPTEs in the TDP MMU")
Fixes: 063afacd8730 ("kvm: x86/mmu: Support invalidate range MMU notifier for 
TDP MMU")
Fixes: a6a0b05da9f3 ("kvm: x86/mmu: Support dirty logging for the TDP MMU")
Fixes: 14881998566d ("kvm: x86/mmu: Support disabling dirty logging for the tdp 
MMU")
Signed-off-by: Ben Gardon 
---
 arch/x86/kvm/mmu/tdp_mmu.c | 97 +-
 1 file changed, 44 insertions(+), 53 deletions(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 75db27fda8f3..6e076b66973c 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -44,8 +44,44 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm)
WARN_ON(!list_empty(>arch.tdp_mmu_roots));
 }
 
-#define for_each_tdp_mmu_root(_kvm, _root) \
-   list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link)
+static void tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root)
+{
+   if (kvm_mmu_put_root(kvm, root))
+   kvm_tdp_mmu_free_root(kvm, root);
+}
+
+static inline bool tdp_mmu_next_root_valid(struct kvm *kvm,
+  struct kvm_mmu_page *root)
+{
+   if (list_entry_is_head(root, >arch.tdp_mmu_roots, link))
+   return false;
+
+   kvm_mmu_get_root(kvm, root);
+   return true;
+
+}
+
+static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
+struct kvm_mmu_page *root)
+{
+   struct kvm_mmu_page *next_root;
+
+   next_root = list_next_entry(root, link);
+   tdp_mmu_put_root(kvm, root);
+   return next_root;
+}
+
+/*
+ * Note: this iterator gets and puts references to the roots it iterates over.
+ * This makes it safe to release the MMU lock and yield within the loop, but
+ * if exiting the loop early, the caller must drop the reference to the most
+ * recent root. (Unless keeping a live reference is desirable.)
+ */
+#define for_each_tdp_mmu_root(_kvm, _root) \
+   for (_root = list_first_entry(&_kvm->arch.tdp_mmu_roots,\
+ typeof(*_root), link);\
+tdp_mmu_next_root_valid(_kvm, _root);  \
+_root = tdp_mmu_next_root(_kvm, _root))
 
 bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa)
 {
@@ -128,7 +164,11 @@ static struct kvm_mmu_page *get_tdp_mmu_vcpu_root(struct 
kvm_vcpu *vcpu)
/* Check for an existing root before allocating a new one. */
for_each_tdp_mmu_root(kvm, root) {
if (root->role.word == role.word) {
-   kvm_mmu_get_root(kvm, root);
+   /*
+* The iterator already acquired a reference to this
+* root, so simply return early without dropping the
+* reference.
+*/
spin_unlock(>mmu_lock);
return root;
}
@@ -447,18 +487,9 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t 
start, gfn_t end)
struct kvm_mmu_page *root;
bool flush = false;
 
-   for_each_tdp_mmu_root(kvm, root) {
-   /*
-* Take a reference on the root so that it cannot be freed if
-* this thread releases the MMU lock and yields in this loop.
-*/
-   kvm_mmu_get_root(kvm, root);
-
+   for_each_tdp_mmu_root(kvm, root)
flush |= zap_gfn_range(kvm, root, start, end, true);
 
-   kvm_mmu_put_root(kvm, root);
-   }
-
return flush;
 }
 
@@ -620,12 +651,6 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, 
unsigned long start,
int as_id;
 
for_each_tdp_mmu_root(kvm, root) {
-   /*
-* Take a reference on the root so that it cannot be 

[PATCH v2 2/2] KVM: x86/mmu: Clarify TDP MMU page list invariants

2021-01-06 Thread Ben Gardon
The tdp_mmu_roots and tdp_mmu_pages in struct kvm_arch should only contain
pages with tdp_mmu_page set to true. tdp_mmu_pages should not contain any
pages with a non-zero root_count and tdp_mmu_roots should only contain
pages with a positive root_count, unless a thread holds the MMU lock and
is in the process of modifying the list. Various functions expect these
invariants to be maintained, but they are not explictily documented. Add
to the comments on both fields to document the above invariants.

Signed-off-by: Ben Gardon 
---
 arch/x86/include/asm/kvm_host.h | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 39707e72b062..2389735a29f3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1010,9 +1010,21 @@ struct kvm_arch {
 */
bool tdp_mmu_enabled;
 
-   /* List of struct tdp_mmu_pages being used as roots */
+   /*
+* List of struct tdp_mmu_pages being used as roots.
+* All struct kvm_mmu_pages in the list should have
+* tdp_mmu_page set.
+* All struct kvm_mmu_pages in the list should have a positive
+* root_count except when a thread holds the MMU lock and is removing
+* an entry from the list.
+*/
struct list_head tdp_mmu_roots;
-   /* List of struct tdp_mmu_pages not being used as roots */
+
+   /*
+* List of struct tdp_mmu_pages not being used as roots.
+* All struct kvm_mmu_pages in the list should have
+* tdp_mmu_page set and a root_count of 0.
+*/
struct list_head tdp_mmu_pages;
 };
 
-- 
2.29.2.729.g45daf8777d-goog



Re: [RFC PATCH v3 5/6] dt-bindings: of: Add restricted DMA pool

2021-01-06 Thread Konrad Rzeszutek Wilk
On Wed, Jan 06, 2021 at 11:41:23AM +0800, Claire Chang wrote:
> Introduce the new compatible string, restricted-dma-pool, for restricted
> DMA. One can specify the address and length of the restricted DMA memory
> region by restricted-dma-pool in the device tree.
> 
> Signed-off-by: Claire Chang 
> ---
>  .../reserved-memory/reserved-memory.txt   | 24 +++
>  1 file changed, 24 insertions(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt 
> b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> index e8d3096d922c..44975e2a1fd2 100644
> --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> @@ -51,6 +51,20 @@ compatible (optional) - standard definition
>used as a shared pool of DMA buffers for a set of devices. It can
>be used by an operating system to instantiate the necessary pool
>management subsystem if necessary.
> +- restricted-dma-pool: This indicates a region of memory meant to be
> +  used as a pool of restricted DMA buffers for a set of devices. The
> +  memory region would be the only region accessible to those devices.
> +  When using this, the no-map and reusable properties must not be 
> set,
> +  so the operating system can create a virtual mapping that will be 
> used
> +  for synchronization. The main purpose for restricted DMA is to
> +  mitigate the lack of DMA access control on systems without an 
> IOMMU,
> +  which could result in the DMA accessing the system memory at
> +  unexpected times and/or unexpected addresses, possibly leading to 
> data
> +  leakage or corruption. The feature on its own provides a basic 
> level
> +  of protection against the DMA overwriting buffer contents at
> +  unexpected times. However, to protect against general data leakage 
> and
> +  system memory corruption, the system needs to provide way to 
> restrict
> +  the DMA to a predefined memory region.

Heya!

I think I am missing something obvious here so please bear with my
questions:

 - This code adds the means of having the SWIOTLB pool tied to a specific
   memory correct?

 - Nothing stops the physical device from bypassing the SWIOTLB buffer.
   That is if an errant device screwed up the length or DMA address, the
   SWIOTLB would gladly do what the device told it do?

 - This has to be combined with SWIOTLB-force-ish to always use the
   bounce buffer, otherwise you could still do DMA without using
   SWIOTLB (by not hitting the criteria for needing to use SWIOTLB)?


Re: [RFC PATCH v3 2/6] swiotlb: Add restricted DMA pool

2021-01-06 Thread Konrad Rzeszutek Wilk
Hello!

In this file:

> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index e4368159f88a..7fb2ac087d23 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
..

> +static const struct reserved_mem_ops rmem_swiotlb_ops = {
> + .device_init= rmem_swiotlb_device_init,
> + .device_release = rmem_swiotlb_device_release,
> +};
> +
> +static int __init rmem_swiotlb_setup(struct reserved_mem *rmem)
> +{
> + unsigned long node = rmem->fdt_node;
> +
> + if (of_get_flat_dt_prop(node, "reusable", NULL) ||
> + of_get_flat_dt_prop(node, "linux,cma-default", NULL) ||
> + of_get_flat_dt_prop(node, "linux,dma-default", NULL) ||
> + of_get_flat_dt_prop(node, "no-map", NULL))
> + return -EINVAL;
> +
> + rmem->ops = _swiotlb_ops;
> + pr_info("Reserved memory: created device swiotlb memory pool at %pa, 
> size %ld MiB\n",
> + >base, (unsigned long)rmem->size / SZ_1M);
> + return 0;
> +}
> +
> +RESERVEDMEM_OF_DECLARE(dma, "restricted-dma-pool", rmem_swiotlb_setup);

The code should be as much as possible arch-agnostic. That is why there
are multiple -swiotlb files scattered in arch directories that own the
architecture specific code.

Would it be possible to move the code there and perhaps have a ARM
specific front-end for this DMA restricted pool there? See for example
the xen-swiotlb code.

Cheers!

Konrad


Re: [PATCH] of: property: Add device link support for interrupts

2021-01-06 Thread Saravana Kannan
On Sat, Jan 2, 2021 at 3:37 AM Marc Zyngier  wrote:
>
> On Thu, 31 Dec 2020 21:12:40 +,
> Rob Herring  wrote:
> >
> > On Mon, Dec 21, 2020 at 09:30:45AM +, Marc Zyngier wrote:
> > > On 2020-12-18 21:07, Saravana Kannan wrote:
> > > > Add support for creating device links out of interrupts property.
> > > >
> > > > Cc: Marc Zyngier 
> > > > Cc: Kevin Hilman 
> > > > Signed-off-by: Saravana Kannan 
> > > > ---
> > > > Rob/Greg,
> > > >
> > > > This might need to go into driver-core to avoid conflict
> > > > due to fw_devlink refactor series that merged there.
> > > >
> > > > Thanks,
> > > > Saravana
> > > >
> > > >
> > > >  drivers/of/property.c | 17 +
> > > >  1 file changed, 17 insertions(+)
> > > >
> > > > diff --git a/drivers/of/property.c b/drivers/of/property.c
> > > > index 5f9eed79a8aa..e56a5eae0a0b 100644
> > > > --- a/drivers/of/property.c
> > > > +++ b/drivers/of/property.c
> > > > @@ -1271,6 +1271,22 @@ static struct device_node
> > > > *parse_iommu_maps(struct device_node *np,
> > > >   return of_parse_phandle(np, prop_name, (index * 4) + 1);
> > > >  }
> > > >
> > > > +static struct device_node *parse_interrupts(struct device_node *np,
> > > > + const char *prop_name, int index)
> > > > +{
> > > > + struct device_node *sup;
> > > > +
> > > > + if (strcmp(prop_name, "interrupts") || index)
> > > > + return NULL;
> > > > +
> > > > + of_node_get(np);
> > > > + while (np && !(sup = of_parse_phandle(np, "interrupt-parent", 0)))
> > > > + np = of_get_next_parent(np);
> > > > + of_node_put(np);
> > > > +
> > > > + return sup;
> > > > +}
> > > > +
> > > >  static const struct supplier_bindings of_supplier_bindings[] = {
> > > >   { .parse_prop = parse_clocks, },
> > > >   { .parse_prop = parse_interconnects, },
> > > > @@ -1296,6 +1312,7 @@ static const struct supplier_bindings
> > > > of_supplier_bindings[] = {
> > > >   { .parse_prop = parse_pinctrl6, },
> > > >   { .parse_prop = parse_pinctrl7, },
> > > >   { .parse_prop = parse_pinctrl8, },
> > > > + { .parse_prop = parse_interrupts, },
> > > >   { .parse_prop = parse_regulators, },
> > > >   { .parse_prop = parse_gpio, },
> > > >   { .parse_prop = parse_gpios, },
> > >
> > > You don't really describe what this is for so I'm only guessing
> > > from the context. If you want to follow the interrupt hierarchy,
> > > "interrupt-parent" isn't enough. You also need to track
> > > things like interrupt-map, or anything that carries a phandle
> > > to an interrupt controller.
> >
> > We don't need to follow the hierarchy, we just need the immediate
> > dependencies.
>
> Indeed. I also wonder why this isn't just a irq_find_parent() call, TBH.

Thanks Rob for explaining it.

Marc, I wasn't sure if Rob would be okay with including of_irq.h here.
Also, I'm trying to keep of/property.c independent of the framework
code for now. The long term goal is to see if I can move out most of
this into the frameworks. But I want to do that after I sort of some
of the larger problems (like getting fw_devlink=on to work on all
devices  first). Let me know if you have a strong preference for right
now, if not, I'd rather keep property.c independent for now.

I wasn't aware of interrupt-map until a few weeks ago and didn't know
it carried phandles. I can add support for that too. There's no reason
for all of them to go in one patch though.

>
> > But you are right that 'interrupt-map' also needs to be tracked.
>
> And 'interrupts-extended', while we're at it.

This is already handled.

> >
> > I also noticed that we define 'interrupt-parent' as a dependency to
> > parse, but that's wrong. The dependency is where 'interrupts' appears
> > and where 'interrupt-parent' appears is irrelevant.

No, the interrupt-parent parsing is correct and it's needed for
interrupt controllers to probe in the right order. But
interrupt-parent is also needs to be looked at for parsing
"interrupts".

-Saravana

> Agreed. Though you need the object the dependency is on, I guess, if
> you want to be able to have the dependency edge between the device and
> the interrupt controller. But since the commit message doesn't say
> much about what this is trying to achieve, I'm only guessing the
> purpose of this patch.
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.


Re: [PATCH 00/10] Remove support for TX49xx

2021-01-06 Thread Thomas Bogendoerfer
On Wed, Jan 06, 2021 at 09:37:11AM +0100, Geert Uytterhoeven wrote:
> Hi Thomas,
> 
> CC Nemoto-san (de-facto TX49XX maintainer)
> 
> On Tue, Jan 5, 2021 at 3:03 PM Thomas Bogendoerfer
>  wrote:
> > I couldn't find any buyable product other than reference boards using
> > TX49xx CPUs. And since nobody showed interest in keeping support for
> > it, it's time to remove it.
> 
> I have an RBTX4927 development board in my board farm, boot-test every
> bi-weekly renesas-drivers release on it, and fix kernel issues when they
> appear.
> 
> Is that sufficient to keep it?

for me it is. But now we probaly need some reverts then...

I wonder whether you have seen my mail about the removal

https://lore.kernel.org/linux-mips/20201207105627.ga15...@alpha.franken.de

and my call for people owning MIPS machines

https://lore.kernel.org/linux-mips/20200227144910.ga25...@alpha.franken.de/

Still "unclaimed" machines are

IMG Pistachio SoC based boards (MACH_PISTACHIO(
Toshiba TX39 series based machines (MACH_TX39XX)
NEC VR4100 series based machines (MACH_VR41XX)
Netlogic XLR/XLS based systems (NLM_XLR_BOARD)
Netlogic XLP based systems (NLM_XLP_BOARD)
Sibyte BCM91120C-CRhine (SIBYTE_CRHINE)
Sibyte BCM91120x-Carmel (SIBYTE_CARMEL)
Sibyte BCM91125C-CRhone (SIBYTE_CRHONE)
Sibyte BCM91125E-Rhone (SIBYTE_RHONE)
Sibyte BCM91250C2-LittleSur (SIBYTE_LITTLESUR)
Sibyte BCM91250E-Sentosa (SIBYTE_SENTOSA)

Is there something on this list you also regulary use ?

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [RFC PATCH v3 0/6] Restricted DMA

2021-01-06 Thread Florian Fainelli
Hi,

First of all let me say that I am glad that someone is working on a
upstream solution for this issue, would appreciate if you could CC and
Jim Quinlan on subsequent submissions.

On 1/5/21 7:41 PM, Claire Chang wrote:
> This series implements mitigations for lack of DMA access control on
> systems without an IOMMU, which could result in the DMA accessing the
> system memory at unexpected times and/or unexpected addresses, possibly
> leading to data leakage or corruption.
> 
> For example, we plan to use the PCI-e bus for Wi-Fi and that PCI-e bus is
> not behind an IOMMU. As PCI-e, by design, gives the device full access to
> system memory, a vulnerability in the Wi-Fi firmware could easily escalate
> to a full system exploit (remote wifi exploits: [1a], [1b] that shows a
> full chain of exploits; [2], [3]).
> 
> To mitigate the security concerns, we introduce restricted DMA. Restricted
> DMA utilizes the existing swiotlb to bounce streaming DMA in and out of a
> specially allocated region and does memory allocation from the same region.
> The feature on its own provides a basic level of protection against the DMA
> overwriting buffer contents at unexpected times. However, to protect
> against general data leakage and system memory corruption, the system needs
> to provide a way to restrict the DMA to a predefined memory region (this is
> usually done at firmware level, e.g. in ATF on some ARM platforms).

Can you explain how ATF gets involved and to what extent it does help,
besides enforcing a secure region from the ARM CPU's perpsective? Does
the PCIe root complex not have an IOMMU but can somehow be denied access
to a region that is marked NS=0 in the ARM CPU's MMU? If so, that is
still some sort of basic protection that the HW enforces, right?

On Broadcom STB SoCs we have had something similar for a while however
and while we don't have an IOMMU for the PCIe bridge, we do have a a
basic protection mechanism whereby we can configure a region in DRAM to
be PCIe read/write and CPU read/write which then gets used as the PCIe
inbound region for the PCIe EP. By default the PCIe bridge is not
allowed access to DRAM so we must call into a security agent to allow
the PCIe bridge to access the designated DRAM region.

We have done this using a private CMA area region assigned via Device
Tree, assigned with a and requiring the PCIe EP driver to use
dma_alloc_from_contiguous() in order to allocate from this device
private CMA area. The only drawback with that approach is that it
requires knowing how much memory you need up front for buffers and DMA
descriptors that the PCIe EP will need to process. The problem is that
it requires driver modifications and that does not scale over the number
of PCIe EP drivers, some we absolutely do not control, but there is no
need to bounce buffer. Your approach scales better across PCIe EP
drivers however it does require bounce buffering which could be a
performance hit.

Thanks!
-- 
Florian


Re: [PATCH] HID: logitech-hidpp: add support for Unified Battery (1004) feature

2021-01-06 Thread Filipe Laíns
On Wed, 2021-01-06 at 10:34 +0100, Bastien Nocera wrote:
> On Mon, 2021-01-04 at 18:29 +, la...@archlinux.org wrote:
> > From: Filipe Laíns 
> > 
> > This new feature present in new devices replaces the old Battery
> > Level
> > Status (0x1000) feature. It keeps essentially the same information
> > for
> > levels (reporting critical, low, good and full) but makes these
> > levels
> > optional, the device exports a capability setting which describes
> > which
> > levels it supports. In addition to this, there is an optional
> > state_of_charge paramenter that exports the battery percentage.
> > 
> > This patch adds support for this new feature. There were some
> > implementation choices, as described below and in the code.
> > 
> > If the device supports the state_of_charge parameter, we will just
> > export the battery percentage and not the levels, which the device
> > might
> > still support.
> 
> I'm guessing that means no changes needed on the upower side?
> 
> Cheers
> 

Yes :)
I tested upower and all works as expected.

There will still be devices that only support battery voltage, so I might
implement the battery voltage to charge percentage in a future patch.

Cheers,
Filipe Laíns


signature.asc
Description: This is a digitally signed message part


<    1   2   3   4   5   6   7   8   9   10   >