Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1698545 > unrolled thread
| Started by | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| First post | 2017-07-28 09:20 +0200 |
| Last post | 2017-07-28 09:20 +0200 |
| Articles | 8 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH V2 00/12]: spmi: pmic-arb: Support for HW v5 and other fixes Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 04/12] spmi: pmic-arb: optimize qpnpint_irq_set_type function Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 06/12] spmi: pmic-arb: replace the writel_relaxed with __raw_writel Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 03/12] spmi: pmic-arb: clean up pmic_arb_find_apid function Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 01/12] spmi: pmic-arb: remove the read/write access checks Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 11/12] spmi: pmic-arb: add support for HW version 5 Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 05/12] spmi: pmic-arb: fix memory allocation for mapping_table Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
[PATCH V2 12/12] spmi: pmic-arb: Remove checking opc value not less than 0 Kiran Gunda <kgunda@codeaurora.org> - 2017-07-28 09:20 +0200
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 00/12]: spmi: pmic-arb: Support for HW v5 and other fixes |
| Message-ID | <u87IZ-CM-5@gated-at.bofh.it> |
v2:
* [PATCH V2 04/12] spmi: pmic-arb: optimize qpnpint_irq_set_type function
Added Stephen's Reviewed-by tag.
* [PATCH V2 05/12] spmi: pmic-arb: fix memory allocation for mapping_table
Added Fixes tag and Stephen's Reviewed-by tag.
* [PATCH V2 02/12] spmi: pmic-arb: rename pa_xx to pmic_arb_xx and other cleanup
Added Stephen's Reviewed-by tag.
* [PATCH V2 06/12] spmi: pmic-arb: replace the writel_relaxed with __raw_writel
Added Fixes tag.
* [PATCH V2 03/12] spmi: pmic-arb: clean up pmic_arb_find_apid function
Fixed alignement issue and added Stephen's reviewed-by tag.
Now all the patches in this series are reviewed and acked by Stephen boyd and are ready
for merge.
v1:
* This patch series add the support for pmic arbiter hardware v5 along with
the few bug fixes and code cleanup.
* This new series is the combined series of
[PATCH V3 0/5]: spmi: pmic-arb: Fixup patches and
[PATCH V4 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes, which are
being reviewed by Stephen Boyd.
* This series depends on the below patch uploaded by Stephen Boyd
https://patchwork.kernel.org/patch/9810723/.
David Collins (1):
spmi: pmic-arb: add support for HW version 5
Fenglin Wu (1):
spmi: pmic-arb: Remove checking opc value not less than 0
Kiran Gunda (10):
spmi: pmic-arb: remove the read/write access checks
spmi: pmic-arb: rename pa_xx to pmic_arb_xx and other cleanup
spmi: pmic-arb: clean up pmic_arb_find_apid function
spmi: pmic-arb: optimize qpnpint_irq_set_type function
spmi: pmic-arb: fix memory allocation for mapping_table
spmi: pmic-arb: replace the writel_relaxed with __raw_writel
spmi: pmic-arb: return the value instead of passing by pointer
spmi: pmic-arb: use irq_chip callback to set spmi irq wakeup
capability
spmi: pmic-arb: return __iomem pointer instead of offset
spmi: pmic-arb: fix a possible null pointer dereference
drivers/spmi/spmi-pmic-arb.c | 825 +++++++++++++++++++++++++------------------
1 file changed, 481 insertions(+), 344 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 04/12] spmi: pmic-arb: optimize qpnpint_irq_set_type function |
| Message-ID | <u87J1-CM-25@gated-at.bofh.it> |
| In reply to | #1698545 |
Optimize the qpnpint_irq_set_type() by using a local variable
to hold the handler type. Also clean up other variable usage.
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/spmi/spmi-pmic-arb.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 530d410..0577cfd 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -587,35 +587,35 @@ static void qpnpint_irq_unmask(struct irq_data *d)
static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct spmi_pmic_arb_qpnpint_type type;
+ irq_flow_handler_t flow_handler;
u8 irq = hwirq_to_irq(d->hwirq);
- u8 bit_mask_irq = BIT(irq);
qpnpint_spmi_read(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
- type.type |= bit_mask_irq;
+ type.type |= BIT(irq);
if (flow_type & IRQF_TRIGGER_RISING)
- type.polarity_high |= bit_mask_irq;
+ type.polarity_high |= BIT(irq);
if (flow_type & IRQF_TRIGGER_FALLING)
- type.polarity_low |= bit_mask_irq;
+ type.polarity_low |= BIT(irq);
+
+ flow_handler = handle_edge_irq;
} else {
if ((flow_type & (IRQF_TRIGGER_HIGH)) &&
(flow_type & (IRQF_TRIGGER_LOW)))
return -EINVAL;
- type.type &= ~bit_mask_irq; /* level trig */
+ type.type &= ~BIT(irq); /* level trig */
if (flow_type & IRQF_TRIGGER_HIGH)
- type.polarity_high |= bit_mask_irq;
+ type.polarity_high |= BIT(irq);
else
- type.polarity_low |= bit_mask_irq;
+ type.polarity_low |= BIT(irq);
+
+ flow_handler = handle_level_irq;
}
qpnpint_spmi_write(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
-
- if (flow_type & IRQ_TYPE_EDGE_BOTH)
- irq_set_handler_locked(d, handle_edge_irq);
- else
- irq_set_handler_locked(d, handle_level_irq);
+ irq_set_handler_locked(d, flow_handler);
return 0;
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 06/12] spmi: pmic-arb: replace the writel_relaxed with __raw_writel |
| Message-ID | <u87J1-CM-23@gated-at.bofh.it> |
| In reply to | #1698545 |
Replace the writel_relaxed with __raw_writel to avoid byte swapping
in pmic_arb_write_data() function. That way the code is independent
of the CPU endianness.
Fixes: 111a10bf3e53 ("spmi: pmic-arb: rename spmi_pmic_arb_dev to
spmi_pmic_arb")
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/spmi/spmi-pmic-arb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 340e7b8..a9d9359 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -230,7 +230,7 @@ static void pmic_arb_write_data(struct spmi_pmic_arb *pmic_arb, const u8 *buf,
u32 data = 0;
memcpy(&data, buf, (bc & 3) + 1);
- pmic_arb_base_write(pmic_arb, reg, data);
+ __raw_writel(data, pmic_arb->wr_base + reg);
}
static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 03/12] spmi: pmic-arb: clean up pmic_arb_find_apid function |
| Message-ID | <u87J1-CM-29@gated-at.bofh.it> |
| In reply to | #1698545 |
Clean up the pmic_arb_find_apid() by using the local
variables to improve the code readability.
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/spmi/spmi-pmic-arb.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 530fa11..530d410 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -762,23 +762,22 @@ static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
{
+ struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
u32 regval, offset;
- u16 apid;
- u16 id;
+ u16 id, apid;
/*
- * PMIC_ARB_REG_CHNL is a table in HW mapping channel to ppid.
+ * PMIC_ARB_REG_APID is a table in HW mapping apid to ppid.
* ppid_to_apid is an in-memory invert of that table.
*/
- for (apid = pmic_arb->last_apid; ; apid++) {
+ for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
offset = PMIC_ARB_REG_APID(apid);
if (offset >= pmic_arb->core_size)
break;
regval = readl_relaxed(pmic_arb->cnfg +
SPMI_OWNERSHIP_TABLE_REG(apid));
- pmic_arb->apid_data[apid].owner =
- SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+ apidd->owner = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
regval = readl_relaxed(pmic_arb->core + offset);
if (!regval)
@@ -786,7 +785,7 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
id = (regval >> 8) & PMIC_ARB_PPID_MASK;
pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
- pmic_arb->apid_data[apid].ppid = id;
+ apidd->ppid = id;
if (id == ppid) {
apid |= PMIC_ARB_APID_VALID;
break;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 01/12] spmi: pmic-arb: remove the read/write access checks |
| Message-ID | <u87J1-CM-33@gated-at.bofh.it> |
| In reply to | #1698545 |
The access mode checks for peripheral ownership for read/write
permissions should not be required. Every peripheral enabled for
this master is expected to have a read/write permissions. If there
is any such invalid access due to wrong configuration in boot loader
or device tree files, then it should be fixed in those locations.
Hence, remove the access mode checks from the driver.
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/spmi/spmi-pmic-arb.c | 75 +++-----------------------------------------
1 file changed, 5 insertions(+), 70 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index f4b7a98..7531519 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -128,7 +128,6 @@ struct apid_data {
* @ee: the current Execution Environment
* @min_apid: minimum APID (used for bounding IRQ search)
* @max_apid: maximum APID
- * @max_periph: maximum number of PMIC peripherals supported by HW.
* @mapping_table: in-memory copy of PPID -> APID mapping table.
* @domain: irq domain object for PMIC IRQ domain
* @spmic: SPMI controller object
@@ -148,7 +147,6 @@ struct spmi_pmic_arb {
u8 ee;
u16 min_apid;
u16 max_apid;
- u16 max_periph;
u32 *mapping_table;
DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
struct irq_domain *domain;
@@ -164,7 +162,6 @@ struct spmi_pmic_arb {
*
* @ver_str: version string.
* @ppid_to_apid: finds the apid for a given ppid.
- * @mode: access rights to specified pmic peripheral.
* @non_data_cmd: on v1 issues an spmi non-data command.
* on v2 no HW support, returns -EOPNOTSUPP.
* @offset: on v1 offset of per-ee channel.
@@ -183,8 +180,6 @@ struct pmic_arb_ver_ops {
const char *ver_str;
int (*ppid_to_apid)(struct spmi_pmic_arb *pa, u8 sid, u16 addr,
u16 *apid);
- int (*mode)(struct spmi_pmic_arb *dev, u8 sid, u16 addr,
- mode_t *mode);
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
int (*offset)(struct spmi_pmic_arb *dev, u8 sid, u16 addr,
u32 *offset);
@@ -340,23 +335,11 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
u32 cmd;
int rc;
u32 offset;
- mode_t mode;
rc = pa->ver_ops->offset(pa, sid, addr, &offset);
if (rc)
return rc;
- rc = pa->ver_ops->mode(pa, sid, addr, &mode);
- if (rc)
- return rc;
-
- if (!(mode & S_IRUSR)) {
- dev_err(&pa->spmic->dev,
- "error: impermissible read from peripheral sid:%d addr:0x%x\n",
- sid, addr);
- return -EPERM;
- }
-
if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
dev_err(&ctrl->dev,
"pmic-arb supports 1..%d bytes per trans, but:%zu requested",
@@ -402,23 +385,11 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
u32 cmd;
int rc;
u32 offset;
- mode_t mode;
rc = pa->ver_ops->offset(pa, sid, addr, &offset);
if (rc)
return rc;
- rc = pa->ver_ops->mode(pa, sid, addr, &mode);
- if (rc)
- return rc;
-
- if (!(mode & S_IWUSR)) {
- dev_err(&pa->spmic->dev,
- "error: impermissible write to peripheral sid:%d addr:0x%x\n",
- sid, addr);
- return -EPERM;
- }
-
if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
dev_err(&ctrl->dev,
"pmic-arb supports 1..%d bytes per trans, but:%zu requested",
@@ -785,13 +756,6 @@ static int qpnpint_irq_domain_map(struct irq_domain *d,
return -ENODEV;
}
-static int
-pmic_arb_mode_v1_v3(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode)
-{
- *mode = S_IRUSR | S_IWUSR;
- return 0;
-}
-
/* v1 offset per ee */
static int
pmic_arb_offset_v1(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u32 *offset)
@@ -810,15 +774,15 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pa, u16 ppid)
* PMIC_ARB_REG_CHNL is a table in HW mapping channel to ppid.
* ppid_to_apid is an in-memory invert of that table.
*/
- for (apid = pa->last_apid; apid < pa->max_periph; apid++) {
- regval = readl_relaxed(pa->cnfg +
- SPMI_OWNERSHIP_TABLE_REG(apid));
- pa->apid_data[apid].owner = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
-
+ for (apid = pa->last_apid; ; apid++) {
offset = PMIC_ARB_REG_CHNL(apid);
if (offset >= pa->core_size)
break;
+ regval = readl_relaxed(pa->cnfg +
+ SPMI_OWNERSHIP_TABLE_REG(apid));
+ pa->apid_data[apid].owner = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+
regval = readl_relaxed(pa->core + offset);
if (!regval)
continue;
@@ -853,24 +817,6 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pa, u16 ppid)
return 0;
}
-static int
-pmic_arb_mode_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode)
-{
- u16 apid;
- int rc;
-
- rc = pmic_arb_ppid_to_apid_v2(pa, sid, addr, &apid);
- if (rc < 0)
- return rc;
-
- *mode = 0;
- *mode |= S_IRUSR;
-
- if (pa->ee == pa->apid_data[apid].owner)
- *mode |= S_IWUSR;
- return 0;
-}
-
/* v2 offset per ppid and per ee */
static int
pmic_arb_offset_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u32 *offset)
@@ -944,7 +890,6 @@ static u32 pmic_arb_irq_clear_v2(u16 n)
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
.ver_str = "v1",
.ppid_to_apid = pmic_arb_ppid_to_apid_v1,
- .mode = pmic_arb_mode_v1_v3,
.non_data_cmd = pmic_arb_non_data_cmd_v1,
.offset = pmic_arb_offset_v1,
.fmt_cmd = pmic_arb_fmt_cmd_v1,
@@ -957,7 +902,6 @@ static u32 pmic_arb_irq_clear_v2(u16 n)
static const struct pmic_arb_ver_ops pmic_arb_v2 = {
.ver_str = "v2",
.ppid_to_apid = pmic_arb_ppid_to_apid_v2,
- .mode = pmic_arb_mode_v2,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v2,
.fmt_cmd = pmic_arb_fmt_cmd_v2,
@@ -970,7 +914,6 @@ static u32 pmic_arb_irq_clear_v2(u16 n)
static const struct pmic_arb_ver_ops pmic_arb_v3 = {
.ver_str = "v3",
.ppid_to_apid = pmic_arb_ppid_to_apid_v2,
- .mode = pmic_arb_mode_v1_v3,
.non_data_cmd = pmic_arb_non_data_cmd_v2,
.offset = pmic_arb_offset_v2,
.fmt_cmd = pmic_arb_fmt_cmd_v2,
@@ -1003,11 +946,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
pa->core_size = resource_size(res);
- if (pa->core_size <= 0x800) {
- dev_err(&pdev->dev, "core_size is smaller than 0x800. Failing Probe\n");
- err = -EINVAL;
- goto err_put_ctrl;
- }
core = devm_ioremap_resource(&ctrl->dev, res);
if (IS_ERR(core)) {
@@ -1036,9 +974,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
else
pa->ver_ops = &pmic_arb_v3;
- /* the apid to ppid table starts at PMIC_ARB_REG_CHNL(0) */
- pa->max_periph = (pa->core_size - PMIC_ARB_REG_CHNL(0)) / 4;
-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"obsrvr");
pa->rd_base = devm_ioremap_resource(&ctrl->dev, res);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 11/12] spmi: pmic-arb: add support for HW version 5 |
| Message-ID | <u87J1-CM-31@gated-at.bofh.it> |
| In reply to | #1698545 |
From: David Collins <collinsd@codeaurora.org>
Add support for version 5 of the SPMI PMIC arbiter. It utilizes
different offsets for registers than those found on version 3.
Also, the procedure to determine if writing and IRQ access is
allowed for a given PPID changes for version 5.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/spmi/spmi-pmic-arb.c | 236 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 214 insertions(+), 22 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index bc68e08..3f46445 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -29,6 +29,7 @@
#define PMIC_ARB_VERSION 0x0000
#define PMIC_ARB_VERSION_V2_MIN 0x20010000
#define PMIC_ARB_VERSION_V3_MIN 0x30000000
+#define PMIC_ARB_VERSION_V5_MIN 0x50000000
#define PMIC_ARB_INT_EN 0x0004
/* PMIC Arbiter channel registers offsets */
@@ -39,7 +40,6 @@
#define PMIC_ARB_WDATA1 0x14
#define PMIC_ARB_RDATA0 0x18
#define PMIC_ARB_RDATA1 0x1C
-#define PMIC_ARB_REG_APID(N) (0x800 + 0x4 * (N))
/* Mapping Table */
#define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N)))
@@ -52,6 +52,8 @@
#define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */
#define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */
#define PMIC_ARB_APID_VALID BIT(15)
+#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24))
+#define INVALID_EE 0xFF
/* Ownership Table */
#define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N)))
@@ -86,6 +88,15 @@ enum pmic_arb_cmd_op_code {
PMIC_ARB_OP_ZERO_WRITE = 16,
};
+/*
+ * PMIC arbiter version 5 uses different register offsets for read/write vs
+ * observer channels.
+ */
+enum pmic_arb_channel {
+ PMIC_ARB_CHANNEL_RW,
+ PMIC_ARB_CHANNEL_OBS,
+};
+
/* Maximum number of support PMIC peripherals */
#define PMIC_ARB_MAX_PERIPHS 512
#define PMIC_ARB_TIMEOUT_US 100
@@ -112,7 +123,8 @@ enum pmic_arb_cmd_op_code {
struct apid_data {
u16 ppid;
- u8 owner;
+ u8 write_ee;
+ u8 irq_ee;
};
/**
@@ -175,12 +187,14 @@ struct spmi_pmic_arb {
* on v2 address of SPMI_PIC_IRQ_STATUSn.
* @irq_clear: on v1 address of PMIC_ARB_SPMI_PIC_IRQ_CLEARn
* on v2 address of SPMI_PIC_IRQ_CLEARn.
+ * @apid_map_offset: offset of PMIC_ARB_REG_CHNLn
*/
struct pmic_arb_ver_ops {
const char *ver_str;
int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
- int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr);
+ int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type);
u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
/* Interrupts controller functionality (offset of PIC registers) */
@@ -189,6 +203,7 @@ struct pmic_arb_ver_ops {
void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+ u32 (*apid_map_offset)(u16 n);
};
static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -233,7 +248,8 @@ static void pmic_arb_write_data(struct spmi_pmic_arb *pmic_arb, const u8 *buf,
}
static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
- void __iomem *base, u8 sid, u16 addr)
+ void __iomem *base, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
u32 status = 0;
@@ -241,7 +257,7 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
u32 offset;
int rc;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr);
+ rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
if (rc < 0)
return rc;
@@ -289,7 +305,7 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
int rc;
u32 offset;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0);
+ rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
if (rc < 0)
return rc;
@@ -298,7 +314,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
raw_spin_lock_irqsave(&pmic_arb->lock, flags);
pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
- rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0);
+ rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0,
+ PMIC_ARB_CHANNEL_RW);
raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
return rc;
@@ -334,7 +351,8 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
int rc;
u32 offset;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr);
+ rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+ PMIC_ARB_CHANNEL_OBS);
if (rc < 0)
return rc;
@@ -359,7 +377,8 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
raw_spin_lock_irqsave(&pmic_arb->lock, flags);
pmic_arb_set_rd_cmd(pmic_arb, offset + PMIC_ARB_CMD, cmd);
- rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr);
+ rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr,
+ PMIC_ARB_CHANNEL_OBS);
if (rc)
goto done;
@@ -376,7 +395,7 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
}
static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
- u16 addr, const u8 *buf, size_t len)
+ u16 addr, const u8 *buf, size_t len)
{
struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
unsigned long flags;
@@ -385,7 +404,8 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
int rc;
u32 offset;
- rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr);
+ rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+ PMIC_ARB_CHANNEL_RW);
if (rc < 0)
return rc;
@@ -420,7 +440,8 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
/* Start the transaction */
pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
- rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr);
+ rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr,
+ PMIC_ARB_CHANNEL_RW);
raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
return rc;
@@ -680,12 +701,19 @@ static int qpnpint_irq_domain_dt_translate(struct irq_domain *d,
ppid = intspec[0] << 8 | intspec[1];
rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
if (rc < 0) {
- dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = 0x%x, periph = 0x%x, irq = %x rc = %d\n",
+ dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
intspec[0], intspec[1], intspec[2], rc);
return rc;
}
apid = rc;
+ if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
+ dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+ intspec[0], intspec[1], intspec[2], pmic_arb->ee,
+ pmic_arb->apid_data[apid].irq_ee);
+ return -ENODEV;
+ }
+
/* Keep track of {max,min}_apid for bounding search during interrupt */
if (apid > pmic_arb->max_apid)
pmic_arb->max_apid = apid;
@@ -762,7 +790,8 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
}
/* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
return 0x800 + 0x80 * pmic_arb->channel;
}
@@ -773,18 +802,15 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
u32 regval, offset;
u16 id, apid;
- /*
- * PMIC_ARB_REG_APID is a table in HW mapping apid to ppid.
- * ppid_to_apid is an in-memory invert of that table.
- */
for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
- offset = PMIC_ARB_REG_APID(apid);
+ offset = pmic_arb->ver_ops->apid_map_offset(apid);
if (offset >= pmic_arb->core_size)
break;
regval = readl_relaxed(pmic_arb->cnfg +
SPMI_OWNERSHIP_TABLE_REG(apid));
- apidd->owner = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+ apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+ apidd->write_ee = apidd->irq_ee;
regval = readl_relaxed(pmic_arb->core + offset);
if (!regval)
@@ -816,8 +842,84 @@ static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
return apid_valid & ~PMIC_ARB_APID_VALID;
}
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+{
+ struct apid_data *apidd = pmic_arb->apid_data;
+ struct apid_data *prev_apidd;
+ u16 i, apid, ppid;
+ bool valid, is_irq_ee;
+ u32 regval, offset;
+
+ /*
+ * In order to allow multiple EEs to write to a single PPID in arbiter
+ * version 5, there is more than one APID mapped to each PPID.
+ * The owner field for each of these mappings specifies the EE which is
+ * allowed to write to the APID. The owner of the last (highest) APID
+ * for a given PPID will receive interrupts from the PPID.
+ */
+ for (i = 0; ; i++, apidd++) {
+ offset = pmic_arb->ver_ops->apid_map_offset(i);
+ if (offset >= pmic_arb->core_size)
+ break;
+
+ regval = readl_relaxed(pmic_arb->core + offset);
+ if (!regval)
+ continue;
+ ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
+ is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
+
+ regval = readl_relaxed(pmic_arb->cnfg +
+ SPMI_OWNERSHIP_TABLE_REG(i));
+ apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+
+ apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
+
+ valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+ apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+ prev_apidd = &pmic_arb->apid_data[apid];
+
+ if (valid && is_irq_ee &&
+ prev_apidd->write_ee == pmic_arb->ee) {
+ /*
+ * Duplicate PPID mapping after the one for this EE;
+ * override the irq owner
+ */
+ prev_apidd->irq_ee = apidd->irq_ee;
+ } else if (!valid || is_irq_ee) {
+ /* First PPID mapping or duplicate for another EE */
+ pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+ }
+
+ apidd->ppid = ppid;
+ pmic_arb->last_apid = i;
+ }
+
+ /* Dump the mapping table for debug purposes. */
+ dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+ for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
+ apid = pmic_arb->ppid_to_apid[ppid];
+ if (apid & PMIC_ARB_APID_VALID) {
+ apid &= ~PMIC_ARB_APID_VALID;
+ apidd = &pmic_arb->apid_data[apid];
+ dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
+ ppid, apid, apidd->write_ee, apidd->irq_ee);
+ }
+ }
+
+ return 0;
+}
+
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+{
+ if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+ return -ENODEV;
+
+ return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+}
+
/* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
{
u16 apid;
u16 ppid;
@@ -832,6 +934,35 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr)
return 0x1000 * pmic_arb->ee + 0x8000 * apid;
}
+/*
+ * v5 offset per ee and per apid for observer channels and per apid for
+ * read/write channels.
+ */
+static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
+ enum pmic_arb_channel ch_type)
+{
+ u16 apid;
+ int rc;
+ u32 offset = 0;
+ u16 ppid = (sid << 8) | (addr >> 8);
+
+ rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+ if (rc < 0)
+ return rc;
+
+ apid = rc;
+ switch (ch_type) {
+ case PMIC_ARB_CHANNEL_OBS:
+ offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
+ break;
+ case PMIC_ARB_CHANNEL_RW:
+ offset = 0x10000 * apid;
+ break;
+ }
+
+ return offset;
+}
+
static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc)
{
return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
@@ -861,6 +992,12 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
}
static void __iomem *
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+{
+ return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+}
+
+static void __iomem *
pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
{
return pmic_arb->intr + 0x200 + 0x4 * n;
@@ -873,6 +1010,12 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
}
static void __iomem *
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+{
+ return pmic_arb->wr_base + 0x100 + 0x10000 * n;
+}
+
+static void __iomem *
pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
{
return pmic_arb->intr + 0x600 + 0x4 * n;
@@ -885,6 +1028,12 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
}
static void __iomem *
+pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+{
+ return pmic_arb->wr_base + 0x104 + 0x10000 * n;
+}
+
+static void __iomem *
pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
{
return pmic_arb->intr + 0xA00 + 0x4 * n;
@@ -896,6 +1045,22 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
return pmic_arb->intr + 0x8 + 0x1000 * n;
}
+static void __iomem *
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+{
+ return pmic_arb->wr_base + 0x108 + 0x10000 * n;
+}
+
+static u32 pmic_arb_apid_map_offset_v2(u16 n)
+{
+ return 0x800 + 0x4 * n;
+}
+
+static u32 pmic_arb_apid_map_offset_v5(u16 n)
+{
+ return 0x900 + 0x4 * n;
+}
+
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
.ver_str = "v1",
.ppid_to_apid = pmic_arb_ppid_to_apid_v1,
@@ -906,6 +1071,7 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
.acc_enable = pmic_arb_acc_enable_v1,
.irq_status = pmic_arb_irq_status_v1,
.irq_clear = pmic_arb_irq_clear_v1,
+ .apid_map_offset = pmic_arb_apid_map_offset_v2,
};
static const struct pmic_arb_ver_ops pmic_arb_v2 = {
@@ -918,6 +1084,7 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
.acc_enable = pmic_arb_acc_enable_v2,
.irq_status = pmic_arb_irq_status_v2,
.irq_clear = pmic_arb_irq_clear_v2,
+ .apid_map_offset = pmic_arb_apid_map_offset_v2,
};
static const struct pmic_arb_ver_ops pmic_arb_v3 = {
@@ -930,6 +1097,20 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
.acc_enable = pmic_arb_acc_enable_v2,
.irq_status = pmic_arb_irq_status_v2,
.irq_clear = pmic_arb_irq_clear_v2,
+ .apid_map_offset = pmic_arb_apid_map_offset_v2,
+};
+
+static const struct pmic_arb_ver_ops pmic_arb_v5 = {
+ .ver_str = "v5",
+ .ppid_to_apid = pmic_arb_ppid_to_apid_v5,
+ .non_data_cmd = pmic_arb_non_data_cmd_v2,
+ .offset = pmic_arb_offset_v5,
+ .fmt_cmd = pmic_arb_fmt_cmd_v2,
+ .owner_acc_status = pmic_arb_owner_acc_status_v5,
+ .acc_enable = pmic_arb_acc_enable_v5,
+ .irq_status = pmic_arb_irq_status_v5,
+ .irq_clear = pmic_arb_irq_clear_v5,
+ .apid_map_offset = pmic_arb_apid_map_offset_v5,
};
static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
@@ -982,8 +1163,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
pmic_arb->ver_ops = &pmic_arb_v2;
- else
+ else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
pmic_arb->ver_ops = &pmic_arb_v3;
+ else
+ pmic_arb->ver_ops = &pmic_arb_v5;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"obsrvr");
@@ -1073,6 +1256,15 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
ctrl->read_cmd = pmic_arb_read_cmd;
ctrl->write_cmd = pmic_arb_write_cmd;
+ if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
+ err = pmic_arb_read_apid_map_v5(pmic_arb);
+ if (err) {
+ dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
+ err);
+ goto err_put_ctrl;
+ }
+ }
+
dev_dbg(&pdev->dev, "adding irq domain\n");
pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
&pmic_arb_irq_domain_ops, pmic_arb);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 05/12] spmi: pmic-arb: fix memory allocation for mapping_table |
| Message-ID | <u87J1-CM-37@gated-at.bofh.it> |
| In reply to | #1698545 |
Allocate the correct memory size (max_pmic_peripherals) for the
mapping_table that holds the apid to ppid mapping. Also use a local
variable for mapping_table for better alignment of the code.
Fixes: 987a9f128b8a ("spmi: pmic-arb: Support more than 128 peripherals")
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/spmi/spmi-pmic-arb.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 0577cfd..340e7b8 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -929,6 +929,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
struct spmi_controller *ctrl;
struct resource *res;
void __iomem *core;
+ u32 *mapping_table;
u32 channel, ee, hw_ver;
int err;
@@ -1038,16 +1039,14 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
}
pmic_arb->ee = ee;
-
- pmic_arb->mapping_table = devm_kcalloc(&ctrl->dev,
- PMIC_ARB_MAX_PERIPHS - 1,
- sizeof(*pmic_arb->mapping_table),
- GFP_KERNEL);
- if (!pmic_arb->mapping_table) {
+ mapping_table = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PERIPHS,
+ sizeof(*mapping_table), GFP_KERNEL);
+ if (!mapping_table) {
err = -ENOMEM;
goto err_put_ctrl;
}
+ pmic_arb->mapping_table = mapping_table;
/* Initialize max_apid/min_apid to the opposite bounds, during
* the irq domain translation, we are sure to update these */
pmic_arb->max_apid = 0;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kiran Gunda <kgunda@codeaurora.org> |
|---|---|
| Date | 2017-07-28 09:20 +0200 |
| Subject | [PATCH V2 12/12] spmi: pmic-arb: Remove checking opc value not less than 0 |
| Message-ID | <u87J2-CM-43@gated-at.bofh.it> |
| In reply to | #1698545 |
From: Fenglin Wu <fenglinw@codeaurora.org> The opc parameter in pmic_arb_write_cmd() function is defined with type u8 and it's always greater than or equal to 0. Checking that it's not less than 0 is redundant and it can cause a forbidden warning during compilation. Remove the check. Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> --- drivers/spmi/spmi-pmic-arb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 3f46445..ca9bdd3 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -419,7 +419,7 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, /* Check the opcode */ if (opc >= 0x40 && opc <= 0x5F) opc = PMIC_ARB_OP_WRITE; - else if (opc >= 0x00 && opc <= 0x0F) + else if (opc <= 0x0F) opc = PMIC_ARB_OP_EXT_WRITE; else if (opc >= 0x30 && opc <= 0x37) opc = PMIC_ARB_OP_EXT_WRITEL; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web