[PATCH v4 1/1] usb: gadget: f_fs: Add support for SuperSpeed Mode

2013-12-23 Thread Manu Gautam
Allow userspace to pass SuperSpeed descriptors and
handle them in the driver accordingly.
This change doesn't modify existing desc_header and thereby
keeps the ABI changes backward compatible i.e. existing
userspace drivers compiled with old header (functionfs.h)
would continue to work with the updated kernel.

Change-Id: Ic27035fdef2a83828024348d75be1518e9f8c5c6
Signed-off-by: Manu Gautam mgau...@codeaurora.org
---
 drivers/usb/gadget/f_fs.c | 176 +++---
 drivers/usb/gadget/u_fs.h |   8 ++-
 2 files changed, 142 insertions(+), 42 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 306a2b5..8c7bf04 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -122,8 +122,8 @@ struct ffs_ep {
struct usb_ep   *ep;/* P: ffs-eps_lock */
struct usb_request  *req;   /* P: epfile-mutex */
 
-   /* [0]: full speed, [1]: high speed */
-   struct usb_endpoint_descriptor  *descs[2];
+   /* [0]: full speed, [1]: high speed, [2]: super speed */
+   struct usb_endpoint_descriptor  *descs[3];
 
u8  num;
 
@@ -1184,9 +1184,12 @@ static void ffs_data_reset(struct ffs_data *ffs)
ffs-stringtabs = NULL;
 
ffs-raw_descs_length = 0;
-   ffs-raw_fs_descs_length = 0;
+   ffs-raw_fs_hs_descs_length = 0;
+   ffs-raw_ss_descs_offset = 0;
+   ffs-raw_ss_descs_length = 0;
ffs-fs_descs_count = 0;
ffs-hs_descs_count = 0;
+   ffs-ss_descs_count = 0;
 
ffs-strings_count = 0;
ffs-interfaces_count = 0;
@@ -1329,7 +1332,24 @@ static int ffs_func_eps_enable(struct ffs_function *func)
spin_lock_irqsave(func-ffs-eps_lock, flags);
do {
struct usb_endpoint_descriptor *ds;
-   ds = ep-descs[ep-descs[1] ? 1 : 0];
+   int desc_idx;
+
+   if (ffs-gadget-speed == USB_SPEED_SUPER)
+   desc_idx = 2;
+   else if (ffs-gadget-speed == USB_SPEED_HIGH)
+   desc_idx = 1;
+   else
+   desc_idx = 0;
+
+   /* fall-back to lower speed if desc missing for current speed */
+   do {
+   ds = ep-descs[desc_idx];
+   } while (!ds  --desc_idx = 0);
+
+   if (!ds) {
+   ret = -EINVAL;
+   break;
+   }
 
ep-ep-driver_data = ep;
ep-ep-desc = ds;
@@ -1464,6 +1484,12 @@ static int __must_check ffs_do_desc(char *data, unsigned 
len,
}
break;
 
+   case USB_DT_SS_ENDPOINT_COMP:
+   pr_vdebug(EP SS companion descriptor\n);
+   if (length != sizeof(struct usb_ss_ep_comp_descriptor))
+   goto inv_length;
+   break;
+
case USB_DT_OTHER_SPEED_CONFIG:
case USB_DT_INTERFACE_POWER:
case USB_DT_DEBUG:
@@ -1574,8 +1600,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
 static int __ffs_data_got_descs(struct ffs_data *ffs,
char *const _data, size_t len)
 {
-   unsigned fs_count, hs_count;
-   int fs_len, ret = -EINVAL;
+   unsigned fs_count, hs_count, ss_count = 0;
+   int fs_len, hs_len, ss_len, ret = -EINVAL;
char *data = _data;
 
ENTER();
@@ -1586,9 +1612,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
fs_count = get_unaligned_le32(data +  8);
hs_count = get_unaligned_le32(data + 12);
 
-   if (!fs_count  !hs_count)
-   goto einval;
-
data += 16;
len  -= 16;
 
@@ -1607,22 +1630,58 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
}
 
if (likely(hs_count)) {
-   ret = ffs_do_descs(hs_count, data, len,
+   hs_len = ffs_do_descs(hs_count, data, len,
   __ffs_data_do_entity, ffs);
-   if (unlikely(ret  0))
+   if (unlikely(hs_len  0)) {
+   ret = hs_len;
+   goto error;
+   }
+
+   data += hs_len;
+   len  -= hs_len;
+   } else {
+   hs_len = 0;
+   }
+
+   if (len = 8) {
+   /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */
+   if (get_unaligned_le32(data) != FUNCTIONFS_SS_DESC_MAGIC)
+   goto einval;
+
+   ss_count = get_unaligned_le32(data + 4);
+   data += 8;
+   len  -= 8;
+   }
+
+   if (!fs_count  !hs_count  !ss_count)
+   goto einval;
+
+   if (ss_count) {
+   ss_len = ffs_do_descs(ss_count, data, len,
+  __ffs_data_do_entity, ffs);
+   if (unlikely(ss_len  0)) {
+   ret = ss_len;
  

Re: [PATCH v4 1/1] usb: gadget: f_fs: Add support for SuperSpeed Mode

2013-12-23 Thread Felipe Balbi
On Mon, Dec 23, 2013 at 05:18:42PM +0530, Manu Gautam wrote:
 Allow userspace to pass SuperSpeed descriptors and
 handle them in the driver accordingly.
 This change doesn't modify existing desc_header and thereby
 keeps the ABI changes backward compatible i.e. existing
 userspace drivers compiled with old header (functionfs.h)
 would continue to work with the updated kernel.
 
 Change-Id: Ic27035fdef2a83828024348d75be1518e9f8c5c6

when sending patches upstream, please remove gerrit garbage from commit
log ;-)

I'll wait for Michal to review this one.

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH] regmap: Allow regmap_bulk_write() to work for no-bus regmaps

2013-12-23 Thread Stephen Boyd
On 12/18/13 10:45, Mark Brown wrote:
 On Mon, Dec 16, 2013 at 06:30:47PM -0800, Stephen Boyd wrote:

 -/* No formatting is require if val_byte is 1 */
 -if (val_bytes == 1) {
 -wval = (void *)val;
 +ival = *(unsigned int *)(val + (i * val_bytes));
 +ret = _regmap_write(map, reg + (i * map-reg_stride),
 +ival);
 +if (ret != 0)
 +goto out;
 This doesn't quite work - val is an array of objects of the size of the
 size of a register not of unsigned integers so you're parsing extra data
 out there.  That possibly wasn't the best choice of API but we have
 quite a few users now so ick.

Are you concerned that we'll read past the end of the val buffer? Do we
need to cast the pointer to be the appropriate size according to
val_bytes? Something like this?

for (i = 0; i  val_count; i++) {
unsigned int ival;

switch (val_bytes) {
case 1: 
ival = *(u8 *)(val + (i * val_bytes));
break;
case 2: 
ival = *(u16 *)(val + (i * val_bytes));
break;
case 4: 
ival = *(u32 *)(val + (i * val_bytes));
break;
#ifdef CONFIG_64BIT
case 8: 
ival = *(u64 *)(val + (i * val_bytes));
break;
#endif
default:
ret = -EINVAL;
goto out;
}

ret = _regmap_write(map, reg + (i * map-reg_stride),
ival);
if (ret != 0)
goto out;
}

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 4/7] mfd: ssbi: Add regmap read/write helpers

2013-12-23 Thread Stephen Boyd
Add read and write helper functions that the pm8921-core driver
can use to read and write ssbi regsiters via a no-bus regmap.

Cc: Mark Brown broo...@kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/mfd/ssbi.c   | 13 +
 include/linux/ssbi.h |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/drivers/mfd/ssbi.c b/drivers/mfd/ssbi.c
index b78942e..c5d270f 100644
--- a/drivers/mfd/ssbi.c
+++ b/drivers/mfd/ssbi.c
@@ -269,6 +269,19 @@ int ssbi_write(struct device *dev, u16 addr, const u8 
*buf, int len)
 }
 EXPORT_SYMBOL_GPL(ssbi_write);
 
+int ssbi_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+   *val = 0;
+   return ssbi_read(context, reg, (u8 *)val, 1);
+}
+EXPORT_SYMBOL_GPL(ssbi_reg_read);
+
+int ssbi_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+   return ssbi_write(context, reg, (u8 *)val, 1);
+}
+EXPORT_SYMBOL_GPL(ssbi_reg_write);
+
 static int ssbi_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev-dev.of_node;
diff --git a/include/linux/ssbi.h b/include/linux/ssbi.h
index bcbb642..b862f3d 100644
--- a/include/linux/ssbi.h
+++ b/include/linux/ssbi.h
@@ -20,4 +20,7 @@
 int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len);
 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len);
 
+int ssbi_reg_read(void *context, unsigned int reg, unsigned int *val);
+int ssbi_reg_write(void *context, unsigned int reg, unsigned int val);
+
 #endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 6/7] mfd: pm8921: Add DT match table

2013-12-23 Thread Stephen Boyd
Allow this driver to probe based on devicetree.

Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/mfd/pm8921-core.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index d13cb6e..290f0da 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -420,6 +420,13 @@ static const struct regmap_config ssbi_regmap_config = {
.reg_write = ssbi_reg_write
 };
 
+static const struct of_device_id pm8921_id_table[] = {
+   { .compatible = qcom,pm8058, },
+   { .compatible = qcom,pm8921, },
+   { }
+};
+MODULE_DEVICE_TABLE(of, pm8921_id_table);
+
 static int pm8921_probe(struct platform_device *pdev)
 {
struct pm8921 *pmic;
@@ -429,7 +436,6 @@ static int pm8921_probe(struct platform_device *pdev)
unsigned int irq;
u32 rev;
 
-
irq = platform_get_irq(pdev, 0);
if (irq  0)
return irq;
@@ -494,6 +500,7 @@ static struct platform_driver pm8921_driver = {
.driver = {
.name   = pm8921-core,
.owner  = THIS_MODULE,
+   .of_match_table = pm8921_id_table,
},
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/7] mfd: Move pm8xxx-irq.c contents into only driver that uses it

2013-12-23 Thread Stephen Boyd
The pm8xxx-irq.c code is practically mandatory given that the
pm8921-core driver will WARN about it missing and the Kconfig
marks it as default y when a PM8xxx chips is enabled. The only
reason the file was split out was because we planned to support
other pm8xxx chips with different pm8xxx-core.c files. Now that
we have DT on ARM this isn't necessary because we should be able
to support all the ssbi based PM8xxx chips in one driver and one
file with no data bloat. Let's move this code into the only
driver that uses it right now (pm8921) so that it's always compiled when
needed. In the future we can rename pm8921-core.c to something
more generic.

Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/mfd/Kconfig|  10 --
 drivers/mfd/pm8921-core.c  | 348 ++
 drivers/mfd/pm8xxx-irq.c   | 371 -
 include/linux/mfd/pm8xxx/irq.h |  23 ---
 4 files changed, 348 insertions(+), 404 deletions(-)
 delete mode 100644 drivers/mfd/pm8xxx-irq.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 914c3d1..9ee4ce6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -466,16 +466,6 @@ config MFD_PM8921_CORE
  Say M here if you want to include support for PM8921 chip as a module.
  This will build a module called pm8921-core.
 
-config MFD_PM8XXX_IRQ
-   bool Qualcomm PM8xxx IRQ features
-   depends on MFD_PM8XXX
-   default y if MFD_PM8XXX
-   help
- This is the IRQ driver for Qualcomm PM 8xxx PMIC chips.
-
- This is required to use certain other PM 8xxx features, such as GPIO
- and MPP.
-
 config MFD_RDC321X
tristate RDC R-321x southbridge
select MFD_CORE
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index a6841f7..669f8f2 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -14,6 +14,8 @@
 #define pr_fmt(fmt) %s:  fmt, __func__
 
 #include linux/kernel.h
+#include linux/interrupt.h
+#include linux/irq.h
 #include linux/module.h
 #include linux/platform_device.h
 #include linux/slab.h
@@ -22,15 +24,361 @@
 #include linux/mfd/core.h
 #include linux/mfd/pm8xxx/pm8921.h
 #include linux/mfd/pm8xxx/core.h
+#include linux/mfd/pm8xxx/irq.h
+
+#defineSSBI_REG_ADDR_IRQ_BASE  0x1BB
+
+#defineSSBI_REG_ADDR_IRQ_ROOT  (SSBI_REG_ADDR_IRQ_BASE + 0)
+#defineSSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
+#defineSSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
+#defineSSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
+#defineSSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
+#defineSSBI_REG_ADDR_IRQ_BLK_SEL   (SSBI_REG_ADDR_IRQ_BASE + 5)
+#defineSSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
+#defineSSBI_REG_ADDR_IRQ_CONFIG(SSBI_REG_ADDR_IRQ_BASE + 7)
+#defineSSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
+
+#definePM_IRQF_LVL_SEL 0x01/* level select */
+#definePM_IRQF_MASK_FE 0x02/* mask falling edge */
+#definePM_IRQF_MASK_RE 0x04/* mask rising edge */
+#definePM_IRQF_CLR 0x08/* clear interrupt */
+#definePM_IRQF_BITS_MASK   0x70
+#definePM_IRQF_BITS_SHIFT  4
+#definePM_IRQF_WRITE   0x80
+
+#definePM_IRQF_MASK_ALL(PM_IRQF_MASK_FE | \
+   PM_IRQF_MASK_RE)
 
 #define REG_HWREV  0x002  /* PMIC4 revision */
 #define REG_HWREV_20x0E8  /* PMIC4 revision 2 */
 
