diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c | 8 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 7 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/omap_temp_sensor.c | 709 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/include/linuxver.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_android.h | 22 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfg80211.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_iw.c | 72 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc.c | 18 | ||||
-rw-r--r-- | drivers/rpmsg/rpmsg_omx.c | 12 | ||||
-rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 11 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/base.c | 40 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/device.c | 45 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/dsscomp.h | 5 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/gralloc.c | 8 |
16 files changed, 866 insertions, 99 deletions
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c index 2e803e1..79a00e5 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c +++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c @@ -812,13 +812,16 @@ static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, OMAPLFB_DEVINFO *psDevInfo, IMG_VOID **ppvMemInfos, IMG_UINT32 ui32NumMemInfos, - struct dsscomp_setup_mgr_data *psDssData) + struct dsscomp_setup_dispc_data *psDssData, + IMG_UINT32 uiDssDataLength) { PVRSRV_KERNEL_MEM_INFO **ppsMemInfos = (PVRSRV_KERNEL_MEM_INFO **)ppvMemInfos; struct tiler_pa_info *apsTilerPAs[5]; IMG_UINT32 i, k; + BUG_ON(uiDssDataLength != sizeof(*psDssData)); + for(i = k = 0; i < ui32NumMemInfos && i < ARRAY_SIZE(apsTilerPAs); i++, k++) { struct tiler_pa_info *psTilerInfo; @@ -931,7 +934,8 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, psDevInfo, psFlipCmd2->ppvMemInfos, psFlipCmd2->ui32NumMemInfos, - psFlipCmd2->pvPrivData); + psFlipCmd2->pvPrivData, + psFlipCmd2->ui32PrivDataLength); #else BUG(); #endif diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 050f26a..d2a7df5 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -564,6 +564,13 @@ config USB_SWITCH_FSA9480 stereo and mono audio, video, microphone and UART data to use a common connector port. +config OMAP_DIE_TEMP_SENSOR + bool "OMAP On-Die temp sensor support" + depends on OMAP_TEMP_SENSOR + help + Enabling this config will give support for the on-die + temp sensor for the OMAP platform. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index dfe1881..bf750e4 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -57,3 +57,4 @@ obj-$(CONFIG_SENSORS_AK8975) += akm8975.o obj-y += inv_mpu/ obj-$(CONFIG_SEC_MODEM) += modem_if/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o +obj-$(CONFIG_OMAP_DIE_TEMP_SENSOR) += omap_temp_sensor.o diff --git a/drivers/misc/omap_temp_sensor.c b/drivers/misc/omap_temp_sensor.c new file mode 100644 index 0000000..f7a2ef2 --- /dev/null +++ b/drivers/misc/omap_temp_sensor.c @@ -0,0 +1,709 @@ +/* + * OMAP4 Temperature sensor driver file + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * Author: J Keerthy <j-keerthy@ti.com> + * Author: Moiz Sonasath <m-sonasath@ti.com> + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reboot.h> +#include <linux/slab.h> +#include <linux/sysfs.h> +#include <linux/types.h> + +#include <plat/common.h> +#include <plat/omap_device.h> +#include <plat/temperature_sensor.h> + +/* TO DO: This needs to be fixed */ +#include "../../../../arch/arm/mach-omap2/control.h" +/* #include <plat/control.h> */ + +#include <mach/ctrl_module_core_44xx.h> + +extern void omap_thermal_throttle(void); +extern void omap_thermal_unthrottle(void); + +#define TSHUT_THRESHOLD_TSHUT_HOT 122000 /* 122 deg C */ +#define TSHUT_THRESHOLD_TSHUT_COLD 100000 /* 100 deg C */ +#define BGAP_THRESHOLD_T_HOT 110000 /* 110 deg C */ +#define BGAP_THRESHOLD_T_COLD 100000 /* 100 deg C */ +#define OMAP_ADC_START_VALUE 530 +#define OMAP_ADC_END_VALUE 923 + +/* + * omap_temp_sensor structure + * @pdev - Platform device pointer + * @dev - device pointer + * @clock - Clock pointer + * @sensor_mutex - Mutex for sysfs, irq and PM + * @irq - MPU Irq number for thermal alertemp_sensor + * @tshut_irq - Thermal shutdown IRQ + * @phy_base - Physical base of the temp I/O + * @is_efuse_valid - Flag to determine if eFuse is valid or not + * @clk_on - Manages the current clock state + * @clk_rate - Holds current clock rate + */ +struct omap_temp_sensor { + struct platform_device *pdev; + struct device *dev; + struct clk *clock; + struct spinlock lock; + unsigned int irq; + unsigned int tshut_irq; + unsigned long phy_base; + int is_efuse_valid; + u8 clk_on; + unsigned long clk_rate; + u32 current_temp; +}; + +#ifdef CONFIG_PM +struct omap_temp_sensor_regs { + u32 temp_sensor_ctrl; + u32 bg_ctrl; + u32 bg_counter; + u32 bg_threshold; + u32 temp_sensor_tshut_threshold; +}; + +static struct omap_temp_sensor_regs temp_sensor_context; +static struct omap_temp_sensor *temp_sensor_pm; +#endif + +/* + * Temperature values in milli degrees celsius ADC code values from 530 to 923 + */ +static int adc_to_temp[] = { + -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200, + -37800, -37300, -36800, -36400, -36000, -35600, -35200, -34800, + -34300, -33800, -33400, -33000, -32600, -32200, -31800, -31300, + -30800, -30400, -30000, -29600, -29200, -28700, -28200, -27800, + -27400, -27000, -26600, -26200, -25700, -25200, -24800, -24400, + -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000, + -20600, -20200, -19700, -19200, -18800, -18400, -18000, -17600, + -17200, -16700, -16200, -15800, -15400, -15000, -14600, -14200, + -13700, -13200, -12800, -12400, -12000, -11600, -11200, -10700, + -10200, -9800, -9400, -9000, -8600, -8200, -7700, -7200, -6800, + -6400, -6000, -5600, -5200, -4800, -4300, -3800, -3400, -3000, + -2600, -2200, -1800, -1300, -800, -400, 0, 400, 800, 1200, 1600, + 2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, 6400, + 6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10600, 11000, + 11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800, + 15300, 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18700, + 19200, 19600, 20000, 20400, 20800, 21200, 21600, 22100, 22600, + 23000, 23400, 23800, 24200, 24600, 25000, 25400, 25900, 26400, + 26800, 27200, 27600, 28000, 28400, 28800, 29300, 29800, 30200, + 30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000, + 34400, 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800, + 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41100, 41600, + 42000, 42400, 42800, 43200, 43600, 44000, 44400, 44800, 45300, + 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600, 49000, + 49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, 52800, + 53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600, + 57000, 57400, 57800, 58200, 58700, 59200, 59600, 60000, 60400, + 60800, 61200, 61600, 62000, 62400, 62800, 63300, 63800, 64200, + 64600, 65000, 65400, 65800, 66200, 66600, 67000, 67400, 67800, + 68200, 68700, 69200, 69600, 70000, 70400, 70800, 71200, 71600, + 72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400, + 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, + 79400, 79800, 80300, 80800, 81200, 81600, 82000, 82400, 82800, + 83200, 83600, 84000, 84400, 84800, 85200, 85600, 86000, 86400, + 86800, 87300, 87800, 88200, 88600, 89000, 89400, 89800, 90200, + 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, 93800, + 94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600, + 98000, 98400, 98800, 99200, 99600, 100000, 100400, 100800, 101200, + 101600, 102000, 102400, 102800, 103200, 103600, 104000, 104400, + 104800, 105200, 105600, 106100, 106600, 107000, 107400, 107800, + 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000, + 111400, 111800, 112200, 112600, 113000, 113400, 113800, 114200, + 114600, 115000, 115400, 115800, 116200, 116600, 117000, 117400, + 117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600, + 121000, 121400, 121800, 122200, 122600, 123000 +}; + +static unsigned long omap_temp_sensor_readl(struct omap_temp_sensor + *temp_sensor, u32 reg) +{ + return omap_ctrl_readl(temp_sensor->phy_base + reg); +} + +static void omap_temp_sensor_writel(struct omap_temp_sensor *temp_sensor, + u32 val, u32 reg) +{ + omap_ctrl_writel(val, (temp_sensor->phy_base + reg)); +} + +static int adc_to_temp_conversion(int adc_val) +{ + if (adc_val < OMAP_ADC_START_VALUE || adc_val > OMAP_ADC_END_VALUE) { + pr_err("%s:Temp read is invalid %i\n", __func__, adc_val); + return -EINVAL; + } + + return adc_to_temp[adc_val - OMAP_ADC_START_VALUE]; +} + +static int temp_to_adc_conversion(long temp) +{ + int i; + + for (i = 0; i <= OMAP_ADC_END_VALUE - OMAP_ADC_START_VALUE; i++) + if (temp < adc_to_temp[i]) + return OMAP_ADC_START_VALUE + i - 1; + return -EINVAL; +} + +static int omap_read_current_temp(struct omap_temp_sensor *temp_sensor) +{ + int adc; + + adc = omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET); + adc &= (OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK); + + if (!temp_sensor->is_efuse_valid) + pr_err_once("Invalid EFUSE, Non-trimmed BGAP, \ + Temp not accurate\n"); + + if (adc < OMAP_ADC_START_VALUE || adc > OMAP_ADC_END_VALUE) { + pr_err("%s:Invalid adc code reported by the sensor %d", + __func__, adc); + return -EINVAL; + } + + return adc_to_temp_conversion(adc); +} + +static void omap_configure_temp_sensor_thresholds(struct omap_temp_sensor + *temp_sensor) +{ + u32 temp = 0, t_hot, t_cold, tshut_hot, tshut_cold; + + t_hot = temp_to_adc_conversion(BGAP_THRESHOLD_T_HOT); + t_cold = temp_to_adc_conversion(BGAP_THRESHOLD_T_COLD); + + if ((t_hot == -EINVAL) || (t_cold == -EINVAL)) { + pr_err("%s:Temp thresholds out of bounds\n", __func__); + return; + } + temp |= ((t_hot << OMAP4_T_HOT_SHIFT) | (t_cold << OMAP4_T_COLD_SHIFT)); + omap_temp_sensor_writel(temp_sensor, temp, BGAP_THRESHOLD_OFFSET); + + tshut_hot = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_HOT); + tshut_cold = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_COLD); + if ((tshut_hot == -EINVAL) || (tshut_cold == -EINVAL)) { + pr_err("%s:Temp shutdown thresholds out of bounds\n", __func__); + return; + } + temp |= ((tshut_hot << OMAP4_TSHUT_HOT_SHIFT) + | (tshut_cold << OMAP4_TSHUT_COLD_SHIFT)); + omap_temp_sensor_writel(temp_sensor, temp, BGAP_TSHUT_OFFSET); +} + +static void omap_configure_temp_sensor_counter(struct omap_temp_sensor + *temp_sensor, u32 counter) +{ + u32 val; + + val = omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET); + val = val & ~(OMAP4_COUNTER_MASK); + val = val | (counter << OMAP4_COUNTER_SHIFT); + omap_temp_sensor_writel(temp_sensor, val, BGAP_COUNTER_OFFSET); +} + +static void omap_enable_continuous_mode(struct omap_temp_sensor *temp_sensor) +{ + u32 val; + + val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); + + val = val | (1 << OMAP4_SINGLE_MODE_SHIFT); + + omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET); +} + +/* + * sysfs hook functions + */ +static ssize_t omap_temp_show_current(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); + + return sprintf(buf, "%d\n", omap_read_current_temp(temp_sensor)); +} + +static ssize_t omap_throttle_store(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + if (count && buf[0] == '1') + omap_thermal_throttle(); + else + omap_thermal_unthrottle(); + + return count; +} + +static DEVICE_ATTR(temperature, S_IRUGO, omap_temp_show_current, NULL); +static DEVICE_ATTR(throttle, S_IWUSR, NULL, omap_throttle_store); +static struct attribute *omap_temp_sensor_attributes[] = { + &dev_attr_temperature.attr, + &dev_attr_throttle.attr, + NULL +}; + +static const struct attribute_group omap_temp_sensor_group = { + .attrs = omap_temp_sensor_attributes, +}; + +static int omap_temp_sensor_enable(struct omap_temp_sensor *temp_sensor) +{ + u32 temp; + u32 ret = 0; + unsigned long clk_rate; + + unsigned long flags; + + spin_lock_irqsave(&temp_sensor->lock, flags); + + if (temp_sensor->clk_on) { + pr_err("clock already on\n"); + goto out; + } + + ret = pm_runtime_get_sync(&temp_sensor->pdev->dev); + if (ret) { + pr_err("%s:get sync failed\n", __func__); + ret = -EINVAL; + goto out; + } + + clk_set_rate(temp_sensor->clock, 1000000); + clk_rate = clk_get_rate(temp_sensor->clock); + temp_sensor->clk_rate = clk_rate; + + temp = omap_temp_sensor_readl(temp_sensor, + TEMP_SENSOR_CTRL_OFFSET); + temp &= ~(OMAP4_BGAP_TEMPSOFF_MASK); + + /* write BGAP_TEMPSOFF should be reset to 0 */ + omap_temp_sensor_writel(temp_sensor, temp, + TEMP_SENSOR_CTRL_OFFSET); + temp_sensor->clk_on = 1; + +out: +spin_unlock_irqrestore(&temp_sensor->lock, flags); + return ret; +} + + +static int omap_temp_sensor_disable(struct omap_temp_sensor *temp_sensor) +{ + u32 temp; + u32 ret = 0; + u32 counter = 1000; + unsigned long flags; + + spin_lock_irqsave(&temp_sensor->lock, flags); + + if (!temp_sensor->clk_on) { + pr_err("clock already off\n"); + goto out; + } + temp = omap_temp_sensor_readl(temp_sensor, + TEMP_SENSOR_CTRL_OFFSET); + temp |= OMAP4_BGAP_TEMPSOFF_MASK; + + /* write BGAP_TEMPSOFF should be set to 1 before gating clock */ + omap_temp_sensor_writel(temp_sensor, temp, + TEMP_SENSOR_CTRL_OFFSET); + temp = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET); + + /* wait till the clean stop bit is set */ + while ((temp & OMAP4_CLEAN_STOP_MASK) && --counter) + temp = omap_temp_sensor_readl(temp_sensor, + BGAP_STATUS_OFFSET); + /* Gate the clock */ + ret = pm_runtime_put_sync_suspend(&temp_sensor->pdev->dev); + if (ret) { + pr_err("%s:put sync failed\n", __func__); + ret = -EINVAL; + goto out; + } + temp_sensor->clk_on = 0; + +out: + spin_unlock_irqrestore(&temp_sensor->lock, flags); + return ret; +} + +static irqreturn_t omap_tshut_irq_handler(int irq, void *data) +{ + struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data; + + /* Need to handle thermal mgmt in bootloader + * to avoid restart again at kernel level + */ + if (temp_sensor->is_efuse_valid) { + pr_emerg("%s: Thermal shutdown reached rebooting device\n", + __func__); + kernel_restart(NULL); + } else { + pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__); + } + + return IRQ_HANDLED; +} + +static irqreturn_t omap_talert_irq_handler(int irq, void *data) +{ + struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data; + int t_hot, t_cold, temp_offset; + + t_hot = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET) + & OMAP4_HOT_FLAG_MASK; + t_cold = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET) + & OMAP4_COLD_FLAG_MASK; + temp_offset = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); + if (t_hot) { + omap_thermal_throttle(); + temp_offset &= ~(OMAP4_MASK_HOT_MASK); + temp_offset |= OMAP4_MASK_COLD_MASK; + } else if (t_cold) { + omap_thermal_unthrottle(); + temp_offset &= ~(OMAP4_MASK_COLD_MASK); + temp_offset |= OMAP4_MASK_HOT_MASK; + } + + omap_temp_sensor_writel(temp_sensor, temp_offset, BGAP_CTRL_OFFSET); + + return IRQ_HANDLED; +} + +static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; + struct omap_temp_sensor *temp_sensor; + struct resource *mem; + int ret = 0, val; + + if (!pdata) { + dev_err(dev, "%s: platform data missing\n", __func__); + return -EINVAL; + } + + temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); + if (!temp_sensor) + return -ENOMEM; + + spin_lock_init(&temp_sensor->lock); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(dev, "%s:no mem resource\n", __func__); + ret = -EINVAL; + goto plat_res_err; + } + + temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert"); + if (temp_sensor->irq < 0) { + dev_err(dev, "%s:Cannot get thermal alert irq\n", + __func__); + ret = -EINVAL; + goto get_irq_err; + } + + ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN, + "thermal_shutdown"); + if (ret) { + dev_err(dev, "%s: Could not get tshut_gpio\n", + __func__); + goto tshut_gpio_req_err; + } + + temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO); + if (temp_sensor->tshut_irq < 0) { + dev_err(dev, "%s:Cannot get thermal shutdown irq\n", + __func__); + ret = -EINVAL; + goto get_tshut_irq_err; + } + + temp_sensor->phy_base = pdata->offset; + temp_sensor->pdev = pdev; + temp_sensor->dev = dev; + + pm_runtime_enable(dev); + pm_runtime_irq_safe(dev); + + /* + * check if the efuse has a non-zero value if not + * it is an untrimmed sample and the temperatures + * may not be accurate */ + if (omap_readl(OMAP4_CTRL_MODULE_CORE + + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) + temp_sensor->is_efuse_valid = 1; + + temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); + if (IS_ERR(temp_sensor->clock)) { + ret = PTR_ERR(temp_sensor->clock); + pr_err("%s:Unable to get fclk: %d\n", __func__, ret); + ret = -EINVAL; + goto clk_get_err; + } + + ret = omap_temp_sensor_enable(temp_sensor); + if (ret) { + dev_err(dev, "%s:Cannot enable temp sensor\n", __func__); + goto sensor_enable_err; + } + + platform_set_drvdata(pdev, temp_sensor); + + omap_enable_continuous_mode(temp_sensor); + omap_configure_temp_sensor_thresholds(temp_sensor); + /* 1 ms */ + omap_configure_temp_sensor_counter(temp_sensor, 1); + + /* Wait till the first conversion is done wait for at least 1ms */ + mdelay(2); + + /* Read the temperature once due to hw issue*/ + omap_read_current_temp(temp_sensor); + + /* Set 2 seconds time as default counter */ + omap_configure_temp_sensor_counter(temp_sensor, + temp_sensor->clk_rate * 2); + ret = request_threaded_irq(temp_sensor->irq, NULL, + omap_talert_irq_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "temp_sensor", (void *)temp_sensor); + if (ret) { + dev_err(dev, "Request threaded irq failed.\n"); + goto req_irq_err; + } + + ret = request_threaded_irq(temp_sensor->tshut_irq, NULL, + omap_tshut_irq_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "tshut", (void *)temp_sensor); + if (ret) { + dev_err(dev, "Request threaded irq failed for TSHUT.\n"); + goto tshut_irq_req_err; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); + if (ret) { + dev_err(&pdev->dev, "could not create sysfs files\n"); + goto sysfs_create_err; + } + + /* unmask the T_COLD and unmask T_HOT at init */ + val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); + val |= OMAP4_MASK_COLD_MASK; + val |= OMAP4_MASK_HOT_MASK; + omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET); + + dev_info(dev, "%s probed", pdata->name); + + temp_sensor_pm = temp_sensor; + return 0; + +sysfs_create_err: + free_irq(temp_sensor->tshut_irq, temp_sensor); +tshut_irq_req_err: + free_irq(temp_sensor->irq, temp_sensor); +req_irq_err: + platform_set_drvdata(pdev, NULL); + omap_temp_sensor_disable(temp_sensor); +sensor_enable_err: + clk_put(temp_sensor->clock); +clk_get_err: + pm_runtime_disable(dev); +get_tshut_irq_err: + gpio_free(OMAP_TSHUT_GPIO); +tshut_gpio_req_err: +get_irq_err: +plat_res_err: + kfree(temp_sensor); + return ret; +} + +static int __devexit omap_temp_sensor_remove(struct platform_device *pdev) +{ + struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); + + sysfs_remove_group(&pdev->dev.kobj, &omap_temp_sensor_group); + omap_temp_sensor_disable(temp_sensor); + clk_put(temp_sensor->clock); + platform_set_drvdata(pdev, NULL); + if (temp_sensor->irq) + free_irq(temp_sensor->irq, temp_sensor); + if (temp_sensor->tshut_irq) + free_irq(temp_sensor->tshut_irq, temp_sensor); + kfree(temp_sensor); + + return 0; +} + +#ifdef CONFIG_PM +static void omap_temp_sensor_save_ctxt(struct omap_temp_sensor *temp_sensor) +{ + temp_sensor_context.temp_sensor_ctrl = + omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET); + temp_sensor_context.bg_ctrl = + omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); + temp_sensor_context.bg_counter = + omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET); + temp_sensor_context.bg_threshold = + omap_temp_sensor_readl(temp_sensor, BGAP_THRESHOLD_OFFSET); + temp_sensor_context.temp_sensor_tshut_threshold = + omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET); +} + +static void omap_temp_sensor_restore_ctxt(struct omap_temp_sensor *temp_sensor) +{ + omap_temp_sensor_writel(temp_sensor, + temp_sensor_context.temp_sensor_ctrl, + TEMP_SENSOR_CTRL_OFFSET); + omap_temp_sensor_writel(temp_sensor, + temp_sensor_context.bg_ctrl, + BGAP_CTRL_OFFSET); + omap_temp_sensor_writel(temp_sensor, + temp_sensor_context.bg_counter, + BGAP_COUNTER_OFFSET); + omap_temp_sensor_writel(temp_sensor, + temp_sensor_context.bg_threshold, + BGAP_THRESHOLD_OFFSET); + omap_temp_sensor_writel(temp_sensor, + temp_sensor_context.temp_sensor_tshut_threshold, + BGAP_TSHUT_OFFSET); +} + +static int omap_temp_sensor_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); + + omap_temp_sensor_disable(temp_sensor); + + return 0; +} + +static int omap_temp_sensor_resume(struct platform_device *pdev) +{ + struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); + + omap_temp_sensor_enable(temp_sensor); + + return 0; +} + +void omap_temp_sensor_idle(int idle_state) +{ + if (idle_state) + omap_temp_sensor_disable(temp_sensor_pm); + else + omap_temp_sensor_enable(temp_sensor_pm); +} + +#else +omap_temp_sensor_suspend NULL +omap_temp_sensor_resume NULL + +#endif /* CONFIG_PM */ + +static int omap_temp_sensor_runtime_suspend(struct device *dev) +{ + struct omap_temp_sensor *temp_sensor = + platform_get_drvdata(to_platform_device(dev)); + + omap_temp_sensor_save_ctxt(temp_sensor); + + return 0; +} + +static int omap_temp_sensor_runtime_resume(struct device *dev) +{ + static int context_loss_count; + int temp; + struct omap_temp_sensor *temp_sensor = + platform_get_drvdata(to_platform_device(dev)); + + temp = omap_device_get_context_loss_count(to_platform_device(dev)); + + if (temp != context_loss_count && context_loss_count != 0) + omap_temp_sensor_restore_ctxt(temp_sensor); + + context_loss_count = temp; + + return 0; +} + +static const struct dev_pm_ops omap_temp_sensor_dev_pm_ops = { + .runtime_suspend = omap_temp_sensor_runtime_suspend, + .runtime_resume = omap_temp_sensor_runtime_resume, +}; + +static struct platform_driver omap_temp_sensor_driver = { + .probe = omap_temp_sensor_probe, + .remove = omap_temp_sensor_remove, + .suspend = omap_temp_sensor_suspend, + .resume = omap_temp_sensor_resume, + .driver = { + .name = "omap_temp_sensor", + .pm = &omap_temp_sensor_dev_pm_ops, + }, +}; + +int __init omap_temp_sensor_init(void) +{ + if (!cpu_is_omap446x()) + return 0; + + return platform_driver_register(&omap_temp_sensor_driver); +} + +static void __exit omap_temp_sensor_exit(void) +{ + platform_driver_unregister(&omap_temp_sensor_driver); +} + +module_init(omap_temp_sensor_init); +module_exit(omap_temp_sensor_exit); + +MODULE_DESCRIPTION("OMAP446X Temperature Sensor Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRIVER_NAME); +MODULE_AUTHOR("Texas Instruments Inc"); diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile index 9984363..56500b7 100644 --- a/drivers/net/wireless/bcmdhd/Makefile +++ b/drivers/net/wireless/bcmdhd/Makefile @@ -26,4 +26,6 @@ bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o dhd_linux_mon.o DHDCFLAGS += -DWL_CFG80211 endif EXTRA_CFLAGS = $(DHDCFLAGS) +ifeq ($(CONFIG_BCMDHD),m) EXTRA_LDFLAGS += --strip-debug +endif diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h index b64d0bb..e1c62b7 100644 --- a/drivers/net/wireless/bcmdhd/include/linuxver.h +++ b/drivers/net/wireless/bcmdhd/include/linuxver.h @@ -70,6 +70,7 @@ #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/netdevice.h> +#include <linux/semaphore.h> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) #undef IP_TOS #endif @@ -123,11 +124,9 @@ typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) -#ifndef SANDGATE2G #define MOD_INC_USE_COUNT #define MOD_DEC_USE_COUNT #endif -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) #include <linux/sched.h> diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h index 289a326..17373b7 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.h +++ b/drivers/net/wireless/bcmdhd/wl_android.h @@ -1,9 +1,27 @@ /* * Linux cfg80211 driver - Android related functions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2011, Broadcom Corporation * - * $Id: wl_android.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 linm Exp $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: wl_android.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ */ #include <linux/module.h> diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h index 4dea132..838003b 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h @@ -499,7 +499,7 @@ extern void wl_cfg80211_set_sdio_func(void *func); /* set sdio function info */ extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */ extern s32 wl_cfg80211_up(void); /* dongle up */ extern s32 wl_cfg80211_down(void); /* dongle down */ -extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, +extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, int (*_net_attach)(dhd_pub_t *dhdp, int ifidx)); extern s32 wl_cfg80211_ifdel_ops(struct net_device *net); extern s32 wl_cfg80211_notify_ifdel(struct net_device *net); diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c index 494538c..ae28c6d 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/bcmdhd/wl_iw.c @@ -1261,7 +1261,6 @@ wl_iw_set_dtim_skip( &iovbuf, sizeof(iovbuf))) >= 0) { p += snprintf(p, MAX_WX_STRING, "OK"); - net_os_set_dtim_skip(dev, bcn_li_dtim); WL_TRACE(("%s: set dtim_skip %d OK\n", __FUNCTION__, @@ -1471,8 +1470,8 @@ wl_iw_set_pno_set( } if (wrqu->data.length < (strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, - wrqu->data.length, strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))); + WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, + wrqu->data.length, (int)(strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t)))); goto exit_proc; } @@ -1959,6 +1958,7 @@ static int iwpriv_get_assoc_list(struct net_device *dev, return -EINVAL; } + iw = *(wl_iw_t **)netdev_priv(dev); net_os_wake_lock(dev); @@ -1985,6 +1985,7 @@ static int iwpriv_get_assoc_list(struct net_device *dev, WL_SOFTAP(("%s: got %d stations\n", __FUNCTION__, sta_maclist->count)); + memset(mac_lst, 0, sizeof(mac_lst)); p_mac_str = mac_lst; @@ -3119,7 +3120,6 @@ wl_iw_force_specific_scan(iscan_info_t *iscan) static void wl_iw_send_scan_complete(iscan_info_t *iscan) { -#ifndef SANDGATE2G union iwreq_data wrqu; memset(&wrqu, 0, sizeof(wrqu)); @@ -3131,7 +3131,6 @@ wl_iw_send_scan_complete(iscan_info_t *iscan) g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_READY; #endif WL_TRACE(("Send Event ISCAN complete\n")); -#endif } static int @@ -6094,8 +6093,8 @@ wl_iw_set_cscan( } if (wrqu->data.length < (strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))) { - WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, - wrqu->data.length, strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))); + WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, + wrqu->data.length, (int)(strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t)))); return -1; } @@ -6274,7 +6273,7 @@ thr_wait_for_2nd_eth_dev(void *data) } DHD_OS_WAKE_LOCK(iw->pub); complete(&tsk_ctl->completed); - if (down_timeout(&tsk_ctl->sema, msecs_to_jiffies(1000)) != 0) { + if (down_timeout(&tsk_ctl->sema, msecs_to_jiffies(1000)) != 0) { #else if (down_interruptible(&tsk_ctl->sema) != 0) { #endif @@ -7335,69 +7334,68 @@ wl_iw_set_priv( return -EFAULT; } - if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { + if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { #ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS WL_TRACE(("%s: active scan setting suppressed\n", dev->name)); #else ret = wl_iw_set_active_scan(dev, info, (union iwreq_data *)dwrq, extra); #endif - } - else if (strnicmp(extra, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) + } + else if (strnicmp(extra, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) #ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS WL_TRACE(("%s: passive scan setting suppressed\n", dev->name)); #else ret = wl_iw_set_passive_scan(dev, info, (union iwreq_data *)dwrq, extra); #endif - else if (strnicmp(extra, "RSSI", strlen("RSSI")) == 0) + else if (strnicmp(extra, "RSSI", strlen("RSSI")) == 0) ret = wl_iw_get_rssi(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "LINKSPEED", strlen("LINKSPEED")) == 0) + else if (strnicmp(extra, "LINKSPEED", strlen("LINKSPEED")) == 0) ret = wl_iw_get_link_speed(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "MACADDR", strlen("MACADDR")) == 0) + else if (strnicmp(extra, "MACADDR", strlen("MACADDR")) == 0) ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) + else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) + else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) ret = wl_iw_control_wl_off(dev, info); - else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) + else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) + else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0) + else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0) ret = wl_iw_get_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0) + else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0) ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0) + else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0) ret = wl_iw_set_suspend(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) + else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) ret = wl_iw_set_txpower(dev, info, (union iwreq_data *)dwrq, extra); #if defined(PNO_SUPPORT) - else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) + else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0) + else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0) ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0) + else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0) ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra); #endif #if defined(CSCAN) - else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0) + else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0) ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra); #endif - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) + else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) + else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) + else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra); #ifdef SOFTAP - else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { - - wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); - } + else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { + wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); + } else if (strnicmp(extra, "AP_MAC_LIST_SET", strlen("AP_MAC_LIST_SET")) == 0) { WL_SOFTAP(("penguin, set AP_MAC_LIST_SET\n")); set_ap_mac_list(dev, (extra + PROFILE_OFFSET)); - } + } #endif else { WL_ERROR(("Unknown PRIVATE command %s - ignored\n", extra)); @@ -8130,9 +8128,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, ETHER_ADDR_LEN); -#ifndef SANDGATE2G wireless_send_event(dev, cmd, &wrqu, extra); -#endif pmkidcand++; count--; } @@ -8182,14 +8178,12 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) WL_TRACE(("Unknown Event %d: ignoring\n", event_type)); break; } -#ifndef SANDGATE2G if (cmd) { if (cmd == SIOCGIWSCAN) wireless_send_event(dev, cmd, &wrqu, NULL); else wireless_send_event(dev, cmd, &wrqu, extra); } -#endif #if WIRELESS_EXT > 14 @@ -8197,9 +8191,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { cmd = IWEVCUSTOM; wrqu.data.length = strlen(extra); -#ifndef SANDGATE2G wireless_send_event(dev, cmd, &wrqu, extra); -#endif } #endif diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c index a697ccf..7502fa0 100644 --- a/drivers/remoteproc/remoteproc.c +++ b/drivers/remoteproc/remoteproc.c @@ -250,6 +250,19 @@ unlock_mutext: mutex_unlock(&rproc->lock); } +static void rproc_reset_poolmem(struct rproc *rproc) +{ + struct rproc_mem_pool *pool = rproc->memory_pool; + + if (!pool || !pool->mem_base || !pool->mem_size) { + pr_warn("invalid pool\n"); + return; + } + + pool->cur_base = pool->mem_base; + pool->cur_size = pool->mem_size; +} + static int rproc_add_mem_entry(struct rproc *rproc, struct fw_resource *rsc) { struct rproc_mem_entry *me = rproc->memory_maps; @@ -279,7 +292,7 @@ static int rproc_alloc_poolmem(struct rproc *rproc, u32 size, phys_addr_t *pa) struct rproc_mem_pool *pool = rproc->memory_pool; *pa = 0; - if (!pool || !pool->mem_base) { + if (!pool || !pool->mem_base || !pool->mem_size) { pr_warn("invalid pool\n"); return -EINVAL; } @@ -680,6 +693,9 @@ void rproc_put(struct rproc *rproc) rproc->trace_buf0 = rproc->trace_buf1 = NULL; + rproc_reset_poolmem(rproc); + memset(rproc->memory_maps, 0, sizeof(rproc->memory_maps)); + /* * make sure rproc is really running before powering it off. * this is important, because the fw loading might have failed. diff --git a/drivers/rpmsg/rpmsg_omx.c b/drivers/rpmsg/rpmsg_omx.c index 01fc65a..9684b11 100644 --- a/drivers/rpmsg/rpmsg_omx.c +++ b/drivers/rpmsg/rpmsg_omx.c @@ -80,18 +80,6 @@ struct rpmsg_omx_instance { #endif }; -/* the packet structure (actual message sent to omx service) */ -struct omx_packet { - uint16_t desc; /* descriptor, and omx service status */ - uint16_t msg_id; /* message id */ - uint32_t flags; /* Set to a fixed value for now. */ - uint32_t fxn_idx; /* Index into OMX service's function table.*/ - int32_t result; /* The OMX function status. */ - uint32_t data_size;/* Size of in/out data to/from the function. */ - uint32_t data[0]; /* Payload of data_size char's passed to - function. */ -}; - static struct class *rpmsg_omx_class; static dev_t rpmsg_omx_dev; diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 5ae755a..619070a 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -418,13 +418,20 @@ static int rpmsg_destroy_channel_by_info(struct virtproc_info *vrp, static void *get_a_buf(struct virtproc_info *vrp) { unsigned int len; + void *buf = NULL; + + /* protect svq from simultaneous concurrent manipulations */ + mutex_lock(&vrp->svq_lock); /* either pick the next unused buffer */ if (vrp->last_sbuf < vrp->num_bufs / 2) - return vrp->sbufs + vrp->buf_size * vrp->last_sbuf++; + buf = vrp->sbufs + vrp->buf_size * vrp->last_sbuf++; /* or recycle a used one */ else - return virtqueue_get_buf(vrp->svq, &len); + buf = virtqueue_get_buf(vrp->svq, &len); + + mutex_unlock(&vrp->svq_lock); + return buf; } /* XXX: the blocking 'wait' mechanism hasn't been tested yet */ diff --git a/drivers/video/omap2/dsscomp/base.c b/drivers/video/omap2/dsscomp/base.c index 7c3b0b1..b54fc50 100644 --- a/drivers/video/omap2/dsscomp/base.c +++ b/drivers/video/omap2/dsscomp/base.c @@ -448,24 +448,44 @@ void dump_ovl_info(struct dsscomp_dev *cdev, struct dss2_ovl_info *oi) (void *) oi->ba, (void *) oi->uv, c->stride); } +static void print_mgr_info(struct dsscomp_dev *cdev, + struct dss2_mgr_info *mi) +{ + printk("(dis%d(%s) alpha=%d col=%08x ilace=%d) ", + mi->ix, + (mi->ix < cdev->num_displays && cdev->displays[mi->ix]) ? + cdev->displays[mi->ix]->name : "NONE", + mi->alpha_blending, mi->default_color, + mi->interlaced); +} + void dump_comp_info(struct dsscomp_dev *cdev, struct dsscomp_setup_mgr_data *d, const char *phase) { - struct dss2_mgr_info *mi = &d->mgr; + if (!(debug & DEBUG_COMPOSITIONS)) + return; + + dev_info(DEV(cdev), "[%p] %s: %c%c%c ", + *phase == 'q' ? (void *) d->sync_id : d, phase, + (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-', + (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-', + (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-'); + print_mgr_info(cdev, &d->mgr); + printk("n=%d\n", d->num_ovls); +} +void dump_total_comp_info(struct dsscomp_dev *cdev, + struct dsscomp_setup_dispc_data *d, + const char *phase) +{ if (!(debug & DEBUG_COMPOSITIONS)) return; - dev_info(DEV(cdev), "[%p] %s: %c%c%c" - "(dis%d(%s) alpha=%d col=%08x ilace=%d n=%d)\n", + dev_info(DEV(cdev), "[%p] %s: %c%c%c ", *phase == 'q' ? (void *) d->sync_id : d, phase, (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-', (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-', - (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-', - mi->ix, - (mi->ix < cdev->num_displays && cdev->displays[mi->ix]) ? - cdev->displays[mi->ix]->name : "NONE", - mi->alpha_blending, mi->default_color, - mi->interlaced, - d->num_ovls); + (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-'); + print_mgr_info(cdev, &d->mgr); + printk("n=%d\n", d->num_ovls); } diff --git a/drivers/video/omap2/dsscomp/device.c b/drivers/video/omap2/dsscomp/device.c index 9bc14fc..eb57c4a 100644 --- a/drivers/video/omap2/dsscomp/device.c +++ b/drivers/video/omap2/dsscomp/device.c @@ -381,45 +381,46 @@ static long comp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct dsscomp_dev *cdev = container_of(dev, struct dsscomp_dev, dev); void __user *ptr = (void __user *)arg; - struct { - struct dsscomp_setup_mgr_data set; - struct dss2_ovl_info ovl[MAX_OVERLAYS]; - } p; + union { + struct { + struct dsscomp_setup_mgr_data set; + struct dss2_ovl_info ovl[MAX_OVERLAYS]; + } m; + struct dsscomp_setup_dispc_data dispc; + struct dsscomp_display_info dis; + struct dsscomp_check_ovl_data chk; + } u; dsscomp_gralloc_init(cdev); switch (cmd) { case DSSCOMP_SETUP_MGR: { - r = copy_from_user(&p.set, ptr, sizeof(p.set)) ? : - p.set.num_ovls >= ARRAY_SIZE(p.ovl) ? -EINVAL : - copy_from_user(&p.ovl, (void __user *)arg + sizeof(p.set), - sizeof(*p.ovl) * p.set.num_ovls) ? : - setup_mgr(cdev, &p.set); + r = copy_from_user(&u.m.set, ptr, sizeof(u.m.set)) ? : + u.m.set.num_ovls >= ARRAY_SIZE(u.m.ovl) ? -EINVAL : + copy_from_user(&u.m.ovl, + (void __user *)arg + sizeof(u.m.set), + sizeof(*u.m.ovl) * u.m.set.num_ovls) ? : + setup_mgr(cdev, &u.m.set); break; } - case DSSCOMP_SETUP_MGR_G: + case DSSCOMP_SETUP_DISPC: { - r = copy_from_user(&p.set, ptr, sizeof(p.set)) ? : - p.set.num_ovls >= ARRAY_SIZE(p.ovl) ? -EINVAL : - copy_from_user(&p.ovl, (void __user *)arg + sizeof(p.set), - sizeof(*p.ovl) * p.set.num_ovls) ? : - dsscomp_gralloc_queue_ioctl(&p.set); + r = copy_from_user(&u.dispc, ptr, sizeof(u.dispc)) ? : + dsscomp_gralloc_queue_ioctl(&u.dispc); break; } case DSSCOMP_QUERY_DISPLAY: { - struct dsscomp_display_info dis; - r = copy_from_user(&dis, ptr, sizeof(dis)) ? : - query_display(cdev, &dis) ? : - copy_to_user(ptr, &dis, sizeof(dis)); + r = copy_from_user(&u.dis, ptr, sizeof(u.dis)) ? : + query_display(cdev, &u.dis) ? : + copy_to_user(ptr, &u.dis, sizeof(u.dis)); break; } case DSSCOMP_CHECK_OVL: { - struct dsscomp_check_ovl_data chk; - r = copy_from_user(&chk, ptr, sizeof(chk)) ? : - check_ovl(cdev, &chk); + r = copy_from_user(&u.chk, ptr, sizeof(u.chk)) ? : + check_ovl(cdev, &u.chk); break; } default: diff --git a/drivers/video/omap2/dsscomp/dsscomp.h b/drivers/video/omap2/dsscomp/dsscomp.h index 8634f04..6deeda0 100644 --- a/drivers/video/omap2/dsscomp/dsscomp.h +++ b/drivers/video/omap2/dsscomp/dsscomp.h @@ -109,7 +109,7 @@ int dsscomp_queue_init(struct dsscomp_dev *cdev); void dsscomp_queue_exit(void); void dsscomp_gralloc_init(struct dsscomp_dev *cdev); void dsscomp_gralloc_exit(void); -int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_mgr_data *d); +int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_dispc_data *d); int dsscomp_wait(struct dsscomp_sync_obj *sync, enum dsscomp_wait_phase phase, int timeout); @@ -126,5 +126,8 @@ void swap_rb_in_mgr_info(struct dss2_mgr_info *mi); void dump_ovl_info(struct dsscomp_dev *cdev, struct dss2_ovl_info *oi); void dump_comp_info(struct dsscomp_dev *cdev, struct dsscomp_setup_mgr_data *d, const char *phase); +void dump_total_comp_info(struct dsscomp_dev *cdev, + struct dsscomp_setup_dispc_data *d, + const char *phase); #endif diff --git a/drivers/video/omap2/dsscomp/gralloc.c b/drivers/video/omap2/dsscomp/gralloc.c index 914c6bd..fe3e2a2 100644 --- a/drivers/video/omap2/dsscomp/gralloc.c +++ b/drivers/video/omap2/dsscomp/gralloc.c @@ -86,7 +86,7 @@ static void dsscomp_gralloc_cb(void *data, int status) /* This is just test code for now that does the setup + apply. It still uses userspace virtual addresses, but maps non TILER buffers into 1D */ -int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_mgr_data *d) +int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_dispc_data *d) { struct tiler_pa_info *pas[MAX_OVERLAYS]; s32 ret; @@ -119,7 +119,7 @@ int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_mgr_data *d) return ret; } -int dsscomp_gralloc_queue(struct dsscomp_setup_mgr_data *d, +int dsscomp_gralloc_queue(struct dsscomp_setup_dispc_data *d, struct tiler_pa_info **pas, void (*cb_fn)(void *, int), void *cb_arg) { @@ -135,7 +135,7 @@ int dsscomp_gralloc_queue(struct dsscomp_setup_mgr_data *d, /* reserve tiler areas if not already done so */ dsscomp_gralloc_init(cdev); - dump_comp_info(cdev, d, "queue"); + dump_total_comp_info(cdev, d, "queue"); for (i = 0; i < d->num_ovls; i++) dump_ovl_info(cdev, d->ovls + i); @@ -283,7 +283,7 @@ static void dsscomp_early_suspend_cb(void *data, int status) static void dsscomp_early_suspend(struct early_suspend *h) { - struct dsscomp_setup_mgr_data d = { + struct dsscomp_setup_dispc_data d = { .mgr.alpha_blending = 1, }; int err; |