Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Olof Johansson: "New and/or improved SoC support for this release: Marvell Berlin: - Enable standard DT-based cpufreq - Add CPU hotplug support Freescale: - Ethernet init for i.MX7D - Suspend/resume support for i.MX6UL Allwinner: - Support for R8 chipset (used on NTC's $9 C.H.I.P board) Mediatek: - SMP support for some platforms Uniphier: - L2 support - Cleaned up SMP support, etc. plus a handful of other patches around above functionality, and a few other smaller changes" * tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (42 commits) ARM: uniphier: rework SMP operations to use trampoline code ARM: uniphier: add outer cache support Documentation: EXYNOS: Update bootloader interface on exynos542x ARM: mvebu: add broken-idle option ARM: orion5x: use mac_pton() helper ARM: at91: pm: at91_pm_suspend_in_sram() must be 8-byte aligned ARM: sunxi: Add R8 support ARM: digicolor: select pinctrl/gpio driver arm: berlin: add CPU hotplug support arm: berlin: use non-self-cleared reset register to reset cpu ARM: mediatek: add smp bringup code ARM: mediatek: enable gpt6 on boot up to make arch timer working soc: mediatek: Fix random hang up issue while kernel init soc: ti: qmss: make acc queue support optional in the driver soc: ti: add firmware file name as part of the driver Documentation: dt: soc: Add description for knav qmss driver ARM: S3C64XX: Use PWM lookup table for mach-smartq ARM: S3C64XX: Use PWM lookup table for mach-hmt ARM: S3C64XX: Use PWM lookup table for mach-crag6410 ARM: S3C64XX: Use PWM lookup table for smdk6410 ...
This commit is contained in:
@@ -135,9 +135,10 @@ struct knav_pdsp_info {
|
||||
};
|
||||
void __iomem *intd;
|
||||
u32 __iomem *iram;
|
||||
const char *firmware;
|
||||
u32 id;
|
||||
struct list_head list;
|
||||
bool loaded;
|
||||
bool started;
|
||||
};
|
||||
|
||||
struct knav_qmgr_info {
|
||||
|
@@ -486,8 +486,8 @@ struct knav_range_ops knav_acc_range_ops = {
|
||||
* Return 0 on success or error
|
||||
*/
|
||||
int knav_init_acc_range(struct knav_device *kdev,
|
||||
struct device_node *node,
|
||||
struct knav_range_info *range)
|
||||
struct device_node *node,
|
||||
struct knav_range_info *range)
|
||||
{
|
||||
struct knav_acc_channel *acc;
|
||||
struct knav_pdsp_info *pdsp;
|
||||
@@ -530,6 +530,12 @@ int knav_init_acc_range(struct knav_device *kdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pdsp->started) {
|
||||
dev_err(kdev->dev, "pdsp id %d not started for range %s\n",
|
||||
info->pdsp_id, range->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->pdsp = pdsp;
|
||||
channels = range->num_queues;
|
||||
if (of_get_property(node, "multi-queue", NULL)) {
|
||||
|
@@ -68,6 +68,12 @@ static DEFINE_MUTEX(knav_dev_lock);
|
||||
idx < (kdev)->num_queues_in_use; \
|
||||
idx++, inst = knav_queue_idx_to_inst(kdev, idx))
|
||||
|
||||
/* All firmware file names end up here. List the firmware file names below.
|
||||
* Newest followed by older ones. Search is done from start of the array
|
||||
* until a firmware file is found.
|
||||
*/
|
||||
const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
|
||||
|
||||
/**
|
||||
* knav_queue_notify: qmss queue notfier call
|
||||
*
|
||||
@@ -1439,7 +1445,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
||||
struct device *dev = kdev->dev;
|
||||
struct knav_pdsp_info *pdsp;
|
||||
struct device_node *child;
|
||||
int ret;
|
||||
|
||||
for_each_child_of_node(pdsps, child) {
|
||||
pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
|
||||
@@ -1448,17 +1453,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
||||
return -ENOMEM;
|
||||
}
|
||||
pdsp->name = knav_queue_find_name(child);
|
||||
ret = of_property_read_string(child, "firmware",
|
||||
&pdsp->firmware);
|
||||
if (ret < 0 || !pdsp->firmware) {
|
||||
dev_err(dev, "unknown firmware for pdsp %s\n",
|
||||
pdsp->name);
|
||||
devm_kfree(dev, pdsp);
|
||||
continue;
|
||||
}
|
||||
dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
|
||||
pdsp->firmware);
|
||||
|
||||
pdsp->iram =
|
||||
knav_queue_map_reg(kdev, child,
|
||||
KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
|
||||
@@ -1489,9 +1483,9 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
||||
}
|
||||
of_property_read_u32(child, "id", &pdsp->id);
|
||||
list_add_tail(&pdsp->list, &kdev->pdsps);
|
||||
dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n",
|
||||
dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n",
|
||||
pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
|
||||
pdsp->intd, pdsp->firmware);
|
||||
pdsp->intd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1510,6 +1504,8 @@ static int knav_queue_stop_pdsp(struct knav_device *kdev,
|
||||
dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
|
||||
return ret;
|
||||
}
|
||||
pdsp->loaded = false;
|
||||
pdsp->started = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1518,14 +1514,29 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
|
||||
{
|
||||
int i, ret, fwlen;
|
||||
const struct firmware *fw;
|
||||
bool found = false;
|
||||
u32 *fwdata;
|
||||
|
||||
ret = request_firmware(&fw, pdsp->firmware, kdev->dev);
|
||||
if (ret) {
|
||||
dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n",
|
||||
pdsp->firmware, pdsp->name);
|
||||
return ret;
|
||||
for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
|
||||
if (knav_acc_firmwares[i]) {
|
||||
ret = request_firmware(&fw,
|
||||
knav_acc_firmwares[i],
|
||||
kdev->dev);
|
||||
if (!ret) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
dev_err(kdev->dev, "failed to get firmware for pdsp\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
|
||||
knav_acc_firmwares[i]);
|
||||
|
||||
writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
|
||||
/* download the firmware */
|
||||
fwdata = (u32 *)fw->data;
|
||||
@@ -1583,16 +1594,24 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
|
||||
int ret;
|
||||
|
||||
knav_queue_stop_pdsps(kdev);
|
||||
/* now load them all */
|
||||
/* now load them all. We return success even if pdsp
|
||||
* is not loaded as acc channels are optional on having
|
||||
* firmware availability in the system. We set the loaded
|
||||
* and stated flag and when initialize the acc range, check
|
||||
* it and init the range only if pdsp is started.
|
||||
*/
|
||||
for_each_pdsp(kdev, pdsp) {
|
||||
ret = knav_queue_load_pdsp(kdev, pdsp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!ret)
|
||||
pdsp->loaded = true;
|
||||
}
|
||||
|
||||
for_each_pdsp(kdev, pdsp) {
|
||||
ret = knav_queue_start_pdsp(kdev, pdsp);
|
||||
WARN_ON(ret);
|
||||
if (pdsp->loaded) {
|
||||
ret = knav_queue_start_pdsp(kdev, pdsp);
|
||||
if (!ret)
|
||||
pdsp->started = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user