aboutsummaryrefslogtreecommitdiffstats
path: root/security/capability.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-05-01 23:51:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-05-01 23:51:04 -0400
commit6c3c1eb3c35e8856d6dcb01b412316a676f58bbe (patch)
treec04f40c8e871461aff0927256edfcfe2bb51604e /security/capability.c
parente412d3a32badcf17541d7443b033769fdf39b545 (diff)
parenta134f083e79fb4c3d0a925691e732c56911b4326 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Receive packet length needs to be adjust by 2 on RX to accomodate the two padding bytes in altera_tse driver. From Vlastimil Setka. 2) If rx frame is dropped due to out of memory in macb driver, we leave the receive ring descriptors in an undefined state. From Punnaiah Choudary Kalluri 3) Some netlink subsystems erroneously signal NLM_F_MULTI. That is only for dumps. Fix from Nicolas Dichtel. 4) Fix mis-use of raw rt->rt_pmtu value in ipv4, one must always go via the ipv4_mtu() helper. From Herbert Xu. 5) Fix null deref in bridge netfilter, and miscalculated lengths in jump/goto nf_tables verdicts. From Florian Westphal. 6) Unhash ping sockets properly. 7) Software implementation of BPF divide did 64/32 rather than 64/64 bit divide. The JITs got it right. Fix from Alexei Starovoitov. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (30 commits) ipv4: Missing sk_nulls_node_init() in ping_unhash(). net: fec: Fix RGMII-ID mode net/mlx4_en: Schedule napi when RX buffers allocation fails netxen_nic: use spin_[un]lock_bh around tx_clean_lock net/mlx4_core: Fix unaligned accesses mlx4_en: Use correct loop cursor in error path. cxgb4: Fix MC1 memory offset calculation bnx2x: Delay during kdump load net: Fix Kernel Panic in bonding driver debugfs file: rlb_hash_table net: dsa: Fix scope of eeprom-length property net: macb: Fix race condition in driver when Rx frame is dropped hv_netvsc: Fix a bug in netvsc_start_xmit() altera_tse: Correct rx packet length mlx4: Fix tx ring affinity_mask creation tipc: fix problem with parallel link synchronization mechanism tipc: remove wrong use of NLM_F_MULTI bridge/nl: remove wrong use of NLM_F_MULTI bridge/mdb: remove wrong use of NLM_F_MULTI net: sched: act_connmark: don't zap skb->nfct trivial: net: systemport: bcmsysport.h: fix 0x0x prefix ...
Diffstat (limited to 'security/capability.c')
0 files changed, 0 insertions, 0 deletions
'>167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
/*
 * Copyright 2012 Freescale Semiconductor, Inc.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/stmp_device.h>

#define SET	0x4
#define CLR	0x8
#define TOG	0xc

#define PWM_CTRL		0x0
#define PWM_ACTIVE0		0x10
#define PWM_PERIOD0		0x20
#define  PERIOD_PERIOD(p)	((p) & 0xffff)
#define  PERIOD_PERIOD_MAX	0x10000
#define  PERIOD_ACTIVE_HIGH	(3 << 16)
#define  PERIOD_INACTIVE_LOW	(2 << 18)
#define  PERIOD_CDIV(div)	(((div) & 0x7) << 20)
#define  PERIOD_CDIV_MAX	8

struct mxs_pwm_chip {
	struct pwm_chip chip;
	struct clk *clk;
	void __iomem *base;
};

#define to_mxs_pwm_chip(_chip) container_of(_chip, struct mxs_pwm_chip, chip)

static int mxs_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			  int duty_ns, int period_ns)
{
	struct mxs_pwm_chip *mxs = to_mxs_pwm_chip(chip);
	int ret, div = 0;
	unsigned int period_cycles, duty_cycles;
	unsigned long rate;
	unsigned long long c;

	rate = clk_get_rate(mxs->clk);
	while (1) {
		c = rate / (1 << div);
		c = c * period_ns;
		do_div(c, 1000000000);
		if (c < PERIOD_PERIOD_MAX)
			break;
		div++;
		if (div > PERIOD_CDIV_MAX)
			return -EINVAL;
	}

	period_cycles = c;
	c *= duty_ns;
	do_div(c, period_ns);
	duty_cycles = c;

	/*
	 * If the PWM channel is disabled, make sure to turn on the clock
	 * before writing the register. Otherwise, keep it enabled.
	 */
	if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
		ret = clk_prepare_enable(mxs->clk);
		if (ret)
			return ret;
	}

	writel(duty_cycles << 16,
			mxs->base + PWM_ACTIVE0 + pwm->hwpwm * 0x20);
	writel(PERIOD_PERIOD(period_cycles) | PERIOD_ACTIVE_HIGH |
	       PERIOD_INACTIVE_LOW | PERIOD_CDIV(div),
			mxs->base + PWM_PERIOD0 + pwm->hwpwm * 0x20);

	/*
	 * If the PWM is not enabled, turn the clock off again to save power.
	 */
	if (!test_bit(PWMF_ENABLED, &pwm->flags))
		clk_disable_unprepare(mxs->clk);

	return 0;
}

static int mxs_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct mxs_pwm_chip *mxs = to_mxs_pwm_chip(chip);
	int ret;

	ret = clk_prepare_enable(mxs->clk);
	if (ret)
		return ret;

	writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);

	return 0;
}

static void mxs_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct mxs_pwm_chip *mxs = to_mxs_pwm_chip(chip);

	writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);

	clk_disable_unprepare(mxs->clk);
}

static const struct pwm_ops mxs_pwm_ops = {
	.config = mxs_pwm_config,
	.enable = mxs_pwm_enable,
	.disable = mxs_pwm_disable,
	.owner = THIS_MODULE,
};

static int mxs_pwm_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct mxs_pwm_chip *mxs;
	struct resource *res;
	int ret;

	mxs = devm_kzalloc(&pdev->dev, sizeof(*mxs), GFP_KERNEL);
	if (!mxs)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mxs->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(mxs->base))
		return PTR_ERR(mxs->base);

	mxs->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(mxs->clk))
		return PTR_ERR(mxs->clk);

	mxs->chip.dev = &pdev->dev;
	mxs->chip.ops = &mxs_pwm_ops;
	mxs->chip.base = -1;
	mxs->chip.can_sleep = true;
	ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret);
		return ret;
	}

	ret = pwmchip_add(&mxs->chip);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, mxs);

	ret = stmp_reset_block(mxs->base);
	if (ret)
		goto pwm_remove;

	return 0;

pwm_remove:
	pwmchip_remove(&mxs->chip);
	return ret;
}

static int mxs_pwm_remove(struct platform_device *pdev)
{
	struct mxs_pwm_chip *mxs = platform_get_drvdata(pdev);

	return pwmchip_remove(&mxs->chip);
}

static const struct of_device_id mxs_pwm_dt_ids[] = {
	{ .compatible = "fsl,imx23-pwm", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_pwm_dt_ids);

static struct platform_driver mxs_pwm_driver = {
	.driver = {
		.name = "mxs-pwm",
		.owner = THIS_MODULE,
		.of_match_table = mxs_pwm_dt_ids,
	},
	.probe = mxs_pwm_probe,
	.remove = mxs_pwm_remove,
};
module_platform_driver(mxs_pwm_driver);

MODULE_ALIAS("platform:mxs-pwm");
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Freescale MXS PWM Driver");
MODULE_LICENSE("GPL v2");