+struct pm_irq_chip {
+   struct device   *dev;
+   spinlock_t  pm_irq_lock;
+   unsigned intdevirq;
+   unsigned intirq_base;
+   unsigned intnum_irqs;
+   unsigned intnum_blocks;
+   unsigned intnum_masters;
+   u8  config[0];
+};
+
 struct pm8921 {
struct device   *dev;
struct pm_irq_chip  *irq_chip;
 };
 
+static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp)
+{
+   return pm8xxx_readb(chip-dev, SSBI_REG_ADDR_IRQ_ROOT, rp);
+}
+
+static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp)
+{
+   return pm8xxx_readb(chip-dev,
+   SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp);
+}
+
+static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip)
+{
+   int rc;
+
+   spin_lock(chip-pm_irq_lock);
+   rc = pm8xxx_writeb(chip-dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+   if (rc) {
+   pr_err(Failed Selecting Block %d rc=%d\n, bp, rc);
+   goto bail;
+   }
+
+   rc = pm8xxx_readb(chip-dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
+   if 

[PATCH v2 5/7] mfd: pm8921: Use ssbi regmap

2013-12-23 Thread Stephen Boyd
Use a regmap so that the pm8xxx read/write APIs can be removed
once all consumer drivers are converted.

Cc: Mark Brown broo...@kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/mfd/Kconfig   |  1 +
 drivers/mfd/pm8921-core.c | 72 +++
 2 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 35007ed..e4a3ae2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -455,6 +455,7 @@ config MFD_PM8921_CORE
depends on (ARCH_MSM || HEXAGON)
select MFD_CORE
select MFD_PM8XXX
+   select REGMAP
help
  If you say yes to this option, support will be included for the
  built-in PM8921 PMIC chip.
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 5d1d509..d13cb6e 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -23,6 +23,7 @@
 #include linux/slab.h
 #include linux/err.h
 #include linux/ssbi.h
+#include linux/regmap.h
 #include linux/of_platform.h
 #include linux/mfd/core.h
 #include linux/mfd/pm8xxx/core.h
@@ -55,6 +56,7 @@
 
 struct pm_irq_chip {
struct device   *dev;
+   struct regmap   *regmap;
spinlock_t  pm_irq_lock;
struct irq_domain   *domain;
unsigned intnum_irqs;
@@ -68,29 +70,19 @@ struct pm8921 {
struct pm_irq_chip  *irq_chip;
 };
 
-static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp)
-{
-   return pm8xxx_readb(chip-dev, SSBI_REG_ADDR_IRQ_ROOT, rp);
-}
-
-static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp)
-{
-   return pm8xxx_readb(chip-dev,
-   SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp);
-}
-
-static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip)
+static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
+unsigned int *ip)
 {
int rc;
 
spin_lock(chip-pm_irq_lock);
-   rc = pm8xxx_writeb(chip-dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+   rc = regmap_write(chip-regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
if (rc) {
pr_err(Failed Selecting Block %d rc=%d\n, bp, rc);
goto bail;
}
 
-   rc = pm8xxx_readb(chip-dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
+   rc = regmap_read(chip-regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
if (rc)
pr_err(Failed Reading Status rc=%d\n, rc);
 bail:
@@ -98,19 +90,20 @@ bail:
return rc;
 }
 
-static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp)
+static int
+pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)
 {
int rc;
 
spin_lock(chip-pm_irq_lock);
-   rc = pm8xxx_writeb(chip-dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+   rc = regmap_write(chip-regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
if (rc) {
pr_err(Failed Selecting Block %d rc=%d\n, bp, rc);
goto bail;
}
 
cp |= PM_IRQF_WRITE;
-   rc = pm8xxx_writeb(chip-dev, SSBI_REG_ADDR_IRQ_CONFIG, cp);
+   rc = regmap_write(chip-regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp);
if (rc)
pr_err(Failed Configuring IRQ rc=%d\n, rc);
 bail:
@@ -121,7 +114,7 @@ bail:
 static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
 {
int pmirq, irq, i, ret = 0;
-   u8 bits;
+   unsigned int bits;
 
ret = pm8xxx_read_block_irq(chip, block, bits);
if (ret) {
@@ -146,10 +139,11 @@ static int pm8xxx_irq_block_handler(struct pm_irq_chip 
*chip, int block)
 
 static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
 {
-   u8 blockbits;
+   unsigned int blockbits;
int block_number, i, ret = 0;
 
-   ret = pm8xxx_read_master_irq(chip, master, blockbits);
+   ret = regmap_read(chip-regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master,
+ blockbits);
if (ret) {
pr_err(Failed to read master %d ret=%d\n, master, ret);
return ret;
@@ -171,12 +165,12 @@ static void pm8xxx_irq_handler(unsigned int irq, struct 
irq_desc *desc)
 {
struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
struct irq_chip *irq_chip = irq_desc_get_chip(desc);
-   u8  root;
+   unsigned int root;
int i, ret, masters = 0;
 
chained_irq_enter(irq_chip, desc);
 
-   ret = pm8xxx_read_root_irq(chip, root);
+   ret = regmap_read(chip-regmap, SSBI_REG_ADDR_IRQ_ROOT, root);
if (ret) {
pr_err(Can't read root status ret=%d\n, ret);
return;
@@ -281,7 +275,7 @@ static struct irq_chip pm8xxx_irq_chip = {
 static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
 {
int pmirq, rc;
-   u8  block, bits, bit;
+   unsigned int  block, bits, bit;

[PATCH v2 3/7] mfd: pm8921: Migrate to irqdomains

2013-12-23 Thread Stephen Boyd
Convert this driver to use irqdomains so that the PMIC's child
devices can be converted to devicetree.

Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/mfd/pm8921-core.c | 184 ++
 include/linux/mfd/pm8xxx/irq.h|  36 
 include/linux/mfd/pm8xxx/pm8921.h |  30 ---
 3 files changed, 65 insertions(+), 185 deletions(-)
 delete mode 100644 include/linux/mfd/pm8xxx/irq.h
 delete mode 100644 include/linux/mfd/pm8xxx/pm8921.h

diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 7964932..5d1d509 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -17,15 +17,15 @@
 #include linux/interrupt.h
 #include linux/irqchip/chained_irq.h
 #include linux/irq.h
+#include linux/irqdomain.h
 #include linux/module.h
 #include linux/platform_device.h
 #include linux/slab.h
 #include linux/err.h
 #include linux/ssbi.h
+#include linux/of_platform.h
 #include linux/mfd/core.h
-#include linux/mfd/pm8xxx/pm8921.h
 #include linux/mfd/pm8xxx/core.h
-#include linux/mfd/pm8xxx/irq.h
 
 #defineSSBI_REG_ADDR_IRQ_BASE  0x1BB
 
@@ -56,8 +56,7 @@
 struct pm_irq_chip {
struct device   *dev;
spinlock_t  pm_irq_lock;
-   unsigned intdevirq;
-   unsigned intirq_base;
+   struct irq_domain   *domain;
unsigned intnum_irqs;
unsigned intnum_blocks;
unsigned intnum_masters;
@@ -138,7 +137,7 @@ static int pm8xxx_irq_block_handler(struct pm_irq_chip 
*chip, int block)
for (i = 0; i  8; i++) {
if (bits  (1  i)) {
pmirq = block * 8 + i;
-   irq = pmirq + chip-irq_base;
+   irq = irq_find_mapping(chip-domain, pmirq);
generic_handle_irq(irq);
}
}
@@ -197,12 +196,11 @@ static void pm8xxx_irq_handler(unsigned int irq, struct 
irq_desc *desc)
 static void pm8xxx_irq_mask_ack(struct irq_data *d)
 {
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-   unsigned int pmirq = d-irq - chip-irq_base;
-   int master, irq_bit;
+   unsigned int pmirq = irqd_to_hwirq(d);
+   int irq_bit;
u8  block, config;
 
block = pmirq / 8;
-   master = block / 8;
irq_bit = pmirq % 8;
 
config = chip-config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
@@ -212,12 +210,11 @@ static void pm8xxx_irq_mask_ack(struct irq_data *d)
 static void pm8xxx_irq_unmask(struct irq_data *d)
 {
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-   unsigned int pmirq = d-irq - chip-irq_base;
-   int master, irq_bit;
+   unsigned int pmirq = irqd_to_hwirq(d);
+   int irq_bit;
u8  block, config;
 
block = pmirq / 8;
-   master = block / 8;
irq_bit = pmirq % 8;
 
config = chip-config[pmirq];
@@ -227,12 +224,11 @@ static void pm8xxx_irq_unmask(struct irq_data *d)
 static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-   unsigned int pmirq = d-irq - chip-irq_base;
-   int master, irq_bit;
+   unsigned int pmirq = irqd_to_hwirq(d);
+   int irq_bit;
u8 block, config;
 
block = pmirq / 8;
-   master = block / 8;
irq_bit  = pmirq % 8;
 
chip-config[pmirq] = (irq_bit  PM_IRQF_BITS_SHIFT)
@@ -287,12 +283,9 @@ static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, 
int irq)
int pmirq, rc;
u8  block, bits, bit;
unsigned long flags;
+   struct irq_data *irq_data = irq_get_irq_data(irq);
 
-   if (chip == NULL || irq  chip-irq_base ||
-   irq = chip-irq_base + chip-num_irqs)
-   return -EINVAL;
-
-   pmirq = irq - chip-irq_base;
+   pmirq = irq_data-hwirq;
 
block = pmirq / 8;
bit = pmirq % 8;
@@ -321,64 +314,55 @@ bail_out:
return rc;
 }
 
-static struct pm_irq_chip *pm8xxx_irq_init(struct device *dev,
-   const struct pm8xxx_irq_platform_data *pdata)
+static struct lock_class_key pm8xxx_irq_lock_class;
+
+static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq,
+  irq_hw_number_t hwirq)
 {
-   struct pm_irq_chip  *chip;
-   int devirq, rc;
-   unsigned int pmirq;
+   struct pm_irq_chip *chip = d-host_data;
 
-   if (!pdata) {
-   pr_err(No platform data\n);
-   return ERR_PTR(-EINVAL);
-   }
+   irq_set_lockdep_class(irq, pm8xxx_irq_lock_class);
+   irq_set_chip_and_handler(irq, pm8xxx_irq_chip, handle_level_irq);
+   irq_set_chip_data(irq, chip);
+#ifdef CONFIG_ARM
+   set_irq_flags(irq, IRQF_VALID);
+#else
+   irq_set_noprobe(irq);
+#endif
+   return 0;
+}
 
-   devirq = 

[PATCH v2 2/7] mfd: pm8921: Update for genirq changes

2013-12-23 Thread Stephen Boyd
Since this code has been marked broken for some time a few genirq
tree wide changes weren't made. set_irq_wake() was renamed to
irq_set_irq_wake() in commit a0cd9ca2b (genirq: Namespace
cleanup, 2011-02-10) and commit 10a8c383 (irq: introduce entry
and exit functions for chained handlers) introduced the chained
irq functions but this driver wasn't updated to use them. Fix
these problems and remove the BROKEN marking on this driver.

Acked-by: Lee Jones lee.jo...@linaro.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/mfd/Kconfig   | 1 -
 drivers/mfd/pm8921-core.c | 7 +--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 9ee4ce6..35007ed 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -453,7 +453,6 @@ config MFD_PM8XXX
 config MFD_PM8921_CORE
tristate Qualcomm PM8921 PMIC chip
depends on (ARCH_MSM || HEXAGON)
-   depends on BROKEN
select MFD_CORE
select MFD_PM8XXX
help
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 669f8f2..7964932 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -15,6 +15,7 @@
 
 #include linux/kernel.h
 #include linux/interrupt.h
+#include linux/irqchip/chained_irq.h
 #include linux/irq.h
 #include linux/module.h
 #include linux/platform_device.h
@@ -174,6 +175,8 @@ static void pm8xxx_irq_handler(unsigned int irq, struct 
irq_desc *desc)
u8  root;
int i, ret, masters = 0;
 
+   chained_irq_enter(irq_chip, desc);
+
ret = pm8xxx_read_root_irq(chip, root);
if (ret) {
pr_err(Can't read root status ret=%d\n, ret);
@@ -188,7 +191,7 @@ static void pm8xxx_irq_handler(unsigned int irq, struct 
irq_desc *desc)
if (masters  (1  i))
pm8xxx_irq_master_handler(chip, i);
 
-   irq_chip-irq_ack(desc-irq_data);
+   chained_irq_exit(irq_chip, desc);
 }
 
 static void pm8xxx_irq_mask_ack(struct irq_data *d)
@@ -367,7 +370,7 @@ static struct pm_irq_chip *pm8xxx_irq_init(struct device 
*dev,
irq_set_irq_type(devirq, pdata-irq_trigger_flag);
irq_set_handler_data(devirq, chip);
irq_set_chained_handler(devirq, pm8xxx_irq_handler);
-   set_irq_wake(devirq, 1);
+   irq_set_irq_wake(devirq, 1);
 
return chip;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 7/7] devicetree: bindings: Document PM8921/8058 PMICs

2013-12-23 Thread Stephen Boyd
PM8921 and PM8058 are PMICs found paired with MSM8960 and MSM8660
devices respectively. They contain subdevices such as keypads,
RTC, regulators, clocks, etc.

Cc: devicet...@vger.kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 .../devicetree/bindings/mfd/qcom,pm8xxx.txt| 63 ++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt

diff --git a/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt 
b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
new file mode 100644
index 000..e3fe625
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
@@ -0,0 +1,63 @@
+Qualcomm PM8xxx PMIC multi-function devices
+
+PROPERTIES
+
+- compatible:
+   Usage: required
+   Value type: string
+   Definition: must be one of:
+   qcom,pm8058
+   qcom,pm8921
+
+- #address-cells:
+   Usage: required
+   Value type: u32
+   Definition: must be 1
+
+- #size-cells:
+   Usage: required
+   Value type: u32
+   Definition: must be 0
+
+- interrupts:
+   Usage: required
+   Value type: prop-encoded-array
+   Definition: specifies the interrupt that indicates a subdevice
+   has generated an interrupt (summary interrupt). The
+   format of the specifier is defined by the binding document
+   describing the node's interrupt parent.
+
+- #interrupt-cells:
+   Usage: required
+   Value type : u32
+   Definition: must be 2. Specifies the number of cells needed to encode
+   an interrupt source. The 1st cell contains the interrupt
+   number. The 2nd cell is the trigger type and level flags
+   encoded as follows:
+
+   1 = low-to-high edge triggered
+   2 = high-to-low edge triggered
+   4 = active high level-sensitive
+   8 = active low level-sensitive
+
+- interrupt-controller:
+   Usage: required
+   Value type: empty
+   Definition: identifies this node as an interrupt controller
+
+EXAMPLE
+
+   pmicintc: pmic@0 {
+   compatible = qcom,pm8921;
+   interrupts = 104 8;
+   #interrupt-cells = 2;
+   interrupt-controller;
+   #address-cells = 1;
+   #size-cells = 0;
+
+   pwrkey {
+   compatible = qcom,pm8921-pwrkey;
+   interrupt-parent = pmicintc;
+   interrupts = 50 1, 51 1;
+   };
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/7] Modernize pm8921 with irqdomains, regmap, DT

2013-12-23 Thread Stephen Boyd
These patches lay the groundwork for converting the pm8921 sub-devices
to devicetree as well as simplify the API by migrating the core code
to use the regmap API instead of the custom pm8xxx read/write wrapper.

Changes since v1:
 * First 3 cleanup patches dropped because they're applied upstream
 * New regmap read/write helpers
 * New patch for DT match table
 * New binding document

Stephen Boyd (7):
  mfd: Move pm8xxx-irq.c contents into only driver that uses it
  mfd: pm8921: Update for genirq changes
  mfd: pm8921: Migrate to irqdomains
  mfd: ssbi: Add regmap read/write helpers
  mfd: pm8921: Use ssbi regmap
  mfd: pm8921: Add DT match table
  devicetree: bindings: Document PM8921/8058 PMICs

 .../devicetree/bindings/mfd/qcom,pm8xxx.txt|  63 +++
 drivers/mfd/Kconfig|  12 +-
 drivers/mfd/pm8921-core.c  | 424 ++---
 drivers/mfd/pm8xxx-irq.c   | 371 --
 drivers/mfd/ssbi.c |  13 +
 include/linux/mfd/pm8xxx/irq.h |  59 ---
 include/linux/mfd/pm8xxx/pm8921.h  |  30 --
 include/linux/ssbi.h   |   3 +
 8 files changed, 449 insertions(+), 526 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
 delete mode 100644 drivers/mfd/pm8xxx-irq.c
 delete mode 100644 include/linux/mfd/pm8xxx/irq.h
 delete mode 100644 include/linux/mfd/pm8xxx/pm8921.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/9] CPU enable method based SMP/hotplug + MSM conversion

2013-12-23 Thread Stephen Boyd
This is a rework of patches sent a months back by Rohit[1].
The goal of these patches is to add support for SMP and (basic)
hotplug on MSM based SoCs. To get there, we add support for a
generic way to hook in SMP/hotplug support code based on DT. To
show how it's used, we convert the MSM8660 SMP support code over
to the new method. After that we add support for the rest of the
upstream MSM SoCs (note these patches are piled high on top of
Rohit's patches to add 8074 support to MSM[2] and my follow ups[3,4],
but this should only matter to the MSM maintainers).

This is one of the last items of code that still requires us to have
a mach directory and a machine descriptor. We should be able to move
the hotplug/smp code out of mach directories if this approach is
accepted.

Changes since v1:
 * Added pointers from cpu nodes to saw and acc nodes
 * Squashed nr_cpus removal into reorganization patch
 * Reworked bindings/documentation
 * Rebased onto v3.13-rc4

[1] https://lkml.org/lkml/2013/8/1/770
[2] https://lkml.org/lkml/2013/10/17/520
[3] https://lkml.org/lkml/2013/10/18/406
[4] http://lkml.org/lkml/2013/10/28/501
 

Rohit Vaswani (6):
  devicetree: bindings: Document Krait/Scorpion cpus and enable-method
  ARM: msm: Remove pen_release usage
  ARM: msm: Re-organize platsmp to make it extensible
  ARM: msm: Add SMP support for KPSSv1
  ARM: msm: Add SMP support for KPSSv2
  ARM: dts: msm: Add nodes necessary for SMP boot

Stephen Boyd (3):
  devicetree: bindings: Document qcom,kpss-acc
  devicetree: bindings: Document qcom,saw2 node
  ARM: Introduce CPU_METHOD_OF_DECLARE() for cpu hotplug/smp

 Documentation/devicetree/bindings/arm/cpus.txt |  25 +-
 .../devicetree/bindings/arm/msm/qcom,kpss-acc.txt  |  30 ++
 .../devicetree/bindings/arm/msm/qcom,saw2.txt  |  35 ++
 arch/arm/boot/dts/qcom-msm8660-surf.dts|  24 ++
 arch/arm/boot/dts/qcom-msm8960-cdp.dts |  52 +++
 arch/arm/boot/dts/qcom-msm8974.dtsi|  69 
 arch/arm/include/asm/smp.h |   9 +
 arch/arm/kernel/devtree.c  |  40 +++
 arch/arm/mach-msm/Makefile |   2 +-
 arch/arm/mach-msm/board-dt.c   |  14 -
 arch/arm/mach-msm/common.h |   1 -
 arch/arm/mach-msm/headsmp.S|  39 ---
 arch/arm/mach-msm/hotplug.c|  31 +-
 arch/arm/mach-msm/platsmp.c| 371 -
 arch/arm/mach-msm/scm-boot.h   |   8 +-
 include/asm-generic/vmlinux.lds.h  |  10 +
 16 files changed, 595 insertions(+), 165 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
 delete mode 100644 arch/arm/mach-msm/headsmp.S

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 9/9] ARM: dts: msm: Add nodes necessary for SMP boot

2013-12-23 Thread Stephen Boyd
From: Rohit Vaswani rvasw...@codeaurora.org

Add the necessary nodes to support SMP on MSM8660, MSM8960, and
MSM8974/APQ8074. While we're here also add in the error
interrupts for the Krait cache error detection.

Signed-off-by: Rohit Vaswani rvasw...@codeaurora.org
[sboyd: Split into separate patch, add error interrupts]
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 arch/arm/boot/dts/qcom-msm8660-surf.dts | 24 
 arch/arm/boot/dts/qcom-msm8960-cdp.dts  | 52 +
 arch/arm/boot/dts/qcom-msm8974.dtsi | 69 +
 3 files changed, 145 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts 
b/arch/arm/boot/dts/qcom-msm8660-surf.dts
index 20cb9ad..c72325e 100644
--- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
@@ -9,6 +9,30 @@
compatible = qcom,msm8660-surf, qcom,msm8660;
interrupt-parent = intc;
 
+   cpus {
+   #address-cells = 1;
+   #size-cells = 0;
+   compatible = qcom,scorpion;
+   enable-method = qcom,gcc-msm8660;
+
+   cpu@0 {
+   device_type = cpu;
+   reg = 0;
+   next-level-cache = L2;
+   };
+
+   cpu@1 {
+   device_type = cpu;
+   reg = 1;
+   next-level-cache = L2;
+   };
+
+   L2: l2-cache {
+   compatible = cache;
+   cache-level = 2;
+   };
+   };
+
intc: interrupt-controller@208 {
compatible = qcom,msm-8660-qgic;
interrupt-controller;
diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts 
b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
index d5b1318..bb20f94 100644
--- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
@@ -9,6 +9,36 @@
compatible = qcom,msm8960-cdp, qcom,msm8960;
interrupt-parent = intc;
 
+   cpus {
+   #address-cells = 1;
+   #size-cells = 0;
+   interrupts = 1 14 0x304;
+   compatible = qcom,krait;
+   enable-method = qcom,kpss-acc-v1;
+
+   cpu@0 {
+   device_type = cpu;
+   reg = 0;
+   next-level-cache = L2;
+   qcom,acc = acc0;
+   qcom,saw = saw0;
+   };
+
+   cpu@1 {
+   device_type = cpu;
+   reg = 1;
+   next-level-cache = L2;
+   qcom,acc = acc1;
+   qcom,saw = saw1;
+   };
+
+   L2: l2-cache {
+   compatible = cache;
+   cache-level = 2;
+   interrupts = 0 2 0x4;
+   };
+   };
+
intc: interrupt-controller@200 {
compatible = qcom,msm-qgic2;
interrupt-controller;
@@ -53,6 +83,28 @@
#reset-cells = 1;
};
 
+   acc0: clock-controller@2088000 {
+   compatible = qcom,kpss-acc-v1;
+   reg = 0x02088000 0x1000, 0x02008000 0x1000;
+   };
+
+   acc1: clock-controller@2098000 {
+   compatible = qcom,kpss-acc-v1;
+   reg = 0x02098000 0x1000, 0x02008000 0x1000;
+   };
+
+   saw0: regulator@2089000 {
+   compatible = qcom,saw2;
+   reg = 0x02089000 0x1000, 0x02009000 0x1000;
+   regulator;
+   };
+
+   saw1: regulator@2099000 {
+   compatible = qcom,saw2;
+   reg = 0x02099000 0x1000, 0x02009000 0x1000;
+   regulator;
+   };
+
serial@1644 {
compatible = qcom,msm-uartdm-v1.3, qcom,msm-uartdm;
reg = 0x1644 0x1000,
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 9fa57d7..22555f6 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -9,6 +9,49 @@
compatible = qcom,msm8974;
interrupt-parent = intc;
 
+   cpus {
+   #address-cells = 1;
+   #size-cells = 0;
+   interrupts = 1 9 0xf04;
+   compatible = qcom,krait;
+   enable-method = qcom,kpss-acc-v2;
+
+   cpu@0 {
+   device_type = cpu;
+   reg = 0;
+   next-level-cache = L2;
+   qcom,acc = acc0;
+   };
+
+   cpu@1 {
+   device_type = cpu;
+   reg = 1;
+   next-level-cache = L2;
+   qcom,acc = acc1;
+   };
+
+   cpu@2 {
+   device_type = cpu;
+   reg = 2;

[PATCH v2 3/9] devicetree: bindings: Document qcom,saw2 node

2013-12-23 Thread Stephen Boyd
The saw2 binding describes the SPM/AVS wrapper hardware used to
control the regulator supplying voltage to the Krait CPUs.

Cc: devicet...@vger.kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 .../devicetree/bindings/arm/msm/qcom,saw2.txt  | 35 ++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt 
b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
new file mode 100644
index 000..1505fb8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
@@ -0,0 +1,35 @@
+SPM AVS Wrapper 2 (SAW2)
+
+The SAW2 is a wrapper around the Subsystem Power Manager (SPM) and the
+Adaptive Voltage Scaling (AVS) hardware. The SPM is a programmable
+micro-controller that transitions a piece of hardware (like a processor or
+subsystem) into and out of low power modes via a direct connection to
+the PMIC. It can also be wired up to interact with other processors in the
+system, notifying them when a low power state is entered or exited.
+
+PROPERTIES
+
+- compatible:
+   Usage: required
+   Value type: string
+   Definition: shall contain qcom,saw2. A more specific value should be
+   one of:
+qcom,saw2-v1
+qcom,saw2-v1.1
+qcom,saw2-v2
+qcom,saw2-v2.1
+
+- reg:
+   Usage: required
+   Value type: prop-encoded-array
+   Definition: the first element specifies the base address and size of
+   the register region. An optional second element specifies
+   the base address and size of the alias register region.
+
+
+Example:
+
+   regulator@2099000 {
+   compatible = qcom,saw2;
+   reg = 0x02099000 0x1000, 0x02009000 0x1000;
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 8/9] ARM: msm: Add SMP support for KPSSv2

2013-12-23 Thread Stephen Boyd
From: Rohit Vaswani rvasw...@codeaurora.org

Implement support for the Krait CPU release sequence when the
CPUs are part of the second version of the Krait processor
subsystem.

Signed-off-by: Rohit Vaswani rvasw...@codeaurora.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 arch/arm/mach-msm/platsmp.c | 123 
 1 file changed, 123 insertions(+)

diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 4b13cd8..f07ad9d 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -38,7 +38,15 @@
 #define L2DT_SLP   BIT(3)
 #define CLAMP  BIT(0)
 
+#define APC_PWR_GATE_CTL   0x14
+#define BHS_CNT_SHIFT  24
+#define LDO_PWR_DWN_SHIFT  16
+#define LDO_BYP_SHIFT  8
+#define BHS_SEG_SHIFT  1
+#define BHS_EN BIT(0)
+
 #define APCS_SAW2_VCTL 0x14
+#define APCS_SAW2_2_VCTL   0x1c
 
 extern void secondary_startup(void);
 
@@ -157,6 +165,106 @@ out_acc:
return ret;
 }
 
+static int kpssv2_release_secondary(unsigned int cpu)
+{
+   void __iomem *reg;
+   struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
+   void __iomem *l2_saw_base;
+   unsigned reg_val;
+   int ret;
+
+   cpu_node = of_get_cpu_node(cpu, NULL);
+   if (!cpu_node)
+   return -ENODEV;
+
+   acc_node = of_parse_phandle(cpu_node, qcom,acc, 0);
+   if (!acc_node) {
+   ret = -ENODEV;
+   goto out_acc;
+   }
+
+   l2_node = of_parse_phandle(cpu_node, next-level-cache, 0);
+   if (!l2_node) {
+   ret = -ENODEV;
+   goto out_l2;
+   }
+
+   saw_node = of_parse_phandle(l2_node, qcom,saw, 0);
+   if (!saw_node) {
+   ret = -ENODEV;
+   goto out_saw;
+   }
+
+   reg = of_iomap(acc_node, 0);
+   if (!reg) {
+   ret = -ENOMEM;
+   goto out_map;
+   }
+
+   l2_saw_base = of_iomap(saw_node, 0);
+   if (!l2_saw_base) {
+   ret = -ENOMEM;
+   goto out_saw_map;
+   }
+
+   /* Turn on the BHS, turn off LDO Bypass and power down LDO */
+   reg_val = (64  BHS_CNT_SHIFT) | (0x3f  LDO_PWR_DWN_SHIFT) | BHS_EN;
+   writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+   mb();
+   /* wait for the BHS to settle */
+   udelay(1);
+
+   /* Turn on BHS segments */
+   reg_val |= 0x3f  BHS_SEG_SHIFT;
+   writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+   mb();
+/* wait for the BHS to settle */
+   udelay(1);
+
+   /* Finally turn on the bypass so that BHS supplies power */
+   reg_val |= 0x3f  LDO_BYP_SHIFT;
+   writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+
+   /* enable max phases */
+   writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
+   mb();
+   udelay(50);
+
+   reg_val = COREPOR_RST | CLAMP;
+   writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+   mb();
+   udelay(2);
+
+   reg_val = ~CLAMP;
+   writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+   mb();
+   udelay(2);
+
+   reg_val = ~COREPOR_RST;
+   writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+   mb();
+
+   reg_val |= CORE_PWRD_UP;
+   writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+   mb();
+
+   ret = 0;
+
+   iounmap(l2_saw_base);
+out_saw_map:
+   iounmap(reg);
+out_map:
+   of_node_put(saw_node);
+out_saw:
+   of_node_put(l2_node);
+out_l2:
+   of_node_put(acc_node);
+out_acc:
+   of_node_put(cpu_node);
+
+   return ret;
+}
+
 static DEFINE_PER_CPU(int, cold_boot_done);
 
 static int msm_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
@@ -201,6 +309,11 @@ static int kpssv1_boot_secondary(unsigned int cpu, struct 
task_struct *idle)
return msm_boot_secondary(cpu, kpssv1_release_secondary);
 }
 
+static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+   return msm_boot_secondary(cpu, kpssv2_release_secondary);
+}
+
 static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
 {
int cpu, map;
@@ -250,3 +363,13 @@ static struct smp_operations msm_smp_kpssv1_ops __initdata 
= {
 #endif
 };
 CPU_METHOD_OF_DECLARE(msm_smp_kpssv1, qcom,kpss-acc-v1, msm_smp_kpssv1_ops);
+
+static struct smp_operations msm_smp_kpssv2_ops __initdata = {
+   .smp_prepare_cpus   = msm_smp_prepare_cpus,
+   .smp_secondary_init = msm_secondary_init,
+   .smp_boot_secondary = kpssv2_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+   .cpu_die= msm_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(msm_smp_kpssv2, qcom,kpss-acc-v2, msm_smp_kpssv2_ops);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to 

[PATCH v2 7/9] ARM: msm: Add SMP support for KPSSv1

2013-12-23 Thread Stephen Boyd
From: Rohit Vaswani rvasw...@codeaurora.org

Implement support for the Krait CPU release sequence when the
CPUs are part of the first version of the krait processor
subsystem.

Signed-off-by: Rohit Vaswani rvasw...@codeaurora.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 arch/arm/mach-msm/platsmp.c  | 106 +++
 arch/arm/mach-msm/scm-boot.h |   8 ++--
 2 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 11c6239..4b13cd8 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -30,6 +30,16 @@
 #define SCSS_CPU1CORE_RESET0x2d80
 #define SCSS_DBG_STATUS_CORE_PWRDUP0x2e64
 
+#define APCS_CPU_PWR_CTL   0x04
+#define PLL_CLAMP  BIT(8)
+#define CORE_PWRD_UP   BIT(7)
+#define COREPOR_RSTBIT(5)
+#define CORE_RST   BIT(4)
+#define L2DT_SLP   BIT(3)
+#define CLAMP  BIT(0)
+
+#define APCS_SAW2_VCTL 0x14
+
 extern void secondary_startup(void);
 
 static DEFINE_SPINLOCK(boot_lock);
@@ -68,6 +78,85 @@ static int scss_release_secondary(unsigned int cpu)
return 0;
 }
 
+static int kpssv1_release_secondary(unsigned int cpu)
+{
+   int ret = 0;
+   void __iomem *reg, *saw_reg;
+   struct device_node *cpu_node, *acc_node, *saw_node;
+   u32 val;
+
+   cpu_node = of_get_cpu_node(cpu, NULL);
+   if (!cpu_node)
+   return -ENODEV;
+
+   acc_node = of_parse_phandle(cpu_node, qcom,acc, 0);
+   if (!acc_node) {
+   ret = -ENODEV;
+   goto out_acc;
+   }
+
+   saw_node = of_parse_phandle(cpu_node, qcom,saw, 0);
+   if (!saw_node) {
+   ret = -ENODEV;
+   goto out_saw;
+   }
+
+   reg = of_iomap(acc_node, 0);
+   if (!reg) {
+   ret = -ENOMEM;
+   goto out_acc_map;
+   }
+
+   saw_reg = of_iomap(saw_node, 0);
+   if (!saw_reg) {
+   ret = -ENOMEM;
+   goto out_saw_map;
+   }
+
+   /* Turn on CPU rail */
+   writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
+   mb();
+   udelay(512);
+
+   /* Krait bring-up sequence */
+   val = PLL_CLAMP | L2DT_SLP | CLAMP;
+   writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+   val = ~L2DT_SLP;
+   writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+   mb();
+   ndelay(300);
+
+   val |= COREPOR_RST;
+   writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+   mb();
+   udelay(2);
+
+   val = ~CLAMP;
+   writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+   mb();
+   udelay(2);
+
+   val = ~COREPOR_RST;
+   writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+   mb();
+   udelay(100);
+
+   val |= CORE_PWRD_UP;
+   writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+   mb();
+
+   iounmap(saw_reg);
+out_saw_map:
+   iounmap(reg);
+out_acc_map:
+   of_node_put(saw_node);
+out_saw:
+   of_node_put(acc_node);
+out_acc:
+   of_node_put(cpu_node);
+   return ret;
+}
+
 static DEFINE_PER_CPU(int, cold_boot_done);
 
 static int msm_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
@@ -107,6 +196,11 @@ static int msm8660_boot_secondary(unsigned int cpu, struct 
task_struct *idle)
return msm_boot_secondary(cpu, scss_release_secondary);
 }
 
+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+   return msm_boot_secondary(cpu, kpssv1_release_secondary);
+}
+
 static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
 {
int cpu, map;
@@ -114,6 +208,8 @@ static void __init msm_smp_prepare_cpus(unsigned int 
max_cpus)
static const int cold_boot_flags[] = {
0,
SCM_FLAG_COLDBOOT_CPU1,
+   SCM_FLAG_COLDBOOT_CPU2,
+   SCM_FLAG_COLDBOOT_CPU3,
};
 
for_each_present_cpu(cpu) {
@@ -144,3 +240,13 @@ static struct smp_operations msm_smp_8660_ops __initdata = 
{
 #endif
 };
 CPU_METHOD_OF_DECLARE(msm_smp, qcom,gcc-msm8660, msm_smp_8660_ops);
+
+static struct smp_operations msm_smp_kpssv1_ops __initdata = {
+   .smp_prepare_cpus   = msm_smp_prepare_cpus,
+   .smp_secondary_init = msm_secondary_init,
+   .smp_boot_secondary = kpssv1_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+   .cpu_die= msm_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(msm_smp_kpssv1, qcom,kpss-acc-v1, msm_smp_kpssv1_ops);
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
index 7be32ff..6aabb24 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -13,9 +13,11 @@
 #define __MACH_SCM_BOOT_H
 
 #define SCM_BOOT_ADDR  0x1
-#define SCM_FLAG_COLDBOOT_CPU1 0x1
-#define SCM_FLAG_WARMBOOT_CPU1 0x2
-#define SCM_FLAG_WARMBOOT_CPU0 0x4
+#define SCM_FLAG_COLDBOOT_CPU1 0x01

[PATCH v2 6/9] ARM: msm: Re-organize platsmp to make it extensible

2013-12-23 Thread Stephen Boyd
From: Rohit Vaswani rvasw...@codeaurora.org

This makes it easy to add SMP support for new devices by keying
on a device node for the release sequence. We add the
enable-method property for the cpus property to specify that we
want to use the gcc-msm8660 release sequence (which is going to
look for the global clock controller device node to map some
Scorpion specific power and control registers). We also remove
the nr_cpus detection code as that is done generically in the DT
CPU detection code.

Signed-off-by: Rohit Vaswani rvasw...@codeaurora.org
[sboyd: Port to CPU_METHOD_OF_DECLARE]
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 arch/arm/mach-msm/board-dt.c |  14 --
 arch/arm/mach-msm/common.h   |   1 -
 arch/arm/mach-msm/platsmp.c  | 117 ---
 3 files changed, 65 insertions(+), 67 deletions(-)

diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 1f11d93..1e3af2b 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -11,31 +11,17 @@
  */
 
 #include linux/init.h
-#include linux/of.h
-#include linux/of_platform.h
 
 #include asm/mach/arch.h
-#include asm/mach/map.h
-
-#include common.h
 
 static const char * const msm_dt_match[] __initconst = {
qcom,msm8660-fluid,
qcom,msm8660-surf,
qcom,msm8960-cdp,
-   NULL
-};
-
-static const char * const apq8074_dt_match[] __initconst = {
qcom,apq8074-dragonboard,
NULL
 };
 
 DT_MACHINE_START(MSM_DT, Qualcomm MSM (Flattened Device Tree))
-   .smp = smp_ops(msm_smp_ops),
.dt_compat = msm_dt_match,
 MACHINE_END
-
-DT_MACHINE_START(APQ_DT, Qualcomm MSM (Flattened Device Tree))
-   .dt_compat = apq8074_dt_match,
-MACHINE_END
diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h
index 33c7725..1513f2c 100644
--- a/arch/arm/mach-msm/common.h
+++ b/arch/arm/mach-msm/common.h
@@ -23,7 +23,6 @@ extern void msm_map_qsd8x50_io(void);
 extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
  unsigned int mtype, void *caller);
 
-extern struct smp_operations msm_smp_ops;
 extern void msm_cpu_die(unsigned int cpu);
 
 struct msm_mmc_platform_data;
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 5b481db..11c6239 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -13,6 +13,8 @@
 #include linux/delay.h
 #include linux/device.h
 #include linux/jiffies.h
+#include linux/of.h
+#include linux/of_address.h
 #include linux/smp.h
 #include linux/io.h
 
@@ -24,20 +26,14 @@
 #include scm-boot.h
 #include common.h
 
-#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
-#define SCSS_CPU1CORE_RESET 0xD80
-#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL0x35a0
+#define SCSS_CPU1CORE_RESET0x2d80
+#define SCSS_DBG_STATUS_CORE_PWRDUP0x2e64
 
 extern void secondary_startup(void);
 
 static DEFINE_SPINLOCK(boot_lock);
 
-static inline int get_core_count(void)
-{
-   /* 1 + the PART[1:0] field of MIDR */
-   return ((read_cpuid_id()  4)  3) + 1;
-}
-
 static void msm_secondary_init(unsigned int cpu)
 {
/*
@@ -47,33 +43,41 @@ static void msm_secondary_init(unsigned int cpu)
spin_unlock(boot_lock);
 }
 
-static void prepare_cold_cpu(unsigned int cpu)
+static int scss_release_secondary(unsigned int cpu)
 {
-   int ret;
-   ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
-   SCM_FLAG_COLDBOOT_CPU1);
-   if (ret == 0) {
-   void __iomem *sc1_base_ptr;
-   sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
-   if (sc1_base_ptr) {
-   writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-   writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
-   writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
-   iounmap(sc1_base_ptr);
-   }
-   } else
-   printk(KERN_DEBUG Failed to set secondary core boot 
- address\n);
+   struct device_node *node;
+   void __iomem *base;
+
+   node = of_find_compatible_node(NULL, NULL, qcom,gcc-msm8660);
+   if (!node) {
+   pr_err(%s: can't find node\n, __func__);
+   return -ENXIO;
+   }
+
+   base = of_iomap(node, 0);
+   of_node_put(node);
+   if (!base)
+   return -ENOMEM;
+
+   writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+   writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
+   writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
+   mb();
+   iounmap(base);
+
+   return 0;
 }
 
-static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static DEFINE_PER_CPU(int, cold_boot_done);
+
+static int msm_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
 {
-   static int 

[PATCH v2 2/9] devicetree: bindings: Document qcom,kpss-acc

2013-12-23 Thread Stephen Boyd
The kpss acc binding describes the clock, reset, and power domain
controller for a Krait CPU.

Cc: devicet...@vger.kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 .../devicetree/bindings/arm/msm/qcom,kpss-acc.txt  | 30 ++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt 
b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
new file mode 100644
index 000..1333db9
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
@@ -0,0 +1,30 @@
+Krait Processor Sub-system (KPSS) Application Clock Controller (ACC)
+
+The KPSS ACC provides clock, power domain, and reset control to a Krait CPU.
+There is one ACC register region per CPU within the KPSS remapped region as
+well as an alias register region that remaps accesses to the ACC associated
+with the CPU accessing the region.
+
+PROPERTIES
+
+- compatible:
+   Usage: required
+   Value type: string
+   Definition: should be one of:
+   qcom,kpss-acc-v1
+   qcom,kpss-acc-v2
+
+- reg:
+   Usage: required
+   Value type: prop-encoded-array
+   Definition: the first element specifies the base address and size of
+   the register region. An optional second element specifies
+   the base address and size of the alias register region.
+
+Example:
+
+   clock-controller@2088000 {
+   compatible = qcom,kpss-acc-v2;
+   reg = 0x02088000 0x1000,
+ 0x02008000 0x1000;
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/9] ARM: msm: Remove pen_release usage

2013-12-23 Thread Stephen Boyd
From: Rohit Vaswani rvasw...@codeaurora.org

pen_release is no longer required as the synchronization
is now managed by generic arm code.
This is done as suggested in https://lkml.org/lkml/2013/6/4/184

Cc: Russell King li...@arm.linux.org.uk
Signed-off-by: Rohit Vaswani rvasw...@codeaurora.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 arch/arm/mach-msm/Makefile  |  2 +-
 arch/arm/mach-msm/headsmp.S | 39 ---
 arch/arm/mach-msm/hotplug.c | 31 ---
 arch/arm/mach-msm/platsmp.c | 35 +++
 4 files changed, 8 insertions(+), 99 deletions(-)
 delete mode 100644 arch/arm/mach-msm/headsmp.S

diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 7ed4c1b..15562cf 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -19,7 +19,7 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
 CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_SMP) += platsmp.o
 
 obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o 
devices-msm7x00.o
 obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o 
board-trout-panel.o devices-msm7x00.o
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
deleted file mode 100644
index 6c62c3f..000
--- a/arch/arm/mach-msm/headsmp.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/headsmp.S
- *
- *  Copyright (c) 2003 ARM Limited
- *  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 as
- * published by the Free Software Foundation.
- */
-#include linux/linkage.h
-#include linux/init.h
-
-/*
- * MSM specific entry point for secondary CPUs.  This provides
- * a holding pen into which all secondary cores are held until we're
- * ready for them to initialise.
- */
-ENTRY(msm_secondary_startup)
-   mrc p15, 0, r0, c0, c0, 5
-   and r0, r0, #15
-   adr r4, 1f
-   ldmia   r4, {r5, r6}
-   sub r4, r4, r5
-   add r6, r6, r4
-pen:   ldr r7, [r6]
-   cmp r7, r0
-   bne pen
-
-   /*
-* we've been released from the holding pen: secondary_stack
-* should now contain the SVC stack for this core
-*/
-   b   secondary_startup
-ENDPROC(msm_secondary_startup)
-
-   .align
-1: .long   .
-   .long   pen_release
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 326a872..cea80fc 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -24,33 +24,10 @@ static inline void cpu_leave_lowpower(void)
 
 static inline void platform_do_lowpower(unsigned int cpu)
 {
-   /* Just enter wfi for now. TODO: Properly shut off the cpu. */
-   for (;;) {
-   /*
-* here's the WFI
-*/
-   asm(wfi
-   :
-   :
-   : memory, cc);
-
-   if (pen_release == cpu_logical_map(cpu)) {
-   /*
-* OK, proper wakeup, we're done
-*/
-   break;
-   }
-
-   /*
-* getting here, means that we have come out of WFI without
-* having been woken up - this shouldn't happen
-*
-* The trouble is, letting people know about this is not really
-* possible, since we are currently running incoherently, and
-* therefore cannot safely call printk() or anything else
-*/
-   pr_debug(CPU%u: spurious wakeup call\n, cpu);
-   }
+   asm(wfi
+   :
+   :
+   : memory, cc);
 }
 
 /*
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 3f06edc..5b481db 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -28,7 +28,7 @@
 #define SCSS_CPU1CORE_RESET 0xD80
 #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
 
-extern void msm_secondary_startup(void);
+extern void secondary_startup(void);
 
 static DEFINE_SPINLOCK(boot_lock);
 
@@ -41,13 +41,6 @@ static inline int get_core_count(void)
 static void msm_secondary_init(unsigned int cpu)
 {
/*
-* let the primary processor know we're out of the
-* pen, then head off into the C entry point
-*/
-   pen_release = -1;
-   smp_wmb();
-
-   /*
 * Synchronise with the boot thread.
 */
spin_lock(boot_lock);
@@ -57,7 +50,7 @@ static void msm_secondary_init(unsigned int cpu)
 static void prepare_cold_cpu(unsigned int cpu)
 {
int ret;
-   ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
+   ret = 

[PATCH v2 4/9] ARM: Introduce CPU_METHOD_OF_DECLARE() for cpu hotplug/smp

2013-12-23 Thread Stephen Boyd
The goal of multi-platform kernels is to remove the need for mach
directories and machine descriptors. To further that goal,
introduce CPU_METHOD_OF_DECLARE() to allow cpu hotplug/smp
support to be separated from the machine descriptors.
Implementers should specify an enable-method property in their
cpus node and then implement a matching set of smp_ops in their
hotplug/smp code, wiring it up with the CPU_METHOD_OF_DECLARE()
macro. When the kernel is compiled we'll collect all the
enable-method smp_ops into one section for use at boot.

At boot time we'll look for an enable-method in each cpu node and
try to match that against all known CPU enable methods in the
kernel. If there are no enable-methods in the cpu nodes we
fallback to the cpus node and try to use any enable-method found
there. If that doesn't work we fall back to the old way of using
the machine descriptor.

Cc: Mark Rutland mark.rutl...@arm.com
Cc: Russell King li...@arm.linux.org.uk
Cc: devicet...@vger.kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 arch/arm/include/asm/smp.h|  9 +
 arch/arm/kernel/devtree.c | 40 +++
 include/asm-generic/vmlinux.lds.h | 10 ++
 3 files changed, 59 insertions(+)

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 22a3b9b..772435b 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -114,6 +114,15 @@ struct smp_operations {
 #endif
 };
 
+struct of_cpu_method {
+   const char *method;
+   struct smp_operations *ops;
+};
+
+#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
+   static const struct of_cpu_method __cpu_method_of_table_##name  \
+   __used __section(__cpu_method_of_table) \
+   = { .method = _method, .ops = _ops }
 /*
  * set platform specific SMP operations
  */
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 739c3df..91cc3f8 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -18,6 +18,7 @@
 #include linux/of_fdt.h
 #include linux/of_irq.h
 #include linux/of_platform.h
+#include linux/smp.h
 
 #include asm/cputype.h
 #include asm/setup.h
@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void)
}
 }
 
+#ifdef CONFIG_SMP
+extern struct of_cpu_method __cpu_method_of_table_begin[];
+extern struct of_cpu_method __cpu_method_of_table_end[];
+
+static int __init set_smp_ops_by_method(struct device_node *node)
+{
+   const char *method;
+   struct of_cpu_method *m = __cpu_method_of_table_begin;
+
+   if (of_property_read_string(node, enable-method, method))
+   return 0;
+
+   for (; m  __cpu_method_of_table_end; m++)
+   if (!strcmp(m-method, method)) {
+   smp_set_ops(m-ops);
+   return 1;
+   }
+
+   return 0;
+}
+#else
+static inline int set_smp_ops_by_method(struct device_node *node)
+{
+   return 1;
+}
+#endif
+
+
 /*
  * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
  * and builds the cpu logical map array containing MPIDR values related to
@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
 * read as 0.
 */
struct device_node *cpu, *cpus;
+   int found_method = 0;
u32 i, j, cpuidx = 1;
u32 mpidr = is_smp() ? read_cpuid_mpidr()  MPIDR_HWID_BITMASK : 0;
 
@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
}
 
tmp_map[i] = hwid;
+
+   if (!found_method)
+   found_method = set_smp_ops_by_method(cpu);
}
 
+   /*
+* Fallback to an enable-method in the cpus node if nothing found in
+* a cpu node.
+*/
+   if (!found_method)
+   set_smp_ops_by_method(cpus);
+
if (!bootcpu_valid) {
pr_warn(DT missing boot CPU MPIDR[23:0], fall back to default 
cpu_logical_map\n);
return;
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index bc2121f..bd02ca7 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -167,6 +167,15 @@
 #define CLK_OF_TABLES()
 #endif
 
+#ifdef CONFIG_SMP
+#define CPU_METHOD_OF_TABLES() . = ALIGN(8);   \
+  VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
+  *(__cpu_method_of_table) \
+  VMLINUX_SYMBOL(__cpu_method_of_table_end) = .;
+#else
+#define CPU_METHOD_OF_TABLES()
+#endif
+
 #define KERNEL_DTB()   \
STRUCT_ALIGN(); \
VMLINUX_SYMBOL(__dtb_start) = .;\
@@ -491,6 +500,7 @@
MEM_DISCARD(init.rodata)\

[PATCH v2 1/9] devicetree: bindings: Document Krait/Scorpion cpus and enable-method

2013-12-23 Thread Stephen Boyd
From: Rohit Vaswani rvasw...@codeaurora.org

Scorpion and Krait don't use the spin-table enable-method.
Instead they rely on mmio register accesses to enable power and
clocks to bring CPUs out of reset. Document their enable-methods.

Cc: devicet...@vger.kernel.org
Signed-off-by: Rohit Vaswani rvasw...@codeaurora.org
[sboyd: Split off into separate patch, renamed methods to
match compatible nodes]
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 Documentation/devicetree/bindings/arm/cpus.txt | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt 
b/Documentation/devicetree/bindings/arm/cpus.txt
index 9130435..333f4ae 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -180,7 +180,11 @@ nodes to be present and contain the properties described 
below.
  be one of:
 spin-table
 psci
-   # On ARM 32-bit systems this property is optional.
+   # On ARM 32-bit systems this property is optional and
+ can be one of:
+   qcom,gcc-msm8660
+   qcom,kpss-acc-v1
+   qcom,kpss-acc-v2
 
- cpu-release-addr
Usage: required for systems that have an enable-method
@@ -191,6 +195,21 @@ nodes to be present and contain the properties described 
below.
  property identifying a 64-bit zero-initialised
  memory location.
 
+   - qcom,saw
+   Usage: required for systems that have an enable-method
+  property value of qcom,kpss-acc-v1 or
+  qcom,kpss-acc-v2
+   Value type: phandle
+   Definition: Specifies the SAW[1] node associated with this CPU.
+
+   - qcom,acc
+   Usage: required for systems that have an enable-method
+  property value of qcom,kpss-acc-v1 or
+  qcom,kpss-acc-v2
+   Value type: phandle
+   Definition: Specifies the ACC[2] node associated with this CPU.
+
+
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
cpus {
@@ -382,3 +401,7 @@ cpus {
cpu-release-addr = 0 0x2000;
};
 };
+
+--
+[1] arm/msm/qcom,saw2.txt
+[2] arm/msm/qcom,kpss-acc.txt
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 00/15] Add support for MSM's mmio clock/reset controller

2013-12-23 Thread Stephen Boyd
The first breaks a reset-controller include ordering requirement. I hope it can
go through the clock tree.

The next 3 patches are generic clock framework patches. They add support for
regmap and for setting the rate and the parent at the same time based on
patches from James Hogan's remuxing set_rate series.

After that we add MSM clock hardware support and SoC specific drivers. The DT
node additions will be sent through the MSM maintainers once these patches are
accepted.

Changes since v3:
 * Moved binding include to clock/
 * New patch for 8660 GCC driver
 * Renamed directory to qcom to match vendor prefix
 * Added some missing clocks in 8974 GCC driver
 * New patch for 8974 MMCC driver

Changes since v2:

 * Completed 8960 and 8974 GCC data  dt-bindings
 * Added support for reset controllers
 * Squashed some bugs in 8974 gcc clocks
 * New patch to fix clk NULL pointer deref
 * New patch to fix #include requirement for reset-controller.h

Changes since v1:

 * Rewrote binding to use #clock-cells=1
 * Reworked library components (pll, rcg, branch) to use regmap
 * Dropped common clock framework patches that did DT parsing
 * New patches for regmap support in common clock framework

Stephen Boyd (15):
  reset: Silence warning in reset-controller.h
  clk: Allow drivers to pass in a regmap
  clk: Add regmap core helpers for enable/disable/is_enabled
  clk: Add set_rate_and_parent() op
  clk: qcom: Add support for phase locked loops (PLLs)
  clk: qcom: Add support for root clock generators (RCGs)
  clk: qcom: Add support for branches/gate clocks
  clk: qcom: Add reset controller support
  clk: qcom: Add support for MSM8960's global clock controller (GCC)
  clk: qcom: Add support for MSM8960's multimedia clock controller
(MMCC)
  clk: qcom: Add support for MSM8974's global clock controller (GCC)
  clk: qcom: Add support for MSM8974's multimedia clock controller
(MMCC)
  clk: qcom: Add support for MSM8660's global clock controller (GCC)
  devicetree: bindings: Document qcom,gcc
  devicetree: bindings: Document qcom,mmcc

 Documentation/clk.txt  |3 +
 .../devicetree/bindings/clock/qcom,gcc.txt |   21 +
 .../devicetree/bindings/clock/qcom,mmcc.txt|   21 +
 drivers/clk/Kconfig|2 +
 drivers/clk/Makefile   |1 +
 drivers/clk/clk.c  |  156 +-
 drivers/clk/qcom/Kconfig   |   47 +
 drivers/clk/qcom/Makefile  |   13 +
 drivers/clk/qcom/clk-branch.c  |  159 ++
 drivers/clk/qcom/clk-branch.h  |   53 +
 drivers/clk/qcom/clk-pll.c |  222 ++
 drivers/clk/qcom/clk-pll.h |   65 +
 drivers/clk/qcom/clk-rcg.c |  517 
 drivers/clk/qcom/clk-rcg.h |  157 +
 drivers/clk/qcom/clk-rcg2.c|  291 ++
 drivers/clk/qcom/gcc-msm8660.c | 2818 ++
 drivers/clk/qcom/gcc-msm8960.c | 2992 
 drivers/clk/qcom/gcc-msm8974.c | 2693 ++
 drivers/clk/qcom/mmcc-msm8960.c| 2320 +++
 drivers/clk/qcom/mmcc-msm8974.c| 2624 +
 drivers/clk/qcom/reset.c   |   63 +
 drivers/clk/qcom/reset.h   |   37 +
 include/dt-bindings/clock/qcom,gcc-msm8660.h   |  276 ++
 include/dt-bindings/clock/qcom,gcc-msm8960.h   |  313 ++
 include/dt-bindings/clock/qcom,gcc-msm8974.h   |  320 +++
 include/dt-bindings/clock/qcom,mmcc-msm8960.h  |  137 +
 include/dt-bindings/clock/qcom,mmcc-msm8974.h  |  161 ++
 include/dt-bindings/reset/qcom,gcc-msm8660.h   |  134 +
 include/dt-bindings/reset/qcom,gcc-msm8960.h   |  118 +
 include/dt-bindings/reset/qcom,gcc-msm8974.h   |   96 +
 include/dt-bindings/reset/qcom,mmcc-msm8960.h  |   93 +
 include/dt-bindings/reset/qcom,mmcc-msm8974.h  |   62 +
 include/linux/clk-provider.h   |   35 +
 include/linux/reset-controller.h   |1 +
 34 files changed, 17002 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc.txt
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,mmcc.txt
 create mode 100644 drivers/clk/qcom/Kconfig
 create mode 100644 drivers/clk/qcom/Makefile
 create mode 100644 drivers/clk/qcom/clk-branch.c
 create mode 100644 drivers/clk/qcom/clk-branch.h
 create mode 100644 drivers/clk/qcom/clk-pll.c
 create mode 100644 drivers/clk/qcom/clk-pll.h
 create mode 100644 drivers/clk/qcom/clk-rcg.c
 create mode 100644 drivers/clk/qcom/clk-rcg.h
 create mode 100644 drivers/clk/qcom/clk-rcg2.c
 create mode 100644 drivers/clk/qcom/gcc-msm8660.c
 create mode 100644 drivers/clk/qcom/gcc-msm8960.c
 create mode 100644 

[PATCH v4 15/15] devicetree: bindings: Document qcom,mmcc

2013-12-23 Thread Stephen Boyd
Document the multimedia clock controller found on MSM devices

Cc: devicet...@vger.kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 .../devicetree/bindings/clock/qcom,mmcc.txt | 21 +
 1 file changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,mmcc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
new file mode 100644
index 000..d572e99
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
@@ -0,0 +1,21 @@
+Qualcomm Multimedia Clock  Reset Controller Binding
+
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+   qcom,mmcc-msm8660
+   qcom,mmcc-msm8960
+   qcom,mmcc-msm8974
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+- #reset-cells : shall contain 1
+
+Example:
+   clock-controller@400 {
+   compatible = qcom,mmcc-msm8960;
+   reg = 0x400 0x1000;
+   #clock-cells = 1;
+   #reset-cells = 1;
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 14/15] devicetree: bindings: Document qcom,gcc

2013-12-23 Thread Stephen Boyd
Document the global clock controller found on MSM devices.

Cc: devicet...@vger.kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 .../devicetree/bindings/clock/qcom,gcc.txt  | 21 +
 1 file changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
new file mode 100644
index 000..767401f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -0,0 +1,21 @@
+Qualcomm Global Clock  Reset Controller Binding
+
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+   qcom,gcc-msm8660
+   qcom,gcc-msm8960
+   qcom,gcc-msm8974
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+- #reset-cells : shall contain 1
+
+Example:
+   clock-controller@90 {
+   compatible = qcom,gcc-msm8960;
+   reg = 0x90 0x4000;
+   #clock-cells = 1;
+   #reset-cells = 1;
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 06/15] clk: qcom: Add support for root clock generators (RCGs)

2013-12-23 Thread Stephen Boyd
Add support for the root clock generators on Qualcomm devices.
RCGs are highly customizable mux/divider/counter clocks that can
be used to generate almost any rate desired given some input
source that is faster than the desired rate.

Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/clk/qcom/Makefile   |   2 +
 drivers/clk/qcom/clk-rcg.c  | 517 
 drivers/clk/qcom/clk-rcg.h  | 157 ++
 drivers/clk/qcom/clk-rcg2.c | 291 +
 4 files changed, 967 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-rcg.c
 create mode 100644 drivers/clk/qcom/clk-rcg.h
 create mode 100644 drivers/clk/qcom/clk-rcg2.c

diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 9849a99..7ed16d7 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -1,3 +1,5 @@
 obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
 
 clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o
+clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o
+clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o
diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
new file mode 100644
index 000..afc0401
--- /dev/null
+++ b/drivers/clk/qcom/clk-rcg.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/kernel.h
+#include linux/bitops.h
+#include linux/err.h
+#include linux/export.h
+#include linux/clk-provider.h
+#include linux/regmap.h
+
+#include asm/div64.h
+
+#include clk-rcg.h
+
+static u32 ns_to_src(struct src_sel *s, u32 ns)
+{
+   ns = s-src_sel_shift;
+   ns = SRC_SEL_MASK;
+   return ns;
+}
+
+static u32 src_to_ns(struct src_sel *s, u8 src, u32 ns)
+{
+   u32 mask;
+
+   mask = SRC_SEL_MASK;
+   mask = s-src_sel_shift;
+   ns = ~mask;
+
+   ns |= src  s-src_sel_shift;
+   return ns;
+}
+
+static u8 clk_rcg_get_parent(struct clk_hw *hw)
+{
+   struct clk_rcg *rcg = to_clk_rcg(hw);
+   int num_parents = __clk_get_num_parents(hw-clk);
+   u32 ns;
+   int i;
+
+   regmap_read(hw-regmap, rcg-ns_reg, ns);
+   ns = ns_to_src(rcg-s, ns);
+   for (i = 0; i  num_parents; i++)
+   if (ns == rcg-s.parent_map[i])
+   return i;
+
+   return -EINVAL;
+}
+
+static int reg_to_bank(struct clk_dyn_rcg *rcg, u32 bank)
+{
+   bank = BIT(rcg-mux_sel_bit);
+   return !!bank;
+}
+
+static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
+{
+   struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
+   int num_parents = __clk_get_num_parents(hw-clk);
+   u32 ns, ctl;
+   int bank;
+   int i;
+   struct src_sel *s;
+
+   regmap_read(hw-regmap, hw-enable_reg, ctl);
+   bank = reg_to_bank(rcg, ctl);
+   s = rcg-s[bank];
+
+   regmap_read(hw-regmap, rcg-ns_reg, ns);
+   ns = ns_to_src(s, ns);
+
+   for (i = 0; i  num_parents; i++)
+   if (ns == s-parent_map[i])
+   return i;
+
+   return -EINVAL;
+}
+
+static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct clk_rcg *rcg = to_clk_rcg(hw);
+   u32 ns;
+
+   regmap_read(hw-regmap, rcg-ns_reg, ns);
+   ns = src_to_ns(rcg-s, rcg-s.parent_map[index], ns);
+   regmap_write(hw-regmap, rcg-ns_reg, ns);
+
+   return 0;
+}
+
+static u32 md_to_m(struct mn *mn, u32 md)
+{
+   md = mn-m_val_shift;
+   md = BIT(mn-width) - 1;
+   return md;
+}
+
+static u32 ns_to_pre_div(struct pre_div *p, u32 ns)
+{
+   ns = p-pre_div_shift;
+   ns = BIT(p-pre_div_width) - 1;
+   return ns;
+}
+
+static u32 pre_div_to_ns(struct pre_div *p, u8 pre_div, u32 ns)
+{
+   u32 mask;
+
+   mask = BIT(p-pre_div_width) - 1;
+   mask = p-pre_div_shift;
+   ns = ~mask;
+
+   ns |= pre_div  p-pre_div_shift;
+   return ns;
+}
+
+static u32 mn_to_md(struct mn *mn, u32 m, u32 n, u32 md)
+{
+   u32 mask, mask_w;
+
+   mask_w = BIT(mn-width) - 1;
+   mask = (mask_w  mn-m_val_shift) | mask_w;
+   md = ~mask;
+
+   if (n) {
+   m = mn-m_val_shift;
+   md |= m;
+   md |= ~n  mask_w;
+   }
+
+   return md;
+}
+
+static u32 ns_m_to_n(struct mn *mn, u32 ns, u32 m)
+{
+   ns = ~ns  mn-n_val_shift;
+   ns = BIT(mn-width) - 1;
+   return ns + m;
+}
+
+static u32 reg_to_mnctr_mode(struct mn *mn, u32 val)
+{
+   val = mn-mnctr_mode_shift;
+   val = MNCTR_MODE_MASK;
+   return val;
+}
+
+static u32 

[PATCH v4 01/15] reset: Silence warning in reset-controller.h

2013-12-23 Thread Stephen Boyd
If a user of linux/reset-controller.h doesn't include
linux/of.h before including reset-controller.h they'll get a
warning as follows:

  include/linux/reset-controller.h:44:17:
  warning: 'struct of_phandle_args' declared inside parameter list

This is because of_phandle_args is not forward declared. Add the
declaration to silence this warning.

Cc: Philipp Zabel p.za...@pengutronix.de
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 include/linux/reset-controller.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index 2f61311..41a4695 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -21,6 +21,7 @@ struct reset_control_ops {
 
 struct module;
 struct device_node;
+struct of_phandle_args;
 
 /**
  * struct reset_controller_dev - reset controller entity that might
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 08/15] clk: qcom: Add reset controller support

2013-12-23 Thread Stephen Boyd
Reset controllers and clock controllers are combined into one IP
block on Qualcomm chipsets. Usually a reset signal is associated
with each clock branch but sometimes a reset signal is associated
with a handful of clocks. Either way the register interface is
the same; set a bit to assert a reset and clear a bit to deassert
a reset. Add support for these types of resets signals.

Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/clk/qcom/Kconfig  |  2 +-
 drivers/clk/qcom/Makefile |  1 +
 drivers/clk/qcom/reset.c  | 63 +++
 drivers/clk/qcom/reset.h  | 37 
 4 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/qcom/reset.c
 create mode 100644 drivers/clk/qcom/reset.h

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 73a8c8f..06ccce6 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -2,4 +2,4 @@ config COMMON_CLK_QCOM
tristate Support for Qualcomm's clock controllers
depends on OF
select REGMAP_MMIO
-
+   select RESET_CONTROLLER
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 58a5ab3..b2568be 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -4,3 +4,4 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o
 clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o
 clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o
 clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o
+clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o
diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
new file mode 100644
index 000..6c977d3
--- /dev/null
+++ b/drivers/clk/qcom/reset.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/bitops.h
+#include linux/export.h
+#include linux/regmap.h
+#include linux/reset-controller.h
+#include linux/delay.h
+
+#include reset.h
+
+static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+   rcdev-ops-assert(rcdev, id);
+   udelay(1);
+   rcdev-ops-deassert(rcdev, id);
+   return 0;
+}
+
+static int
+qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+   struct qcom_reset_controller *rst;
+   const struct qcom_reset_map *map;
+   u32 mask;
+
+   rst = to_qcom_reset_controller(rcdev);
+   map = rst-reset_map[id];
+   mask = BIT(map-bit);
+
+   return regmap_update_bits(rst-regmap, map-reg, mask, mask);
+}
+
+static int
+qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+   struct qcom_reset_controller *rst;
+   const struct qcom_reset_map *map;
+   u32 mask;
+
+   rst = to_qcom_reset_controller(rcdev);
+   map = rst-reset_map[id];
+   mask = BIT(map-bit);
+
+   return regmap_update_bits(rst-regmap, map-reg, mask, 0);
+}
+
+struct reset_control_ops qcom_reset_ops = {
+   .reset = qcom_reset,
+   .assert = qcom_reset_assert,
+   .deassert = qcom_reset_deassert,
+};
+EXPORT_SYMBOL_GPL(qcom_reset_ops);
diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h
new file mode 100644
index 000..e22b167
--- /dev/null
+++ b/drivers/clk/qcom/reset.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_CLK_RESET_H__
+#define __MSM_CLK_RESET_H__
+
+#include linux/reset-controller.h
+
+struct qcom_reset_map {
+   unsigned int reg;
+   u8 bit;
+};
+
+struct regmap;
+
+struct qcom_reset_controller {
+   const struct qcom_reset_map *reset_map;
+   struct regmap *regmap;
+   struct reset_controller_dev rcdev;
+};
+
+#define to_qcom_reset_controller(r) \
+   container_of(r, struct qcom_reset_controller, rcdev);
+
+extern struct reset_control_ops qcom_reset_ops;
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message 

[PATCH v4 02/15] clk: Allow drivers to pass in a regmap

2013-12-23 Thread Stephen Boyd
Add support to the clock core so that drivers can pass in a
regmap. If no regmap is specified try to query the device that's
registering the clock for its regmap. This should allow drivers
to use the core regmap helpers. This is based on a similar design
in the regulator framework.

Cc: Mark Brown broo...@kernel.org
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/clk/clk.c| 8 
 include/linux/clk-provider.h | 7 +++
 2 files changed, 15 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 9ad7b71..5e71f5c 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -20,6 +20,7 @@
 #include linux/device.h
 #include linux/init.h
 #include linux/sched.h
+#include linux/regmap.h
 
 static DEFINE_SPINLOCK(enable_lock);
 static DEFINE_MUTEX(prepare_lock);
@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct 
clk_hw *hw, struct clk *clk)
clk-num_parents = hw-init-num_parents;
hw-clk = clk;
 
+   if (hw-init-regmap)
+   hw-regmap = hw-init-regmap;
+   else if (dev  dev_get_regmap(dev, NULL))
+   hw-regmap = dev_get_regmap(dev, NULL);
+   else if (dev  dev-parent)
+   hw-regmap = dev_get_regmap(dev-parent, NULL);
+
/* allocate local copy in case parent_names is __initdata */
clk-parent_names = kcalloc(clk-num_parents, sizeof(char *),
GFP_KERNEL);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7e59253..31f2890 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -142,6 +142,8 @@ struct clk_ops {
void(*init)(struct clk_hw *hw);
 };
 
+struct regmap;
+
 /**
  * struct clk_init_data - holds init data that's common to all clocks and is
  * shared between the clock provider and the common clock framework.
@@ -151,6 +153,7 @@ struct clk_ops {
  * @parent_names: array of string names for all possible parents
  * @num_parents: number of possible parents
  * @flags: framework-level hints and quirks
+ * @regmap: regmap to use for regmap helpers and/or by providers
  */
 struct clk_init_data {
const char  *name;
@@ -158,6 +161,7 @@ struct clk_init_data {
const char  **parent_names;
u8  num_parents;
unsigned long   flags;
+   struct regmap   *regmap;
 };
 
 /**
@@ -171,10 +175,13 @@ struct clk_init_data {
  *
  * @init: pointer to struct clk_init_data that contains the init data shared
  * with the common clock framework.
+ *
+ * @regmap: regmap to use for regmap helpers and/or by providers
  */
 struct clk_hw {
struct clk *clk;
const struct clk_init_data *init;
+   struct regmap *regmap;
 };
 
 /*
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 05/15] clk: qcom: Add support for phase locked loops (PLLs)

2013-12-23 Thread Stephen Boyd
Add support for Qualcomm's PLLs (phase locked loops). This is
sufficient enough to be able to determine the rate the PLL is
running at. We can add rate setting support later when it's
needed.

Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 drivers/clk/Kconfig|   2 +
 drivers/clk/Makefile   |   1 +
 drivers/clk/qcom/Kconfig   |   5 +
 drivers/clk/qcom/Makefile  |   3 +
 drivers/clk/qcom/clk-pll.c | 222 +
 drivers/clk/qcom/clk-pll.h |  65 +
 6 files changed, 298 insertions(+)
 create mode 100644 drivers/clk/qcom/Kconfig
 create mode 100644 drivers/clk/qcom/Makefile
 create mode 100644 drivers/clk/qcom/clk-pll.c
 create mode 100644 drivers/clk/qcom/clk-pll.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 5c51115..afd2a45 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -107,6 +107,8 @@ config COMMON_CLK_KEYSTONE
   Supports clock drivers for Keystone based SOCs. These SOCs have local
  a power sleep control module that gate the clock to the IPs and PLLs.
 
+source drivers/clk/qcom/Kconfig
+
 endmenu
 
 source drivers/clk/mvebu/Kconfig
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 7a10bc9..088b517 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_PLAT_SPEAR)  += spear/
 obj-$(CONFIG_ARCH_U300)+= clk-u300.o
 obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
 obj-$(CONFIG_ARCH_SIRF)+= clk-prima2.o
+obj-$(CONFIG_COMMON_CLK_QCOM)  += qcom/
 obj-$(CONFIG_PLAT_ORION)   += mvebu/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP) += mmp/
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
new file mode 100644
index 000..73a8c8f
--- /dev/null
+++ b/drivers/clk/qcom/Kconfig
@@ -0,0 +1,5 @@
+config COMMON_CLK_QCOM
+   tristate Support for Qualcomm's clock controllers
+   depends on OF
+   select REGMAP_MMIO
+
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
new file mode 100644
index 000..9849a99
--- /dev/null
+++ b/drivers/clk/qcom/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
+
+clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o
diff --git a/drivers/clk/qcom/clk-pll.c b/drivers/clk/qcom/clk-pll.c
new file mode 100644
index 000..b0d2a4e
--- /dev/null
+++ b/drivers/clk/qcom/clk-pll.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/kernel.h
+#include linux/bitops.h
+#include linux/err.h
+#include linux/bug.h
+#include linux/delay.h
+#include linux/export.h
+#include linux/clk-provider.h
+#include linux/regmap.h
+
+#include asm/div64.h
+
+#include clk-pll.h
+
+#define PLL_OUTCTRLBIT(0)
+#define PLL_BYPASSNL   BIT(1)
+#define PLL_RESET_NBIT(2)
+#define PLL_LOCK_COUNT_SHIFT   8
+#define PLL_LOCK_COUNT_MASK0x3f
+#define PLL_BIAS_COUNT_SHIFT   14
+#define PLL_BIAS_COUNT_MASK0x3f
+#define PLL_VOTE_FSM_ENA   BIT(20)
+#define PLL_VOTE_FSM_RESET BIT(21)
+
+static int clk_pll_enable(struct clk_hw *hw)
+{
+   struct clk_pll *pll = to_clk_pll(hw);
+   int ret;
+   u32 mask, val;
+
+   mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
+   ret = regmap_read(hw-regmap, pll-mode_reg, val);
+   if (ret)
+   return ret;
+
+   /* Skip if already enabled or in FSM mode */
+   if ((val  mask) == mask || val  PLL_VOTE_FSM_ENA)
+   return 0;
+
+   /* Disable PLL bypass mode. */
+   ret = regmap_update_bits(hw-regmap, pll-mode_reg, PLL_BYPASSNL,
+PLL_BYPASSNL);
+   if (ret)
+   return ret;
+
+   /*
+* H/W requires a 5us delay between disabling the bypass and
+* de-asserting the reset. Delay 10us just to be safe.
+*/
+   udelay(10);
+
+   /* De-assert active-low PLL reset. */
+   ret = regmap_update_bits(hw-regmap, pll-mode_reg, PLL_RESET_N,
+PLL_RESET_N);
+   if (ret)
+   return ret;
+
+   /* Wait until PLL is locked. */
+   udelay(50);
+
+   /* Enable PLL output. */
+   ret = regmap_update_bits(hw-regmap, pll-mode_reg, PLL_OUTCTRL,
+PLL_OUTCTRL);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static void clk_pll_disable(struct clk_hw *hw)
+{
+   struct clk_pll *pll = to_clk_pll(hw);
+   u32 mask;
+

[PATCH v4 04/15] clk: Add set_rate_and_parent() op

2013-12-23 Thread Stephen Boyd
Some of Qualcomm's clocks can change their parent and rate at the
same time with a single register write. Add support for this
hardware to the common clock framework by adding a new
set_rate_and_parent() op. When the clock framework determines
that both the parent and the rate are going to change during
clk_set_rate() it will call the .set_rate_and_parent() op if
available and fall back to calling .set_parent() followed by
.set_rate() otherwise.

Reviewed-by: James Hogan james.ho...@imgtec.com
Signed-off-by: Stephen Boyd sb...@codeaurora.org
---
 Documentation/clk.txt|  3 ++
 drivers/clk/clk.c| 78 +---
 include/linux/clk-provider.h | 15 +
 3 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/Documentation/clk.txt b/Documentation/clk.txt
index 3aeb5c4..79700ea 100644
--- a/Documentation/clk.txt
+++ b/Documentation/clk.txt
@@ -77,6 +77,9 @@ the operations defined in clk.h:
int (*set_parent)(struct clk_hw *hw, u8 index);
u8  (*get_parent)(struct clk_hw *hw);
int (*set_rate)(struct clk_hw *hw, unsigned long);
+   int (*set_rate_and_parent)(struct clk_hw *hw,
+   unsigned long rate,
+   unsigned long parent_rate, u8 
index);
void(*init)(struct clk_hw *hw);
};
 
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8b40170..e33abeb 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1200,10 +1200,9 @@ static void clk_reparent(struct clk *clk, struct clk 
*new_parent)
clk-parent = new_parent;
 }
 
-static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
+static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
 {
unsigned long flags;
-   int ret = 0;
struct clk *old_parent = clk-parent;
 
/*
@@ -1234,6 +1233,34 @@ static int __clk_set_parent(struct clk *clk, struct clk 
*parent, u8 p_index)
clk_reparent(clk, parent);
clk_enable_unlock(flags);
 
+   return old_parent;
+}
+
+static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
+   struct clk *old_parent)
+{
+   /*
+* Finish the migration of prepare state and undo the changes done
+* for preventing a race with clk_enable().
+*/
+   if (clk-prepare_count) {
+   clk_disable(clk);
+   clk_disable(old_parent);
+   __clk_unprepare(old_parent);
+   }
+
+   /* update debugfs with new clk tree topology */
+   clk_debug_reparent(clk, parent);
+}
+
+static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
+{
+   unsigned long flags;
+   int ret = 0;
+   struct clk *old_parent;
+
+   old_parent = __clk_set_parent_before(clk, parent);
+
/* change clock input source */
if (parent  clk-ops-set_parent)
ret = clk-ops-set_parent(clk-hw, p_index);
@@ -1251,18 +1278,8 @@ static int __clk_set_parent(struct clk *clk, struct clk 
*parent, u8 p_index)
return ret;
}
 
-   /*
-* Finish the migration of prepare state and undo the changes done
-* for preventing a race with clk_enable().
-*/
-   if (clk-prepare_count) {
-   clk_disable(clk);
-   clk_disable(old_parent);
-   __clk_unprepare(old_parent);
-   }
+   __clk_set_parent_after(clk, parent, old_parent);
 
-   /* update debugfs with new clk tree topology */
-   clk_debug_reparent(clk, parent);
return 0;
 }
 
@@ -1447,17 +1464,32 @@ static void clk_change_rate(struct clk *clk)
struct clk *child;
unsigned long old_rate;
unsigned long best_parent_rate = 0;
+   bool skip_set_rate = false;
+   struct clk *old_parent;
 
old_rate = clk-rate;
 
-   /* set parent */
-   if (clk-new_parent  clk-new_parent != clk-parent)
-   __clk_set_parent(clk, clk-new_parent, clk-new_parent_index);
-
-   if (clk-parent)
+   if (clk-new_parent)
+   best_parent_rate = clk-new_parent-rate;
+   else if (clk-parent)
best_parent_rate = clk-parent-rate;
 
-   if (clk-ops-set_rate)
+   if (clk-new_parent  clk-new_parent != clk-parent) {
+   old_parent = __clk_set_parent_before(clk, clk-new_parent);
+
+   if (clk-ops-set_rate_and_parent) {
+   skip_set_rate = true;
+   clk-ops-set_rate_and_parent(clk-hw, clk-new_rate,
+   best_parent_rate,
+   clk-new_parent_index);
+   } else if (clk-ops-set_parent) {
+   clk-ops-set_parent(clk-hw, clk-new_parent_index);
+   }
+
+   

Re: [PATCH v4 1/1] usb: gadget: f_fs: Add support for SuperSpeed Mode

2013-12-23 Thread Michal Nazarewicz
On Mon, Dec 23 2013, Manu Gautam mgau...@codeaurora.org wrote:
 Allow userspace to pass SuperSpeed descriptors and
 handle them in the driver accordingly.
 This change doesn't modify existing desc_header and thereby
 keeps the ABI changes backward compatible i.e. existing
 userspace drivers compiled with old header (functionfs.h)
 would continue to work with the updated kernel.

I'm mostly fine with this patch.  If you change __ffs_func_bind_do_descs
as I've described inline, feel free to resend with:

Acked-by: Michal Nazarewicz min...@mina86.com

The other two minor issues are up to you.  I don't have strong feelings.

 Signed-off-by: Manu Gautam mgau...@codeaurora.org
 ---
  drivers/usb/gadget/f_fs.c | 176 
 +++---
  drivers/usb/gadget/u_fs.h |   8 ++-
  2 files changed, 142 insertions(+), 42 deletions(-)

 diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
 index 306a2b5..8c7bf04 100644
 --- a/drivers/usb/gadget/f_fs.c
 +++ b/drivers/usb/gadget/f_fs.c
 @@ -1607,22 +1630,58 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
   }
  
   if (likely(hs_count)) {
 - ret = ffs_do_descs(hs_count, data, len,
 + hs_len = ffs_do_descs(hs_count, data, len,
  __ffs_data_do_entity, ffs);
 - if (unlikely(ret  0))
 + if (unlikely(hs_len  0)) {
 + ret = hs_len;
 + goto error;
 + }
 +
 + data += hs_len;
 + len  -= hs_len;
 + } else {
 + hs_len = 0;
 + }
 +
 + if (len = 8) {
 + /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */
 + if (get_unaligned_le32(data) != FUNCTIONFS_SS_DESC_MAGIC)
 + goto einval;
 +
 + ss_count = get_unaligned_le32(data + 4);
 + data += 8;
 + len  -= 8;
 + }
 +
 + if (!fs_count  !hs_count  !ss_count)
 + goto einval;
 +
 + if (ss_count) {
 + ss_len = ffs_do_descs(ss_count, data, len,
 +__ffs_data_do_entity, ffs);
 + if (unlikely(ss_len  0)) {
 + ret = ss_len;
   goto error;
 + }
 + ret = ss_len;
   } else {
 + ss_len = 0;
   ret = 0;
   }
  
   if (unlikely(len != ret))
   goto einval;
  
 - ffs-raw_fs_descs_length = fs_len;
 - ffs-raw_descs_length= fs_len + ret;
 - ffs-raw_descs   = _data;
 - ffs-fs_descs_count  = fs_count;
 - ffs-hs_descs_count  = hs_count;
 + ffs-raw_fs_hs_descs_length  = fs_len + hs_len;
 + ffs-raw_ss_descs_length = ss_len;
 + ffs-raw_descs_length= fs_len + hs_len + ss_len;

This can always be calculated as the sum of the other two fields, so
perhaps the redundancy in the structure is not needed, especially as
this is only used in _ffs_func_bind?

 + ffs-raw_descs   = _data;
 + ffs-fs_descs_count  = fs_count;
 + ffs-hs_descs_count  = hs_count;
 + ffs-ss_descs_count  = ss_count;
 + /* ss_descs? present @ header + hs_fs_descs + ss_magic + ss_count */
 + if (ffs-ss_descs_count)
 + ffs-raw_ss_descs_offset = 16 +
 ffs-raw_fs_hs_descs_length + 8;

Similarly here, the offset is easily calculated from the other fields.

I don't have strong feelings, but perhaps it would end up being cleaner
if the values were calculated on demand in _ffs_func_bind?

  
   return 0;
  
 @@ -1850,16 +1909,23 @@ static int __ffs_func_bind_do_descs(enum 
 ffs_entity_type type, u8 *valuep,
* If hs_descriptors is not NULL then we are reading hs
* descriptors now
*/
 - const int isHS = func-function.hs_descriptors != NULL;
 - unsigned idx;
 + const int is_hs = func-function.hs_descriptors != NULL;
 + const int is_ss = func-function.ss_descriptors != NULL;
 + unsigned ep_desc_id, idx;
  
   if (type != FFS_DESCRIPTOR)
   return 0;
  
 - if (isHS)
 + if (is_ss) {
 + func-function.ss_descriptors[(long)valuep] = desc;
 + ep_desc_id = 2;
 + } else if (is_hs) {
   func-function.hs_descriptors[(long)valuep] = desc;
 - else
 + ep_desc_id = 1;
 + } else {
   func-function.fs_descriptors[(long)valuep]= desc;
 + ep_desc_id = 0;
 + }

I should have caught it in my previous review.  Since is_hs and is_ss
are mutually exclusive, it would be better to use ep_desc_id as a single
3-state variable than having two 2-state variables, which may cause some
confusion as to what they actually mean.  So how about:

unsigned ed_desc_id, idx;

if (type != FFS_DESCRIPTOR)
return 0;

/*
 * If ss_descriptors is not NULL, we are reading super